我正在编写一个PHP扩展,它接受一个值并改变它.示例PHP:
$someVal = "input value";
TestPassRef($someVal);
// value now changed
Run Code Online (Sandbox Code Playgroud)
什么是正确的方法?
在PHP 5.3中有一种重命名函数或"挂钩"函数的方法.
还有就是rename_function()因为〜2004年已被打破"APD"内.如果您尝试在PHP 5.3上构建它,您将收到此错误:
'struct _zend_compiler_globals' has no member named 'extended_info'
这是一个非常容易修复的错误,只需更改此行:
GC(extended_info) = 1;
至
CG(compiler_options) |= ZEND_COMPILE_EXTENDED_INFO;
我修改了我的php.ini,APD出现在我的phpinfo()中.但是,当我调用rename_function()PHP页面没有加载,我得到了我的分段错误/var/log/apache2/error.log.
反正有没有修复APD与现代版本的PHP一起工作?或者是否有另一种重命名函数的方法? 为什么地球上的重要功能不在PHP中!??!?!(得爱蟒蛇:)
我在C++中编写了一个使用libtidy的扩展,当我编译PHP时它在PHP下完美运行--with-tidy.
但是,将扩展程序运行在一个vanilla PHP上会很不错.当我尝试使用扩展时,我得到类似的东西:
PHP Warning:
PHP Startup:
Unable to load dynamic library 'extension.so':
undefined symbol: tidyCleanAndRepair in Unknown on line 0
并且未加载扩展名.
显然,官方整洁的扩展工作正常.我在系统上安装了相关的libtidy开发包,它编译+链接没有问题.我试图通过代码查看整洁的扩展,但它是一个巨大的宏 - 复制件随机感觉像货物代码.
除了链接到库PHP_ADD_LIBRARY_WITH_PATH(tidy, $TIDY_LIBDIR, TIDY_SHARED_LIBADD),是否有PHP扩展或C语句来修复此错误?
提前致谢!!
编辑:这是整个config.m4文件:
dnl config.m4 for extension htmlparser
PHP_ARG_ENABLE(htmlparse, whether to enable htmlparser support,
[ --enable-htmlparser Enable htmlparser support])
if test "$PHP_HTMLPARSER" != "no"; then
if test -r $PHP_LIBXML2/lib/libxml2.a; then
LIBXML2_DIR=$PHP_LIBXML2
else
AC_MSG_CHECKING(for libxml2 in default path)
for i in /usr/local /usr; do
if test -r $i/lib/libxml2.a; then
LIBXML2_DIR=$i …Run Code Online (Sandbox Code Playgroud) 我创建了一个PHP Hello World与Microsoft Visual C++ 2008扩展DLL我有权利php.ini(我知道,因为当我启用和禁用GD2扩展,有是一个效果),但是当我加载扩展它没有履行附加模块弹出在phpinfo().
当我尝试测试函数(一个简单的double()函数)时,它显然不起作用.我用过这个教程).
如果有人可以提供他们在创建时创建的dll(看看如果我的搞砸了或者它是我的服务器)那么我很乐意测试它.
操作系统:Windows(Vista)
服务器:WAMP
PHP:5.3.5(Xampp和IIS也已安装)
如果您想测试它是否适合您,请在此处下载.
当我运行命令时,php --ini我收到此错误:
PHP Startup: TalkPHP Extension: Unable to initalize module
Module compiled with build ID=API20090626, TS, VC9.
PHP compiled with build IF=API20090626, TS, VC6.
These options need to match
Run Code Online (Sandbox Code Playgroud)
这是否意味着我必须使用版本9来编译PHP?
在过去,我确实创建了一个共享库,现在我想在php扩展中使用它.有可能吗?正如我在config.m4文件中 看到的那样PHP_NEW_EXTENSION()要求.cc.问题是我不想暴露我的代码.我只是想使用头文件和共享库我在ubuntu下用c表示.对于php扩展,我确实创建了一个:config.m4, php_c.h and php_c.cc.
请帮忙!.THX APPRECIATE我确实输入了配置文件:
libs=mylib.so;
PHP_ADD_LIBRARY_WITH_PATH(libs, $EXTERNAL_LIB_DIR, ?? what to add here);
Run Code Online (Sandbox Code Playgroud)
我获得以下内容:
PHP Warning: PHP Startup: Invalid library (maybe not a PHP library) '/home/foder/mylib.so'in Unknown on line 0
Run Code Online (Sandbox Code Playgroud)
php:符号查找错误:
/usr/php5/20090626+lfs/vehicles.so: undefined symbol: _ZN3CarC1Ei (where vehicles.so) is a php so created with: phpize, ./configure --enable-vehicle make..
Run Code Online (Sandbox Code Playgroud) 我试图在Ubuntu 10.04上安装gearman PHP扩展,PHP固定为5.2,但PHP告诉我它不是一个有效的Zend扩展.
从源代码编译时(或通过pecl安装)没有错误,但在安装完成后,PHP会这样说:
/usr/lib/php5/20060613+lfs/gearman.so doesn't appear to be a valid Zend extension
Run Code Online (Sandbox Code Playgroud)
模块的体系结构与PHP的结构相匹配(我在32位和64位系统上都尝试过它).据我所知,我已经安装了所有依赖项(我假设如果我错过了任何错误,我会得到错误 - 我起初做了).
我正在使用gearman 0.8.0,因为它是在PHP 5.2上运行的最高版本.我使用的是PHP 5.2,因为我最后一次检查时,我们的drupal 6在5.3中表现不佳(据说这已经在核心中修复,但不一定用于模块).
我怀疑这可能与固定PHP有关,因为我找不到有关此行为的任何文档.
我正在开发一个PHP扩展,其中一个对象方法需要返回一个数组zval.
该方法如下:
ZEND_METHOD(myObject, myMethod)
{
zval **myArrayProperty;
if (zend_hash_find(Z_OBJPROP_P(getThis()), "myArrayProperty", sizeof("myArrayProperty"), (void **) &myArrayProperty) == FAILURE) {
RETURN_FALSE;
}
RETURN_ZVAL(*myArrayProperty, 1, 0);
}
Run Code Online (Sandbox Code Playgroud)
代码工作正常,并做了预期的事情 - 它返回对象的myArrayProperty.但是,我想优化这个过程.
myArrayProperty存储一个可能很大的数组.并且RETURN_ZVAL()宏复制该数组以返回值.复制过程需要花费大量时间来获取内存并复制所有数组值.同时,返回的数组通常用于只读操作.所以一个很好的优化是使用PHP的机制与引用计数,不要重复myArrayProperty内容.相反我会提高refcount的myArrayProperty,只是返回指针.当使用PHP扩展中的变量时,这与通常使用的策略相同.
但是,似乎没有办法 - 你必须复制值才能从PHP扩展函数返回它.更改函数签名以通过引用返回值不是一个选项,因为它链接属性和返回值 - 即稍后更改返回值,也会更改属性.这不是一种可接受的行为.
无法参与引用计数看起来很奇怪,因为PHP中的代码相同:
function myMethod() {
{
return $this->myArrayProperty;
}
Run Code Online (Sandbox Code Playgroud)
通过引用计数机制进行优化.这就是我在StackOverflow上提出这个问题的原因,以防我错过了什么.
那么,有没有办法从PHP扩展中的函数返回一个数组,而不是在内存中复制数组?
在我的C扩展中,我可以向调用函数抛出一个PHP异常zend_throw_exception.该函数的第一个参数是zend_class_entry指定要抛出的异常类型.我从文档中知道zend_exceptions.h,我可以使用zend_exception_get_default()默认的异常类型.
但是,它也说我可以传递派生类.我在哪里可以找到派生的内置异常的类条目,例如InvalidArgumentException?
我在我的PHP脚本(PHP 5.6,Apache 2.2)中间歇性地遇到了这个问题:
警告:无法修改标头信息 - 已在第55行的/path/to/index.php中发送的标头
这个警告没有我在其他问题中看过的"发送者"部分,所以我在犯罪header()和setcookie()调用之前添加了这段代码:
if (headers_sent($filename, $linenum)){
echo("Output buffer: #" . ob_get_contents() . "#");
echo "Headers already sent in $filename on line $linenum: ";
print_r(headers_list());
}
Run Code Online (Sandbox Code Playgroud)
这是问题发生时我得到的输出:
Output buffer: ##
Headers already sent in on line 0:
Array (
[0] => X-Powered-By: PHP/5.6.23
[1] => Content-type: text/html; charset=UTF-8
)
Run Code Online (Sandbox Code Playgroud)
(旁注:我在php.ini中将output_buffering设置为4096字节,所以这两个标题中的63个字符是否应该被缓存并等待更多,而不是过早发送?)
第一次启动包含Web服务器的Docker容器时出现此问题.之后,当我第一次访问我的网站(可能是一两个小时),当我打电话并登录用户或重定向到登录页面时,它只会(但不总是)发生.header()setcookie()
我已阅读并重读了一般"已发送标题"错误的答案,并且尽我所能,我已排除了这些可能的原因:
print,echo等等.在我调用setcookie()或header()auto_prepend_file php.ini设置gzip流编码 - …我有一个PHP类,我想转换为PHP扩展.我检查了一些教程(tuxradar的编写扩展,php.net的扩展php和zend的扩展编写),这有点复杂.
我找到了文章"如何编写PHP扩展"(编者注:站点已经不存在),我想知道是否可以使用它来使它从某个路径中获取PHP类(比如说/home/website1/public_html/api/class.php),执行它并返回类实例.
这样它就可以在托管在同一服务器上的其他网站中使用 - 每个网站都可以简单地调用该函数,它将获得自己的实例.
那可能吗?