in the PHP program need to use C code, should be the following two kinds of situations:
1 already have C code, in the PHP program want to use directly
2 because of PHP performance problems, you need to use C to achieve some of the functions
In the first case, the most appropriate method is to use the system call, the existing C code is written as a separate program. Parameters are passed in through the command line or standard input, and the results are read from the standard output. Second, a little bit of trouble is that the C code is written in a daemon,php program to communicate with it using a socket.
Focus on the second case, although the method that follows the system call is also possible, but thinking about your goal is to optimize performance, so frequent processes, of course, can degrade performance. But the method of writing daemon is feasible, but a lot of tedious.
My simple test, the same algorithm, writes in C is 500 times times more efficient than PHP. And in the way of PHP extension, you can also increase by more than 90 times (the performance of the loss in the parameter pass, I guess).
So there are times when PHP extensions are the best option for us.
Here I highlight the method of writing PHP extensions in C, and do not need to recompile PHP.
First of all, find a PHP source code, PHP4 or PHP5 version of the can, and your target platform version of PHP does not matter.
A script named Ext_skel can be found in the Ext directory of the source code (Windows platform uses ext_skel_win32.php)
Execute in this directory./ext_skel--extname=hello (I use Hello as an example)
At this point a directory hello is generated, there are several files in the directory, you just need to care about these three: Config.m4 hello.c php_hello.h
Copy this directory to any place you want, CD in, execute it sequentially.
Phpize
/configure
Make
Nothing happened, did it?
This is because of a missed step, open CONFIG.M4, find the following
DNL If your extension references something external, use with:
..
DNL Otherwise Use enable:
..
This is to let you choose your extension using with or enable, let's use with bar. Uncomment the WITH section.
If you use the Vim editor as much as I do, it's easy to see that the DNL three letters are a comment (this is because VIM defaults to a syntax coloring package with various file formats)
After we modified the CONFIG.M4, we continued
Phpize
/configure
Make
At this point, the hello.so and hello.la files are generated under modules. One is a dynamic library, and the other is a static library.
Your PHP extension is ready, although it has not yet implemented the functionality you want, let me talk about how to use this extension! Ext_skel for you to generate a hello.php inside there is a call example, but that example requires you to copy the hello.so to PHP extension directory, we just want to implement their own function, do not want to build a cottage version of PHP, instead of the following method to load it:
Copy CodeThe code is as follows:
if (!extension_loaded ("Hello")) {
Dl_local ("hello.so");
}
function Dl_local ($extensionFile) {
Make sure, we are ABLE to load LIBRARIES06. if (! ( BOOL) Ini_get ("Enable_dl") | | (BOOL) Ini_get ("Safe_mode")) {
Die ("Dh_local (): Loading extensions are not permitted./n");
}
Check to make sure the file EXISTS11. if (!file_exists (DirName (__file__). "/". $extensionFile)) {
Die ("Dl_local (): File ' $extensionFile ' does not exist./n");
}
Check the file PERMISSIONS16. if (!is_executable (DirName (__file__). "/". $extensionFile)) {
Die ("Dl_local (): File ' $extensionFile ' are not executable./n");
}
We figure out the path21. $currentDir = DirName (__file__). "/";
$currentExtPath = Ini_get ("Extension_dir");
$subDirs = Preg_match_all ("////", $currentExtPath, $matches);
Unset ($matches);
Lets make sure we extracted a valid extension path27. if (! ( BOOL) $subDirs) {
Die (' Dl_local (): Could not determine a valid extension path [extension_dir]./n];
}
$extPathLastChar = strlen ($currentExtPath)-1;
if ($extPathLastChar = = Strrpos ($currentExtPath, "/")) {
$subDirs--;
}
$BACKDIRSTR = "";
for ($i = 1; $i <= $subDirs; $i + +) {
$backDirStr. = "..";
if ($i! = $subDirs) {
$backDirStr. = "/";
}
}
Construct the final path to load46. $finalExtPath = $backDirStr. $currentDir. $extensionFile;
Now we execute DL () to actually load the module49. if (!DL ($finalExtPath)) {
Die ();
}
If the module was loaded correctly, we must bow grab the module NAME54. $loadedExtensions = Get_loaded_extensions ();
$thisExtName = $loadedExtensions [sizeof ($loadedExtensions)-1];
Lastly, we return the extension name58. return $thisExtName;
}//end dl_local ()
The advantage is that your PHP extension can go with your PHP code, and the green extension.
A subsequent concern is how to add functions, implement parameter passing, and return values
The steps to add a function are:
Php_hello.h:
Php_function (confirm_hello_compiled);//parentheses fill in the function name
hello.c
Zend_function_entry hello_functions[] = {
Php_fe (confirm_hello_compiled, NULL)/* Add a line here */
{null, NULL, NULL}/* must is the last line in hello_functions[] */
};
Php_function (confirm_hello_compiled)
{//write the function body here
}
To implement the function prototype is actually a sample, with the macro php_function to wrap a bit, in addition, in the hello_functions inside add a line of information, indicating that you have this function in this module.
So it's all the same. function prototypes, how do you differentiate between return values and parameters?
Let me give you an example:
Copy CodeThe code is as follows:
Php_function (Hello_strdiff)
{
Char *r1 = NULL, *R2 = NULL;
int n = 0, m = 0;
if (Zend_parse_parameters (Zend_num_args () TSRMLS_CC, "SS", &r1, &n, &R2, &m) = = FAILURE) {
Return
}
while (n && m && *r1 = = *r2) {
r1++;
r2++;
n--;
m--;
}
if (n = = 0) return_long (m);
if (M = = 0) return_long (n);
int d[n+1][m+1];
int cost;
int i,j;
for (i = 0; I <= N; i++) d[i][0] = i;
for (j = 0; J <= M; j + +) d[0][j] = j;
for (i = 1; I <= n; i++) {
for (j = 1; j <= M; j + +) {
if (r1[i-1] = = R2[j-1]) cost = 0;
else cost = 1;
int a = MIN (d[i-1][j]+1,d[i][j-1]+1);
A = MIN (A, d[i-1][j-1]+cost);
D[I][J] = A;
}
}
Return_long (D[n][m]);
}
This is an algorithm that asks for two string differences, enters the parameter two strings, and returns the integer type.
Pass the parameter to see here
Zend_parse_parameters (Zend_num_args () TSRMLS_CC, "SS", &r1, &n, &R2, &m)
Take this as a scanf to understand.
The type description is shown in the following table:
| Boolean |
b |
zend_bool |
| Long |
l |
long |
| Double |
d |
double |
| String |
s |
char*, int |
| Resource |
r |
zval* |
| Array |
a |
zval* |
| Object |
o |
zval* |
| Zval |
z |
zval* |
If you want to implement optional parameters, such as a string, a floating point, and an optional bool type, you can use "sd|b" to represent it.
And scanf is a little different, for strings, you have to provide two variables to store, one is char *, the address of the stored string, an int, to save the length of the string. When necessary, you can handle binary data safely.
What about the return value?
Use the following set of macros to represent:
Return_string
Return_long
Return_double
Return_bool
Return_null
Note that return_string has two parameters
When you need to copy a string, use the
Return_string ("Hello World", 1);
otherwise use
Return_string (str, 0);
This involves the allocation of memory in the module, when you request the memory to be released in PHP program, please refer to the following table
| Traditional |
non-persistent |
Persistent |
malloc(count)
calloc(count, num) |
emalloc (count) ecalloc (count, num) |
pemalloc (count, 1) * pecalloc (count, num, 1) |
strdup (str) strndup (str, len) |
estrdup (str) estrndup (str, len) |
pestrdup (str, 1) pemalloc () & memcpy () |
free (PTR) |
efree (PTR) |
pefree (PTR, 1) |
realloc (PTR, newsize) |
erealloc (PTR, newsize) |
perealloc (PTR, newsize, 1) |
malloc(count * num + extr)** |
safe_emalloc(count, num, extr) |
safe_pemalloc(count, num, extr) |
Generally we use these non-persistent listed in the good.
Basically, you can start writing an extension of PHP.
Judging from my current application, it is enough to manipulate strings, so I can only introduce so much.
http://www.bkjia.com/PHPjc/740214.html www.bkjia.com true http://www.bkjia.com/PHPjc/740214.html techarticle in the PHP program need to use the C code, should be the following two cases: 1 already have C code, in PHP program want to directly use 2 due to PHP performance problem, need C to implement part of the function for the first ...