
Advanced PHP Programming
.pdf
608Chapter 23 Writing SAPIs and Extending the Zend Engine
void statement_handler(zend_op_array *op_array)
{
fprintf(stderr, “%s:%d\n”, zend_get_executed_filename(TSRMLS_C), zend_get_executed_lineno(TSRMLS_C));
}
int call_coverage_zend_startup(zend_extension *extension)
{
TSRMLS_FETCH(); CG(extended_info) = 1; return SUCCESS;
}
#ifndef ZEND_EXT_API
#define ZEND_EXT_API ZEND_DLEXPORT #endif
ZEND_EXTENSION();
ZEND_DLEXPORT zend_extension zend_extension_entry = {
“Simple Call Coverage”,
“1.0”,
“George Schlossnagle”,
“http://www.schlossnagle.org/~george”,
“”,
call_coverage_zend_startup, NULL,
NULL,
NULL,
NULL, // message_handler_func_t
NULL, // op_array_handler_func_t
statement_handler, // statement_handler_func_t NULL, // fcall_begin_handler_func_t
NULL, // fcall_end_handler_func_t
NULL, // op_array_ctor_func_t
NULL, // op_array_dtor_func_t
STANDARD_ZEND_EXTENSION_PROPERTIES
};
You compile it as you would a regular PHP extension. Note the startup function, which sets CG(extended_info).Without that set, the engine does not generate the extended opcodes necessary for the handlers to work.
Then you register the extension in the php.ini file, as follows:
zend_extension=/full/path/to/call_coverage.so

Homework 609
Now if you execute the following script:
<?php
$test = 1; if($test) {
$counter++;
}
else { $counter--;
}
?>
you get the following output:
/Users/george/Advanced_PHP/examples/chapter-23/call_coverage/test.php:2
/Users/george/Advanced_PHP/examples/chapter-23/call_coverage/test.php:3
/Users/george/Advanced_PHP/examples/chapter-23/call_coverage/test.php:4
/Users/george/Advanced_PHP/examples/chapter-23/call_coverage/test.php:10
Homework
While the other chapters in this book have “Further Reading” sections at the end, the general lack of organized information on writing SAPIs and Zend extensions makes it hard to list good resources here. Sadly, the code itself is about all the public documentation that exists.
Therefore, this last section is a list of homework for you to sharpen your skills:
nEmbed PHP into your favorite text editor.
nComplete psh so that it behaves more like a standard shell (for example, so executables can be typed on the command line and will be found in your path, so it has input/output streams).
nWrite an output cache that, like Zend Performance Suite, wraps zend_execute() so that include files, functions, and so on can have their output cached based on the parameters passed to them.
nRefine code_coverage Zend extension so that it can dump line-by-line execution times to an external file.Then write a companion script to use the output to annotate the original script with line-by-line timings and execution counts.
nHave fun.







616 |
catching exceptions |
|
|
catching exceptions, 84-85 |
check_credentials function, 329 |
|
CBC (Cypher Block Chaining) mode, 337 |
child processes, 130 |
|
cdb libraries, 252 |
creating, 131 |
|
centralized cache, 378-380 |
reaping, 132-134 |
|
CFB (Cypher Feedback) mode, 337 |
resources, sharing, 131 |
|
CGI SAPI |
signals |
|
activation/deactivation, 584 |
SIGALRM, 134, 137-138 |
|
cookies, 587 |
SIGCHILD, 134-135, 137 |
|
data writing callback, 584 |
SIGHUP, 134, 138 |
|
deactivation code, 584 |
SIGINT, 134 |
|
environment variables lookup interface, |
SIGKILL, 134 |
|
585 |
SIGUSR1, 134 |
|
flush helper method, 584 |
SIGUSR2, 134 |
|
header handlers, 586 |
variables, sharing, 132 |
|
logging, 588 |
chroot() method, 140 |
|
main() routine, 588, 591 |
CISC (Complex Instruction Set |
|
method pointers, 583 |
Computer), 476 |
|
POST data, reading, 587 |
classes |
|
SAPI name, 583 |
abstract, 53-54 |
|
sapi_module_struct structure, 582-584 |
built-in, 88 |
|
sending headers, 586 |
constructors, adding, 557-558 |
|
server variables, 588 |
creating, 550-551 |
|
shell environment variables, 588 |
custom objects, 559-562 |
|
shutdown, 584 |
DB_Result, 58-60 |
|
stat() override, 585 |
__destruct(), 42 |
|
stream buffers, flushing, 585 |
documenting, 32 |
|
userspace error callback, 586 |
Exception, 83, 558 |
|
change control, CVS (Concurrent |
exceptions, throwing, 558-559 |
|
Versioning System), 184 |
factory, 292 |
|
binary files, 187-188 |
factory methods, 562 |
|
branches, 186-187, 194-195 |
implementing, 549-550 |
|
development/production environments, |
inheritance, 554 |
|
195-199 |
interfaces, defining/implementing, |
|
diffs, 189-191 |
562-564 |
|
file versions, 189-191 |
methods, adding, 555-557 |
|
log messages, 186 |
naming, 25 |
|
modifying files, 188-189 |
Net_Telnet, 69 |
|
repositories, 185-186 |
PEAR, caching, 241-242 |
|
single tree limitations, 195 |
PEAR XML-RPC, 395 |
|
symbolic tags, 193-194, 199 |
private properties, 554 |
|
updating files, 191-193 |
private variables, 559 |
|
characters (matching), strings, 463-464 |
properties, adding, 551-553 |
