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.
