我正在尝试按照此说明在Google Cloud App Engine中运行symfony4应用程序.
我的应用程序具有依赖性,它本身依赖于php-gd.由于作曲家失败,这个扩展似乎不可用the requested PHP extension gd is missing from your system..
我如何修改教程以使扩展可用?
这可以用php.ini文件解决,还是需要自定义环境?
或者,因为我不需要我的依赖项所需的部分php-gd,是否有办法composer运行--ignore-platform-reqs标志?
php google-app-engine php-extension composer-php google-app-engine-php
我正在用C编写PHP扩展,我想将我在类中创建的类,函数和变量放在命名空间中.我无法在扩展文档中找到有关命名空间的任何内容.要清楚,我想要相当于
namespace MyNamespace{
class MyClass{
}
}
Run Code Online (Sandbox Code Playgroud)
但在C扩展名中.更具体地说,我正在寻找Zend C API中的函数或宏,它允许我将PHP命名空间分配给我用C编写的类或函数.这可能吗?
我的任务是创建一个访问现有PostgreSQL数据库的PHP应用程序.这是我第一次使用Postgre,更不用说PHP已经安装在应该运行应用程序的Linux机器中.我没有设置这些东西的经验,我只是编码.
我的问题是我似乎无法使用PHP进行Postgre扩展.我检查了php.ini文件,没有"extension = ..."行.所以我添加了"extension = pgsql.so".然后我检查了"extension_dir",发现那里只有2个文件(ldap.so,phpcups.so),我添加了一个从另一个Linux盒子中取出的pgsql.so文件.我重启了httpd.它不起作用.我在phpinfo()中找不到任何"pgsql"或"postgre".
原谅我的无知.我知道Linux太少了.如果你能指出我正确的方向,我将非常感激.
我使用了number5给出的建议:
伙计,我在RedHat上.我使用了你给出的命令的"yum"版本,我得到了这个:
[root @ perseus~] #yum install php-pgsql加载"installonlyn"插件设置安装过程设置存储库无法检索镜像列表http://mirrorlist.centos.org/?release=5&arch=x86_64&repo=extras错误是[Errno 4] IOError:错误:找不到repo:extras的有效baseurl
不幸的是,我正在使用的Linux服务器没有连接到Internet.还有其他安装方法吗?
我已经使用SWIG创建了一个PHP扩展,一切正常,但是当链接方法调用时,我正在观察一些奇怪的垃圾收集行为.例如,这有效:
$results = $response->results();
$row = $results->get(0)->iterator()->next();
printf('%s %s' . "\n", $row->getString(0), $row->getString(1));
Run Code Online (Sandbox Code Playgroud)
但这段错误:
$row = $response->results()->get(0)->iterator()->next();
printf('%s %s' . "\n", $row->getString(0), $row->getString(1));
Run Code Online (Sandbox Code Playgroud)
唯一的区别是第一个创建$results,而第二个将调用链接在一起.
SWIG实际上只向PHP公开函数并生成PHP代理类以与它们进行交互.这些代理类基本上包含一个传递给每个公开函数的资源以及这些函数通常采用的其他参数.考虑到这些代理类可能是问题所在,我重新编写代码来绕过它们,而是直接使用公开的函数.和以前一样,这有效:
$results = InvocationResponse_results($response->_cPtr);
$row = TableIterator_next(Table_iterator(Tables_get($results, 0)));
printf('%s %s' . "\n", Row_getString($row, 0), Row_getString($row, 1));
Run Code Online (Sandbox Code Playgroud)
再次,这段错误:
$row = TableIterator_next(Table_iterator(Tables_get(InvocationResponse_results($response->_cPtr), 0)));
printf('%s %s' . "\n", Row_getString($row, 0), Row_getString($row, 1));
Run Code Online (Sandbox Code Playgroud)
同样,唯一的区别是第一个创建$results,而第二个将调用链接在一起.
此时,我花了一些时间在gdb/valgrind中进行调试,并确定在InvocationResponse_results将调用链接在一起时过早调用返回的析构函数.为了观察,我std::cout在暴露的C++函数及其析构函数的顶部插入了语句.这是没有链接的输出:
InvocationResponse_results()
Tables_get()
Table_iterator()
TableIterator_next()
__wrap_delete_TableIterator
Row_getString()
Row_getString()
Hola Mundo
---
__wrap_delete_InvocationResponse
__wrap_delete_Row
__wrap_delete_Tables
Run Code Online (Sandbox Code Playgroud)
我--- …
我正在写一个PHP扩展.从C代码我尝试在PHP代码中调用静态方法.
PHP方法如下所示:
<?php
class Model {
static method GetModelById($id) { ... }
}
?>
Run Code Online (Sandbox Code Playgroud)
C中的调用如下所示:
if( call_user_function_ex(
&((*ce)->function_table),
NULL, &fname, &retval_ptr,
1, func_params, 0, NULL TSRMLS_CC
) == SUCCESS
){
// do some stuff here ...
}
Run Code Online (Sandbox Code Playgroud)
...所有传递的参数都应包含适当的值.这里奇怪的是:如果我编译我的扩展对PHP 5.2代码工作正常,如果我编译这对PHP 5.3,方法调用失败,没有错误消息.
我也尝试过zend_call_method两种版本都没有成功.
任何人都可以给我一个提示吗?你会如何从C调用静态方法?
提前致谢!
编辑
对不起,伙计们,我zend_call_method这样做了:
if( zend_call_method( NULL, *ce, NULL,
"getmodelbyid",
strlen("getmodelbyid"),
&retval_ptr, 1, p1,
NULL TSRMLS_CC ) == FAILURE) {
php_printf("gosh!");
}
else {
php_printf("yep!");
}
Run Code Online (Sandbox Code Playgroud)
......所以我学到了:
zend_call_method内部加+1).虽然我是C的新手,但我认为PHP代码库在很多方面都过度编译了!
希望这有助于其他人!
我正在尝试为php5.4编写一个扩展,它基本上包含了一个非常简单的CPP类.
这是出于教育目的.
我发现在php5.4中这样做的方法已经从php5.3改变了
我在哪里可以找到有关如何操作的文档?或者甚至更好,代码示例,任何其他扩展,包括CPP类并在php5.4中工作
例如,过去的工作,不再是.摘自http://devzone.zend.com/1435/wrapping-c-classes-in-a-php-extension/
zend_object_value car_create_handler(zend_class_entry *type TSRMLS_DC)
{
zval *tmp;
zend_object_value retval;
car_object *obj = (car_object *)emalloc(sizeof(car_object));
memset(obj, 0, sizeof(car_object));
obj->std.ce = type;
ALLOC_HASHTABLE(obj->std.properties);
zend_hash_init(obj->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
zend_hash_copy(obj->std.properties, &type->default_properties,
(copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *));
retval.handle = zend_objects_store_put(obj, NULL,
car_free_storage, NULL TSRMLS_CC);
retval.handlers = &car_object_handlers;
return retval;
}
Run Code Online (Sandbox Code Playgroud)
该行将
zend_hash_copy(obj->std.properties, &type->default_properties,
(copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *));
失败,因为结构实例type(忘记它的定义)不再具有该成员default_properties
编写PHP扩展时,此文档页面指示config.m4应提供一个文件供autoconf使用.它提供了几个这样的文件示例,但文档不完整.例如,示例文件使用宏PHP_EVAL_INCLINE,但在后面的文档中没有提到.
那么,在config.m4文件中可以使用哪些特定于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 ×10
php-extension ×10
c ×4
apache ×1
chaining ×1
composer-php ×1
http-headers ×1
php-5.6 ×1
swig ×1