# What Is the `php_` C++ Symbol Prefix in TypePHP?

> Discover the php_ C++ symbol prefix in TypePHP. Learn how it ensures stable, collision-free entry points between PHP and compiled C++ code for user-defined functions and methods.

- Repository: [Swoole Project/typephp](https://github.com/swoole/typephp)
- Tags: internals
- Published: 2026-08-30

---

**In TypePHP, the `php_` prefix designates the C++ ABI for symbols that correspond to user-defined PHP functions and class methods, ensuring stable, collision-free entry points between the PHP runtime and compiled C++ code.**

The swoole/typephp compiler transforms PHP source into native C++ to improve execution performance, but this translation requires callable entry points that the PHP engine can invoke without name conflicts. The `php_` prefix serves as the exclusive namespace for these user-facing symbols, distinguishing them from internal runtime helpers and Zend API wrappers.

## The `php_` Prefix and TypePHP's Symbol Architecture

TypePHP employs a strict naming convention to separate concerns across its codebase. While **internal runtime logic** uses the `typephp_` prefix and **Zend API wrappers** reside under `php::`, the compiler reserves `php_` specifically for symbols that originate from PHP declarations.

When the compiler processes a PHP function or method, it normalizes the namespace, class, and function identifiers, then joins them with double underscores (`__`). For example, a function `greet` in namespace `App` becomes `php_app__greet` in the generated C++.

### Comparison of Prefix Scopes

| Prefix | Scope | Example | Visibility |
|--------|-------|---------|------------|
| `typephp_` | Runtime internals | `typephp_call_parent_constructor()` | Internal |
| `php::` | PHPX Zend API wrapper | `php::deindirect()` | API |
| **`php_`** | **User PHP callable** | **`php_app__greet()`** | **Linker-visible** |

## How TypeCPP Generates `php_` Symbols

The transformation from PHP to C++ follows a predictable pattern defined in the project's documentation and compiler core. For global functions, the compiler emits a C++ function with the `php_` prefix followed by the normalized path.

Given this PHP source:

```php
namespace App;

function hello(string $msg): void {}

class Logger {
    public function log(string $msg): void {}
}

```

The compiler generates these C++ signatures in the resulting translation unit:

```cpp
// Function – global callable
void php_app__hello(php::Str msg);

// Method – instance callable (first param is $this)
void php_app__logger__log(php::Object &this_, php::Str msg);

```

Instance methods receive the object as the first parameter (`this_`), while static methods and functions follow the standard calling convention.

## Why TypePHP Reserves the `php_` Prefix

The dedication of `php_` to user-declared symbols serves three critical architectural goals according to the swoole/typephp source code:

1. **Collision Avoidance** – By restricting `php_` to user code, TypePHP prevents global helpers from clashing with compiled PHP functions. A user-defined `function deindirect()` maps to `php_deindirect`, ensuring it never conflicts with internal `typephp_` helpers.

2. **Consistent ABI** – All generated stubs share the same naming format and calling convention. This stability allows the stub generator, runtime library, and external C++ consumers to rely on a version-stable interface.

3. **Linker Visibility** – Because `php_` symbols are exposed to the linker, the PHP engine can dynamically resolve and invoke them when executing user code.

## Implementation in the TypePHP Compiler

The enforcement of this prefix convention begins in [`src/CompilerBase.php`](https://github.com/swoole/typephp/blob/main/src/CompilerBase.php), where the compiler defines the constant used during code generation:

```php
public const string PREFIX = 'php_';

```

This constant drives the symbol naming logic throughout the compilation pipeline. The comprehensive specification for these rules lives in [`docs/zh-cn/CPP_SYMBOL_NAMING.md`](https://github.com/swoole/typephp/blob/main/docs/zh-cn/CPP_SYMBOL_NAMING.md), which documents the ABI requirements for generated stubs.

When the compiler emits C++ for a class method like `App\User::save()`, it constructs the symbol `php_app__user__save`, making it immediately callable by the runtime's invocation handlers.

## Summary

- The `php_` prefix marks C++ symbols that expose user-defined PHP functions and methods to the runtime.
- TypePHP generates these symbols by joining normalized PHP identifiers with double underscores (e.g., `php_app__greet`).
- This convention prevents naming collisions with internal `typephp_` helpers and Zend API wrappers.
- The prefix is defined as the `PREFIX` constant in [`src/CompilerBase.php`](https://github.com/swoole/typephp/blob/main/src/CompilerBase.php).
- All `php_` symbols are linker-visible, enabling dynamic resolution by the PHP engine.

## Frequently Asked Questions

### What does the `php_` prefix represent in TypePHP?

It represents the C++ ABI boundary for user-declared PHP functions and class methods. The prefix distinguishes compiled PHP entry points from TypePHP's internal runtime functions and PHPX wrapper utilities, ensuring that only user code occupies this namespace.

### How does TypePHP handle PHP namespaces when generating `php_` symbols?

The compiler normalizes namespace separators and class names into a flat structure using double underscores. For instance, `App\Controller\Base::index()` becomes `php_app__controller__base__index`, ensuring unique, predictable symbol names across the codebase that the linker can resolve.

### Why doesn't TypePHP use the `typephp_` prefix for user functions?

The `typephp_` namespace is reserved for the compiler's internal runtime logic and helper functions. Separating user symbols under `php_` guarantees that internal refactors never break the public ABI exposed to the PHP engine, maintaining backward compatibility for compiled extensions.

### Where can I find the official documentation for TypePHP's C++ naming conventions?

The specification resides in [`docs/zh-cn/CPP_SYMBOL_NAMING.md`](https://github.com/swoole/typephp/blob/main/docs/zh-cn/CPP_SYMBOL_NAMING.md) within the swoole/typephp repository. This document details the mapping between PHP declarations and their corresponding `php_` C++ symbols, including the double-underscore separator rules and method signatures.