Implementation method of calling C code in php_PHP tutorial
C code needs to be used in the php program, which should be the following two situations:
1 I already have C code and want to use it directly in the PHP program
2 Due to performance issues with PHP, I need to use C to implement some functions
For the first situation, the most appropriate method is to use system calls to 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 standard output. Secondly, the slightly more troublesome method is to write C code as a daemon, and the PHP program uses socket to communicate with it.
Focus on the second case. Although it is also possible to use the system call method, consider that your purpose is to optimize performance. Starting so many processes so frequently will of course degrade performance. The method of writing a daemon is certainly feasible, but it is much more complicated.
My simple test shows that the same algorithm is 500 times more efficient when written in C than in PHP. And using PHP extension can also improve it by more than 90 times (the performance loss is in parameter passing, I guess).
So sometimes php extension is our best choice.
Here I will focus on how to write PHP extensions in C without recompiling PHP.
First of all, find a php source code. It can be php4 or php5 version. It has nothing to do with the php version of your target platform.
You can find a script named ext_skel in the ext directory of the source code (windows platform uses ext_skel_win32.php)
Execute ./ext_skel --extname=hello in this directory (I use hello as an example)
At this time, a directory hello is generated. There are several files in the directory. You only need to care about these three: config.m4 hello.c php_hello.h
Copy this directory to wherever you want, cd into it, and execute
phpize
/configure
make
in sequence. Nothing happens, right?
This is because you missed a step. Open config.m4 and find the following
dnl If your extension references something external, use with:
..
dnl Otherwise use enable:
..
This allows you to choose whether your extension uses with or enable. Let’s use with. Uncomment the with part.
If you use the vim editor like me, you will easily find that the three letters dnl originally represent comments (this is because vim comes with syntax coloring packages for various file formats by default)
After we modify config.m4, continue
phpize
/configure
make
At this time, hello.so and hello.la files will be 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 achieved the function you want. Let me first talk about how to use this extension! ext_skel generated a hello.php for you with a calling example, but that example requires you to copy hello.so to the extension directory of PHP. We just want to implement our own functions and don't want to create a copycat version of PHP. Instead, use the following To load it:
if(!extension_loaded("hello")) {
dl_local("hello.so");
}
function dl_local( $extensionFile ) {
//make sure that we are ABLE to load libraries06. if( !(bool)ini_get( "enable_dl" ) || (bool)ini_get( "safe_mode" ) ) {
die( "dh_local(): Loading extensions is 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' is 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 of this is that your php extension can follow your php code, which is a green extension.
The next question that people are concerned about is how to add functions, implement parameter transfer and return values
The steps to add a function are as follows:
php_hello.h:
PHP_FUNCTION(confirm_hello_compiled);// Fill in the function name in the brackets
hello.c
zend_function_entry hello_functions[] = {
PHP_FE(confirm_hello_compiled, NULL) /* Add a line here*/
{NULL, NULL, NULL} /* Must be the last line in hello_functions [] */
};
PHP_FUNCTION(confirm_hello_compiled)
{// Write the function body here
}
The function prototypes to be implemented are actually the same, and they are packaged with the macro PHP_FUNCTION , 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 to distinguish the return value and parameters?
I will give you an example:
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-; --;
}
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++) {
-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]);
}
这是一个求两个字符串差异度的算法,输入参数两个字符串,返回整型。
参数的传递看这里
zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &r1, &n, &r2, &m)
把这个当成是scanf来理解好了。
类型说明见下表:
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* |
如果想实现可选参数的话,例如一个字符串,一个浮点,再加一个可选的bool型,可以用"sd|b"来表示。
和scanf有一点不同的是,对于字符串,你要提供两个变量来存储,一个是char *,存字符串的地址,一个int,来存字符串的长度。这样有必要的时候,你可以安全的处理二进制数据。
那么返回值怎么办呢?
使用下面一组宏来表示:
RETURN_STRING
RETURN_LONG
RETURN_DOUBLE
RETURN_BOOL
RETURN_NULL
注意RETURN_STRING有两个参数
当你需要复制一份字符串时使用
RETURN_STRING("Hello World", 1);
否则使用
RETURN_STRING(str, 0);
这里涉及到了模块中内存的分配,当你申请的内存需要php程序中去释放的话,请参照如下表
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 the ones listed in Non-Persistent.
That’s basically it, you can start writing a php extension.
From my current application point of view, being able to manipulate strings is enough, so I can only introduce so much.

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



PHP 8.4 brings several new features, security improvements, and performance improvements with healthy amounts of feature deprecations and removals. This guide explains how to install PHP 8.4 or upgrade to PHP 8.4 on Ubuntu, Debian, or their derivati

Visual Studio Code, also known as VS Code, is a free source code editor — or integrated development environment (IDE) — available for all major operating systems. With a large collection of extensions for many programming languages, VS Code can be c

This tutorial demonstrates how to efficiently process XML documents using PHP. XML (eXtensible Markup Language) is a versatile text-based markup language designed for both human readability and machine parsing. It's commonly used for data storage an

A string is a sequence of characters, including letters, numbers, and symbols. This tutorial will learn how to calculate the number of vowels in a given string in PHP using different methods. The vowels in English are a, e, i, o, u, and they can be uppercase or lowercase. What is a vowel? Vowels are alphabetic characters that represent a specific pronunciation. There are five vowels in English, including uppercase and lowercase: a, e, i, o, u Example 1 Input: String = "Tutorialspoint" Output: 6 explain The vowels in the string "Tutorialspoint" are u, o, i, a, o, i. There are 6 yuan in total

JWT is an open standard based on JSON, used to securely transmit information between parties, mainly for identity authentication and information exchange. 1. JWT consists of three parts: Header, Payload and Signature. 2. The working principle of JWT includes three steps: generating JWT, verifying JWT and parsing Payload. 3. When using JWT for authentication in PHP, JWT can be generated and verified, and user role and permission information can be included in advanced usage. 4. Common errors include signature verification failure, token expiration, and payload oversized. Debugging skills include using debugging tools and logging. 5. Performance optimization and best practices include using appropriate signature algorithms, setting validity periods reasonably,

If you are an experienced PHP developer, you might have the feeling that you’ve been there and done that already.You have developed a significant number of applications, debugged millions of lines of code, and tweaked a bunch of scripts to achieve op

Static binding (static::) implements late static binding (LSB) in PHP, allowing calling classes to be referenced in static contexts rather than defining classes. 1) The parsing process is performed at runtime, 2) Look up the call class in the inheritance relationship, 3) It may bring performance overhead.

What are the magic methods of PHP? PHP's magic methods include: 1.\_\_construct, used to initialize objects; 2.\_\_destruct, used to clean up resources; 3.\_\_call, handle non-existent method calls; 4.\_\_get, implement dynamic attribute access; 5.\_\_set, implement dynamic attribute settings. These methods are automatically called in certain situations, improving code flexibility and efficiency.
