萬盛學電腦網

 萬盛學電腦網 >> 網絡編程 >> php編程 >> php怎麼運行c語言程序?利用php調用C語言 擴展PHP的功能

php怎麼運行c語言程序?利用php調用C語言 擴展PHP的功能

php怎麼運行c語言程序?本文介紹了利用php調用C語言 擴展PHP的功能的教程,對php初學者來說非常有用,有興趣的同學快看看吧!

第一步. 生成需要調用的so文件

1.  首先做一個簡單的so文件:

/** * hello.c

* To compile, use following commands:

 *   gcc -O -c -fPIC -o hello.o hello.c

  *   gcc -shared -o libhello.so hello.o

*/

int hello_add(int a, int b)

{

    return a + b;

}

然後將它編譯成.so文件並放到系統中:

$ gcc -O -c -fPIC -o hello.o hello.c                      // -fPIC:是指生成的動態庫與位置無關

$ gcc -shared -o libhello.so hello.o                     // -shared:是指明生成動態鏈接庫

$ su        // 切換成超級用戶,此時,需要輸入密碼。

# cp libhello.so /usr/local/lib      // 把生成的鏈接庫放到指定的地址

# echo /usr/local/lib > /etc/ld.so.conf.d/local.conf       //  把庫地址寫入到配置文件中

# /sbin/ldconfig                // 用此命令,使剛才寫的配置文件生效

2. 寫段小程序來驗證其正確性:

/**

 * hellotest.c

 * To compile, use following commands:

*   gcc -o hellotest -lhello hellotest.c

*/

#include

int main()

{

    int a = 3, b = 4;

    printf("%d + %d = %d", a, b, hello_add(a,b));

    return 0;

}

編譯並執行:

$ gcc -o hellotest -lhello hellotest.c                // 編譯測試文件,生成測試程序

$ ./hellotest           // 運行測試程序

第二步. 制作PHP模塊(外部模塊)

請確保你已安裝 PHP及APACHE服務器。

$ cd php-5.2.3/ext

1. 然後通過下面的命令用ext_skel腳本建立一個名為 hello 的模塊:

$ ./ext_skel --extname=hello

2. 執行該命令之後它會提示你應當用什麼命令來編譯模塊,可惜那是將模塊集成到php內部的編譯方法。

如果要編譯成可動態加載的 php_hello.so,方法要更為簡單。

$ cd hello

 首先編輯 config.m4 文件,去掉第16行和第18行的注釋(注釋符號為 dnl 。)

16:  PHP_ARG_ENABLE(hello, whether to enable hello support,

17:  dnl Make sure that the comment is aligned:

18:  [  --enable-hello           Enable hello support])

3. 然後執行 phpize 程序,生成configure腳本:

$ phpize

 該程序在ubuntu的php5-dev包中

4. 打開 php_hello.h,在 PHP_FUNCTION(confirm_hello_compiled); 之下加入函數聲明:

PHP_FUNCTION(confirm_hello_compiled);   /* For testing, remove later. */

PHP_FUNCTION(hello_add);

5. 打開 hello.c,在 PHP_FE(confirm_hello_compiled, NULL) 下方加入以下內容。

zend_function_entry hello_functions[] = {

    PHP_FE(confirm_hello_compiled,  NULL)       /* For testing, remove later. */

    PHP_FE(hello_add,   NULL)       /* For testing, remove later. */

    {NULL, NULL, NULL}  /* Must be the last line in hello_functions[] */};

    然後在 hello.c 的最末尾書寫hello_add函數的內容: 

PHP_FUNCTION(hello_add)

{

    long int a, b;

    long int result;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &a, &b) == FAILURE) {

        return;

    }

    result = hello_add(a, b);

    RETURN_LONG(result);}保存退出,編譯並安裝:

6. $ ./configure

$ make LDFLAGS=-lhello

$ sudo make install

Installing shared extensions:     /usr/lib/php5/20060613+lfs/$ su# cp modules/hello.so/usr/lib/php/modules

luther@gliethttp:~$ sudo vim /etc/php5/apache2/php.ini;

enable_dl = Off;允許dl()動態加載so擴展功能enable_dl = On

luther@gliethttp:~$ sudo service apache2 reload    然後在 /var/www/html 下建立一個 hello.php 文件,內容如下:

<?php

    dl("hello.so");

    echo hello_add(3, 4);

?>

然後在浏覽器中打開hello.php文件,如果顯示7,則說明函數調用成功了。

第三步. 制作PHP模塊(內部模塊)

另外可以在apache重啟的時候讓我們的so庫直接動態編譯進php5,就像linux的insmod hello.ko模塊一樣,不用dl加載也不用重新編譯php,就可以直接使用so的函數了,步驟如下:

luther@gliethttp:~$ sudo vim /etc/php5/apache2/php.ini
enable_dl = Off
extension=hello.so
luther@gliethttp:~$ sudo service apache2 restart

不能reload而必須restart apache,這樣so就像insmod hello.ko一樣被融到了php5內核,然後代碼就可以忽略掉dl("hello.so");了,

[注意,這種方式只適合hello.so庫內所有功能代碼已經全部調試ok,如果還處在調試期間,那麼需要采用上面的dl強制加載的方式]

代碼如下:

<?php

    echo hello_add(3, 4);

?>,

     但是該功能不太適合調試,因為每次修改hello.so中代碼的話,都需要讓service apacherestart重啟才能讓php5內核再次加載新的hello.so擴展.可以這樣定義hello.so的實現,這樣每次執行.php網頁,都會在/var/www/下建立一個文件夾,所以php擴展實現了

一,搭建php環境
下載php 5.2.6 源碼 並解壓
編譯安裝,搭建php環境
二,創建擴展項目
進入源碼目錄
cd php5.2.6/ext/
./ext_skel --extname=my_ext
創建名字為my_ext的項目,最終會生成my_ext.so
三,更改配置和程序
$ vi ext/my_ext/config.m4
根據你自己的選擇將
dnl PHP_ARG_WITH(my_ext, for my_ext support,
dnl Make sure that the comment is aligned:
dnl [ --with-my_ext Include my_ext support])
修改成
PHP_ARG_WITH(my_ext, for my_ext support,
Make sure that the comment is aligned:
[ --with-my_ext Include my_ext support])
或者將
dnl PHP_ARG_ENABLE(my_ext, whether to enable my_ext support,
dnl Make sure that the comment is aligned:
dnl [ --enable-my_ext Enable my_ext support])
修改成
PHP_ARG_ENABLE(my_ext, whether to enable my_ext support,
Make sure that the comment is aligned:
[ --enable-my_ext Enable my_ext support])
$ vi ext/my_ext/php_my_ext.h

PHP_FUNCTION(confirm_my_ext_compiled); /* For testing, remove later. */
更改為
PHP_FUNCTION(say_hello);
$ vi ext/my_ext/my_ext.c

zend_function_entry php5cpp_functions[] = {
PHP_FE(confirm_my_ext_compiled, NULL) /* For testing, remove later. */
{NULL, NULL, NULL} /* Must be the last line in php5cpp_functions[] */
};
更改為
zend_function_entry php5cpp_functions[] = {
PHP_FE(say_hello, NULL)
{NULL, NULL, NULL} /* Must be the last line in php5cpp_functions[] */
};
在最後添加:
PHP_FUNCTION(say_hello)
{
zend_printf("hello world\n");
}
四,編譯
$ cd my_ext
$ /usr/local/php/bin/phpize
ps: 如果出現:Cannot find autoconf.……的錯誤信息,則需要安裝 autoconf (安裝過程略)
$ ./configure --with-php-config=/usr/local/php/bin/php-config
$ make
這時會編譯出 my_ext/modules/my_ext.so
五,配置php.ini
將my_ext.so放入/usr/local/php/ext/目錄
$ vi php.ini

修改添加如下:
extension_dir = '/usr/local/php/ext/'
extension=my_ext.so
六,測試
$ vi test.php
<?php
say_hello();
?>
$ /usr/local/php/bin/php test.php
hello world.
則大功告成

下面我來講講如何作一個php的擴展
首先要有一個搭建好的php環境
我把php的安裝在了/usr/local/php當然也通過
php的一個配置php.ini的路徑但是要注意了
用這種方法安裝的php擴展不能實現
我們在php安裝以後的/usr/local/php/bin目錄
找到這個文件phpize稍後我們將用到他
他就是個shell腳本你可以用vi phpize來查看他的內容
但是你要注意了這個腳本不是在哪裡都可以應用的
[root@ns root]# phpize
Cannot find config.m4.
Make sure that you run '/usr/local/bin/phpize' in the top level source directory of the module

[root@ns root]# phpize
Cannot find config.m4.
Make sure that you run '/usr/local/bin/phpize' in the top level source directory of the module
你會看到這兩種結果實際上你查看了這個腳本
很輕松的就會發現是怎麼來處理的
你的模擴展的時候最好
放在/usr/local/src/php-4.3.5/ext下
來執行他你在這裡也可以這樣/usr/local/php/bin/phpize來執行也可以
phpize來執行

我們在/usr/local/src/php-4.3.5/ext下找到這個工具
來建立一個php擴展的一個框架
[root@ns ext]#cd /usr/local/src/php-4.3.5/ext/
[root@ns ext]# ./ext_skel --extname=jinzhesheng_module
Creating directory jinzhesheng_module
Creating basic files: config.m4 .cvsignore jinzhesheng_module.cphp_jinzhesheng_module.h CREDITS EXPERIMENTAL tests/001.phptjinzhesheng_module.php [done].

To use your new extension, you will have to execute the following steps:

1.  $ cd ..
2.  $ vi ext/jinzhesheng_module/config.m4
3.  $ ./buildconf
4.  $ ./configure --[with|enable]-jinzhesheng_module
5.  $ make
6.  $ ./php -f ext/jinzhesheng_module/jinzhesheng_module.php
7.  $ vi ext/jinzhesheng_module/jinzhesheng_module.c
8.  $ make
執行了這個步驟以後你會看到這樣的結果
Repeat steps 3-6 until you are satisfied with ext/jinzhesheng_module/config.m4 and
step 6 confirms that your module is compiled into PHP. Then, start writing
code and repeat the last two steps as often as necessary.
這樣以後我們會在這個目錄下生成一個目錄叫jinzhesheng_module
進入這裡面我們看看
[root@ns ext]# cd jinzhesheng_module/
[root@ns jinzhesheng_module]# ls
config.m4  EXPERIMENTAL          jinzhesheng_module.php    tests
CREDITS    jinzhesheng_module.c  php_jinzhesheng_module.h

然後我們要修改文件順序是
configue.m4
jinzhesheng_module.c
php_jinzhesheng_module.h

使用文本編輯器打開config.m4文件,文件內容大致如下:

dnl $Id$d

dnl config.m4 for extension my_module

dnl don't forget to callPHP_EXTENSION(my_module)

dnl Comments in this file start with the string 'dnl'.

dnl Remove where necessary. This file will not work

dnl without editing.

dnl If your extension references something external, use with:

dnl PHP_ARG_WITH(my_module, for my_module support,

dnl Make sure that the comment is aligned:

dnl [  --with-my_module             Include my_module support])

dnl Otherwise use enable:

dnl PHP_ARG_ENABLE(my_module, whether to enable my_module support,

dnl Make sure that the comment is aligned:

dnl [  --enable-my_module           Enable my_module support])

if test "$PHP_MY_MODULE" != "no"; then

  dnl If you will not be testing anything external, like existence of

  dnl headers, libraries or functions in them, just uncomment the

  dnl following line and you are ready to go.

  dnl Write more examples of tests here...

  PHP_EXTENSION(my_module, $ext_shared)

Fi

根據你自己的選擇將

dnl PHP_ARG_WITH(my_module, for my_module support,

dnl Make sure that the comment is aligned:

dnl [  --with-my_module             Include my_module support])

修改成

PHP_ARG_WITH(my_module, for my_module support,

Make sure that the comment is aligned:

[  --with-my_module             Include my_module support])

或者將

dnl PHP_ARG_ENABLE(my_module, whether to enable my_module support,

dnl Make sure that the comment is aligned:

dnl [  --enable-my_module           Enable my_module support])

修改成

PHP_ARG_ENABLE(my_module, whether to enable my_module support,

Make sure that the comment is aligned:

[  --enable-my_module           Enable my_module support])
我這裡用了後者
然後保存退出
然後在編輯
Vi my_module.c
將文件其中的下列代碼進行修改

/* Every user visible function must have an entry in my_module_functions[].

*/

function_entry my_module_functions[] = {

        PHP_FE(say_hello,       NULL)  /* ?添加著一行代碼 */

        PHP_FE(confirm_my_module_compiled,      NULL) /* For testing, remove later. */

        {NULL, NULL, NULL}      /* Must be the last line in my_module_functions[] */

};

在文件的最後添加下列代碼

PHP_FUNCTION(say_hello)

{

        zend_printf("hello world\n");

}

保存文件退出

然後我們就可以在這個目錄下使用上面的命令了
/usr/local/php/bin/phpize
執行以後會看到下面的
[root@ns jinzhesheng_module]# /usr/local/php/bin/phpize
Configuring for:
PHP Api Version:         20020918
Zend Module Api No:      20020429
Zend Extension Api No:   20050606
[root@ns jinzhesheng_module]#
然後執行./configure --enable-jinzhesheng_module --with-apxs=/usr/local/apache/bin/apxs --with-php-config=/usr/local/php/bin/php-config
我們在安裝以後的php的bin目錄下的可以找到這個文件的
php-config 和phpize
這一步驟一定要注意你的apache的apxs放在哪裡了
然後執行make
你會看到出現錯誤了你重新定義了函數我們前面的
這個你在回頭改一下這個文件把原來的函數刪除掉在生成的文件裡面會有同樣的函數
你在加入你的代碼
就可以通過了
這個時候會在當前的目錄下生成一個目錄叫modules他的下面就放著你要的
jinzhesheng_module.so文件
cp modules/jinzhesheng_module.so /usr/local/php/ext/
這裡需要你先設置你的php的擴展目錄的在
在php.ini裡面
通過extension_dir
最後一不是你在php.ini文件中打開這個擴展
extension=jinzhesheng_module.so
然後
重新起動apache
用phpinfo來察看一下ok了

copyright © 萬盛學電腦網 all rights reserved