Press "Enter" to skip to content

A Bug in PHP's Reflection Extension

Running 'php --re Dummy' on an extension whose module-entry function table lists a mixed-case function name (e.g. 'Dummy') triggers 'Internal error: Cannot find extension function Dummy in global function table'. Laruence traces it to the reflection extension's zend_hash_find on EG(function_table) not lowercasing func->fname first, while PHP's global function table is all-lowercase. Reported as bugs.php.net bug 54347.

Filed in English, PHP应用, PHP源码分析
with 0 Comment

The Leftover Problem with a Serializable Singleton — Answer

Why $a === Singleton::getInstance() is false after $a = unserialize(serialize($a)). Laruence walks the refcounting: unserialize runs __wakeup, which re-points self::$instance to the new object and drops the old instance's refcount to 1; the symbol $a still holds it; then reassigning $a drops that last reference, the old zval hits zero refcount and is freed, firing __destruct — which (in the naive version) resets self::$instance to NULL, clobbering the singleton. Fix: keep the cleanup in __destruct but don't reset $instance there.

Filed in English, PHP应用, PHP源码分析, 随笔
with 0 Comment

Serialize/Unserialize Breaks the Singleton

The usual Singleton (__construct/__clone private + static getInstance) silently breaks under serialize/unserialize — $a === $b is false after round-tripping. Two fixes: block it with private __sleep/__wakeup, or make it serialization-friendly by re-pointing self::$instance in __wakeup (and cleaning up in __destruct). Laruence plants a twist: even the 'friendly' version fails in a specific case, teased for the follow-up article.

Filed in English, PHP应用, 随笔
with 0 Comment

PHP Memory Management — Who Moved My Memory

Why memory_get_usage() doesn't drop back to baseline after unset($a). Laruence unpacks it: (1) PHP allocates memory implicitly (variable name in the symbol table + value), not only via explicit calls; (2) PHP's emalloc/efree don't hand memory to/from the OS — efree returns the chunk to PHP's own free/cache list, so real_size stays flat; (3) the 'missing' 32 bytes were actually consumed by an earlier var_dump's output header; (4) a HashTable only grows via resize and never shrinks, so the symbol table keeps its expanded size even after unsetting all variables.

Filed in English, PHP应用, PHP源码分析
with 0 Comment

Speeding Up PHP's ECHO

Why echoing large strings is slow (PHP blocks waiting for the write to complete, which is what inflates request time and piles up DB connections for slow clients) and the two-tier fix: PHP output buffering (ob_start / output_buffering — but only helps if the buffer is big enough) plus Apache's SendBufferSize so PHP hands the body to Apache and exits without waiting for the slow client. Laruence's caveat: it doesn't make the client faster, it just lets PHP release its resources sooner.

Filed in English, PHP应用, PHP源码分析
with 0 Comment

PHP Memory Management — Analyzing a Low-Probability Core

Root-causing a rare core in PHP 5.2.6's zend_alloc: a timeout signal fires mid-way through zend_mm_free_int, just before the line that clears a bit in free_bitmap (the HANDLE_BLOCK_INTERRUPTIONS() around it was a no-op before 5.2.17). The error handler then allocates memory for the 'Maximum execution time exceeded' message, reads the stale free_bitmap, hands out a bad self-pointing pointer, and ZEND_MM_CHECK_BLOCK_LINKAGE panics with 'zend_mm_heap corrupted'. A genuinely subtle interrupt-reentrancy corruption in the Zend memory manager.

Filed in English, PHP应用, PHP源码分析
with 0 Comment

Using HTTP 204 and 205

For Ajax 'fire-and-forget' operations that only need to report success/failure, use the HTTP status code itself as the answer instead of shipping a {status, message} JSON body: 204 No Content = succeeded, no data, don't refresh; 205 Reset Content = succeeded, clear the form. Laruence's note: 204 suits repeated updates of one item, 205 suits repeated form submissions — but no browser actually honors 205 (it's treated as 204/200).

Filed in English, Js/CSS, PHP应用, 随笔
with 0 Comment

Expect: 100-continue

Why a curl POST >1KB sometimes behaves oddly: libcurl first sends 'Expect: 100-continue' and waits for the server to acknowledge before sending the body. Servers that don't handle it (like lighttpd) return 417 Expectation Failed and break the logic. Laruence's one-line fix: suppress the header with curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:')).

Filed in English, PHP应用, 随笔
with 0 Comment

PHP is Innocent

A rebuttal to the viral claim that 'PHP's echo is slow'. Laruence's point: echoing a 500K string taking hundreds of ms has nothing to do with PHP (or its C implementation) — it's IO-bound, and IO speed caps the output speed. Turning on Apache's compression makes it faster simply because the string shrinks (high compression ratio), i.e. trading CPU for IO. PHP is genuinely innocent.

Filed in English, PHP应用, 随笔
with 0 Comment

Compilation failed: support for \P, \p, and \X has not been compiled

Why 'Compilation failed: support for \P, \p, and \X has not been compiled' shows up after a VPS migration: PHP/PCRE was built without Unicode property support, so the \pL regex in a search-highlight plugin fails to compile. Laruence's workaround is to drop \p{L} and match by explicit Unicode code-point ranges ([\x{41}-\x{5a}...\x{0800}-\x{d7a3}] with the u flag), plus a reference table of CJK/Korean/Japanese and GBK byte ranges.

Filed in English, PHP应用
with 0 Comment