How PHP calls C code

Source: Internet
Author: User
Tags php source code

C code must be used in php programs. There are two possible cases:

1. C code already exists. I want to use it directly in php programs. 2. Due to php performance problems, I need to use C to implement some functions. In the first case, the most appropriate method is to use system to call, write the existing C code into an independent program. Parameters are passed in through the command line or standard input, and the results are read from the standard output. Second, the less troublesome method is to write the C code as a daemon, And the php program uses socket to communicate with it. Focus on the second case. Although the method called by the system can be used, but think about your purpose to optimize the performance, so frequent initiation of so many processes will certainly reduce the performance. The method for writing daemon is feasible, but complicated. In my simple test, the same algorithm, using C for writing is 500 times more efficient than using php. The php extension method can also be improved by more than 90 times (the performance loss lies in the parameter transfer, I guess ). So sometimes php extension is our best choice. Here I will introduce how to write php extensions in C without re-compiling php. First, find a php source code, which can be php4 or php5. It has nothing to do with the php version of your target platform. In the ext directory of the source code, you can find the script named ext_skel and execute it in this directory #. /ext_skel -- extname = hello at this time, a directory hello is generated, which contains several files, you only need to care about these three: config. m4 hello. c php_hello.h: copy the directory to any desired location, cd it, and run # phpize # in sequence #. /configure # make does not happen, right? This is because a step is missing. Open config. m4, find dnl If your extension references something external, use :... dnl Otherwise use enable :... this is to let you choose whether your extension uses with or enable. Let's use. Uncomment the part. If you use the vim editor like me, you will easily find that the three dnl letters originally represent annotations (this is because vim uses syntax coloring packages of various file formats by default) we modified config. after m4, continue # phpize #. /configure # make: hello will be generated under modules. so and hello. la file. One is a dynamic library and the other is a static library. Your php extension has been completed. Although it has not implemented the functions you want, let me first talk about how to use this extension! Ext_skel generates a hello. php contains a call example, but you need to set hello in that example. so copy to the extension directory of php. We only want to implement our own functions and do not want to create a cottage version of php. Use the following method to load it:
  1. If (! Extension_loaded ("hello ")){
  2. Dl_local ("Hello. So ");
  3. }
  4. Function dl_local ($ extensionfile ){
  5. // Make sure that we are able to load libraries
  6. If (! (Bool) ini_get ("enable_dl") | (bool) ini_get ("safe_mode ")){
  7. Die ("dh_local (): loading extensions is not permitted./N ");
  8. }
  9. // Check to make sure the file exists
  10. If (! File_exists (dirname (_ FILE _). "/". $ extensionFile )){
  11. Die ("dl_local (): File '$ extensionFile' does not exist./n ");
  12. }
  13. // Check the file permissions
  14. If (! Is_executable (dirname (_ FILE _). "/". $ extensionFile )){
  15. Die ("dl_local (): File '$ extensionFile' is not executable./n ");
  16. }
  17. // We figure out the path
  18. $ CurrentDir = dirname (_ FILE __)."/";
  19. $ CurrentExtPath = ini_get ("extension_dir ");
  20. $ SubDirs = preg_match_all ("//", $ currentExtPath, $ matches );
  21. Unset ($ matches );
  22. // Lets make sure we extracted a valid extension path
  23. If (! (Bool) $ subDirs ){
  24. Die ("dl_local (): cocould not determine a valid extension path [extension_dir]./n ");
  25. }
  26. $ ExtPathLastChar = strlen ($ currentExtPath)-1;
  27. If ($ extPathLastChar = strrpos ($ currentExtPath ,"/")){
  28. $ SubDirs --;
  29. }
  30. $ BackDirStr = "";
  31. For ($ I = 1; $ I <= $ subDirs; $ I ++ ){
  32. $ BackDirStr. = "..";
  33. If ($ I! = $ SubDirs ){
  34. $ BackDirStr. = "/";
  35. }
  36. }
  37. // Construct the final path to load
  38. $ FinalExtPath = $ backDirStr. $ currentDir. $ extensionFile;
  39. // Now we execute dl () to actually load the module
  40. If (! Dl ($ finalExtPath )){
  41. Die ();
  42. }
  43. // If the module was loaded correctly, we must bow grab the module name
  44. $ LoadedExtensions = get_loaded_extensions ();
  45. $ ThisExtName = $ loadedExtensions [sizeof ($ loadedExtensions)-1];
  46. // Lastly, we return the extension name
  47. Return $ thisExtName;
  48. } // End dl_local ()

The advantage is that your php extension can follow your php code to implement green extension.

Next, you will be concerned about how to add a function, implement parameter transfer, and add a function as follows: php_hello.h: php_function (confirm_hello_compiled); // enter the function name hello in the brackets. czend_function_entry hello_functions [] = {php_fe (confirm_hello_compiled, null)/* Add a row */{null, null, null}/* must be the last line in hello_functions [] */}; the prototype of the function to be implemented by php_function (confirm_hello_compiled) {// write the function body here, the macro php_function is used for packaging. In addition, a line of information is added to hello_functions, indicating that you have this function in this module. So they all have the same function prototype. How can we distinguish between return values and parameters? Here is an example:
  1. PHP_FUNCTION (hello_strdiff)
  2. {
  3. Char * r1 = NULL, * r2 = NULL;
  4. Int n = 0, m = 0;
  5. If (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC, "ss", & r1, & n, & r2, & m) = FAILURE ){
  6. Return;
  7. }
  8. While (n & m & * r1 = * r2 ){
  9. R1 ++;
  10. R2 ++;
  11. N --;
  12. M --;
  13. }
  14. If (n = 0) RETURN_LONG (m );
  15. If (m = 0) RETURN_LONG (n );
  16. Int d [n + 1] [m + 1];
  17. Int cost;
  18. Int I, j;
  19. For (I = 0; I <= n; I ++) d [I] [0] = I;
  20. For (j = 0; j <= m; j ++) d [0] [j] = j;
  21. For (I = 1; I <= n; I ++ ){
  22. For (j = 1; j <= m; j ++ ){
  23. If (r1 [I-1] = r2 [J-1]) cost = 0;
  24. Else cost = 1;
  25. Int a = MIN (d [I-1] [j] + 1, d [I] [J-1] + 1 );
  26. A = MIN (a, d [I-1] [J-1] + cost );
  27. D [I] [j] =;
  28. }
  29. }
  30. RETURN_LONG (d [n] [m]);
  31. }

This is an algorithm for determining the degree of difference between two strings. The input parameter returns an integer.

Here, zend_parse_parameters (zend_num_args () tsrmls_cc, "SS", & R1, & N, & R2, & M) can be understood as scanf. The following table describes the types:

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.

Different from scanf, for strings, you need to provide two variables for storage. One is char *, the address of the stored string, and the other is int to store the length of the string. When necessary, you can safely process binary data.
What should I do with the return value? The following macro group is used for representation: 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 RETURN_STRING ("Hello World", 1 );
Otherwise, use RETURN_STRING (str, 0 );
Memory Allocation in the module is involved here. When the memory you apply for needs to be released in the 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 can use the ones listed in Non-Persistent.


Basically, you can start writing a php extension. From my current application, can manipulate the string is enough, so I can only introduce so much, if you want to be detailed, such as php array how to deal with, can refer to the http://devzone.zend.com/node/view/id/1022
For more details, refer to the "Zend API: Deep php kernel" chapter in the PHP manual. However, these materials are in English.

From: http://blog.csdn.net/oyd/article/details/3168417

 

Also can refer to: http://www.phpchina.com/index.php? Action-viewthread-tid-26870

Http://blog.csdn.net/xiaocon/article/details/388953

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.