CHAPTER 15 – Summary of Example
You have learned how to write a simple PHP function. Going back to the beginning of this chapter, we mentioned two main motivations for writing PHP functionality in C. The first was to write some of your algorithms in C for performance or for functionality reasons. The previous example should allow you to quickly get started with these kind of extensions. The second motiva- tion was for wrapping third-party libraries. We will discuss this next.
Wrapping Third-Party Extensions In this section, you learn how to write a more useful and complete extension. It wraps a C library and explains how to write an extension with various PHP functions that work together.
Motivation Probably the most common PHP extension is one which wraps a third party C library. This may include database server libraries, such as MySQL or Oracle, XML technology libraries, such as libxml2 or expat, graphics manipulation libraries, such as ImageMagick or GD, and lots more. In this section, we write such an extension from scratch, yet again using the script for creating skeleton extensions, which saves us much work. This extension wraps the standard C functions fopen(), fclose(), fread(), fwrite(), and feof(). The extension uses an abstract datatype called resource to represent the opened file FILE *. You will notice that most PHP extensions that deal with datatypes, such as database connections and file handles, use resources because the engine itself can't "understand" them directly. The list of C APIs we want to implement in our PHP extension include FILE *fopen(const char *path, const char *mode); int fclose(FILE *stream); size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); int feof(FILE *stream); We implement these functions in a way that fits the PHP spirit both in naming conventions and simplicity of the API. If you ever contribute your code to the PHP community, you will be expected to follow the agreed-upon conven- tions and not necessarily follow the C library's API, as is. Some of the conven- tions, but not all, are documented in the CODING_STANDARDS file in the PHP source tree. That being said, this functionality has already been present in PHP from its early days with an API similar to the C library's API. Your PHP installation already supports fopen(), fclose(), and more PHP functions.
So, here's what our PHP spirited API would look like: resource file_open(string filename, string mode) file_open() accepts two strings (filename and mode) and returns a resource handle to the file. bool file_close(resource filehandle) file_close() receives a resource handle and returns true/false if the operation succeeded. string file_read(resource filehandle, int size) file_read() receives a resource handle and the amount of bytes to read. It returns the read string. bool file_write(resource filehandle, string buffer) file_write() receives a resource handle and the string to write. It returns true/false if the operation succeeded. bool file_eof(resource filehandle) file_eof() receives a resource handle and returns true/false if end of-file has been reached. Therefore, our function definition file, which we'll save in the ext/ direc- tory as myfile.def will look as follows: resource file_open(string filename, string mode) bool file_close(resource filehandle) string file_read(resource filehandle, int size) bool file_write(resource filehandle, string buffer) bool file_eof(resource filehandle) Next, run it through the ext_skel script with the following command inside the ext/ directory of the source tree: ./ext_skel --extname=myfile --proto=myfile.def Then, follow the instructions from the previous example on how to build your newly created extension. You will receive some compile errors on lines that include the FETCH_RESOURCE() macro, which the skeleton script can't complete on its own. To get your skeleton extension to build, you can just com- ment them out for now.