标签: php-internals

PHP的MySQL Cursor实现以及它们如何管理内存

PHP中不同的MySQL游标如何管理内存?我的意思是,当我创建一个MySQL查询来检索一个大的结果集,然后获取MySQL资源时,查询检索的数据有多少存储在本地内存中,以及如何检索更多结果?光标是否自动获取所有结果,并在我使用fetch_array或是缓冲系统迭代资源时将它们提供给我?

最后,mysql中不同驱动程序的游标是否实现不同?有几个MySQL的驱动PHP可用mysql,mysqli,pdo等他们是否都遵循同样的做法?

php mysql php-internals

7
推荐指数
1
解决办法
4533
查看次数

重复的数组键(注意:多次从__sleep()返回成员变量“ a”)

标题似乎有些愚蠢,但是我对此非常认真。今天在工作中,我遇到了无法解释的怪异的PHP行为。幸运的是,此行为已在PHP 7.4中修复,因此似乎也有人偶然发现了该行为。

我举了一个小例子来说明出了什么问题:

<?php

class A {
    private $a = 'This is $a from A';

    public $b = 'This is $b from A';

    public function __sleep(): array
    {
        var_dump(array_keys(get_object_vars($this)));

        return [];
    }
}

class B extends A
{
    public $a = 'This is $a from B';
}

$b = new B;

serialize($b);
Run Code Online (Sandbox Code Playgroud)

在此处运行此代码:https : //3v4l.org/DBt3o

这里是这里发生的事情的一点解释。我们必须同时共享一个属性的A类和B类$a。细心的读者注意到,该物业$a具有两种不同的可见性(公共,私人)。到目前为止还算不上什么。魔术发生在实例中__sleep被神奇调用的方法中serialize。我们希望拥有所有获得的对象变量,将其get_object_vars减少为仅包含键,array_keys并使用输出所有内容var_dump

我期望这样(从PHP 7.4开始发生,这是我的期望输出):

array(2) {
  [0]=>
  string(1) "b"
  [1]=>
  string(1) …
Run Code Online (Sandbox Code Playgroud)

php arrays associative-array php-internals

7
推荐指数
1
解决办法
184
查看次数

PHP 的“o”序列化格式是什么?

PHP 7.4 向后不兼容的更改列表包含以下注释

序列化

o 序列化格式已被删除。由于它从未由 PHP 生成,因此这可能只会破坏手动制作的字符串的反序列化。

(请注意,这指的是 little- o,而不是O用于对象序列化的 big-格式。)

似乎这从未由 PHP 的serialize()函数生成,但是此注释存在的事实意味着它unserialize()函数识别。

我做了一个小测试小提琴 (3v4l.org),它表明这不仅仅是big-的同义词O,这将是一个明显的可能性。

小提琴通过输出的错误消息中的差异公开了 PHP 中的更改。在 PHP >= 7.4 中,我们在位置 0(o遇到 )出现错误,而在 7.4 之前,在位置 5(数据所在的位置)报告错误。这意味着o已识别但数据格式错误,这与我上面已经推断的内容有关。

那么,o序列化格式是什么,它反序列化为什么,如果 PHP 本身没有实际生成它,为什么还要支持这样的功能?

php language-history php-internals

7
推荐指数
1
解决办法
710
查看次数

使用内存引用比较PHP数组

是否有可能看到两个数组变量是否指向相同的内存位置?(它们是相同的阵列)

php arrays php-internals

6
推荐指数
3
解决办法
1939
查看次数

如何将zval转换为矢量用于php扩展?

我正在为我的c ++库编写一个php扩展,其定义如下:

bool getPids(map<string,string> pidsMap, vector<string> ids);
Run Code Online (Sandbox Code Playgroud)

现在,我正在为这样的上述函数编写一个php包装器.

ZEND_METHOD(myFInfo, get_pids)
{
    zval *idsArray;

    if (zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "a",
                                &idsArray ) == FAILURE )
    {
        RETURN_NULL();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我想调用getPids(),但我不知道将idsArray作为向量传递给c ++函数的正确方法.

在网上搜索之后,我找到了一个例子,其中zval数组被迭代以读取每个值,我想也许我可以用它来创建一个向量.

PHP_FUNCTION(hello_array_strings)
{
    zval *arr, **data;
    HashTable *arr_hash;
    HashPosition pointer;
    int array_count;
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &arr) == FAILURE) {
        RETURN_NULL();
    }

arr_hash = Z_ARRVAL_P(arr);
array_count = zend_hash_num_elements(arr_hash);

php_printf("The array passed contains %d elements", array_count);

for(zend_hash_internal_pointer_reset_ex(arr_hash, &pointer); zend_hash_get_current_data_ex(arr_hash, (void**) &data, &pointer) == SUCCESS; 

zend_hash_move_forward_ex(arr_hash, &pointer)) {

            if (Z_TYPE_PP(data) == IS_STRING) { …
Run Code Online (Sandbox Code Playgroud)

php c++ php-extension php-internals

6
推荐指数
1
解决办法
914
查看次数

是否需要在物体前面使用&符号?

由于现在默认情况下通过引用传递对象,是否有一些特殊情况才有&$obj意义?

php oop reference object php-internals

6
推荐指数
1
解决办法
1950
查看次数

当PHP没有被修改时,PHP是否优化了数组类型的函数参数,而不是通过引用显式传递的?

PHP引擎会优化第二个示例来传递$arr引用吗?

function test1(array &$arr)
{
    $arr[] = 123;

    echo $arr[0];
}

function test2(array $arr)
{
    echo $arr[0];
}
Run Code Online (Sandbox Code Playgroud)

php arrays optimization php-internals

6
推荐指数
1
解决办法
100
查看次数

Zend:如何在PHP 7中正确破坏自定义对象?

我正在学习PHP扩展编写,以便使一些旧的扩展与PHP 7一起工作.

我试图从http://devzone.zend.com/1435/wrapping-c-classes-in-a-php-extension/修改示例扩展,但在破坏自定义对象时它会导致段错误.所有其他功能正常工作.(在我的代码中,汽车被BDict取代.)

这是我的代码:

#define Z_BDICT_OBJ_P(zv) php_bdict_object_fetch_object(Z_OBJ_P(zv))

zend_object_handlers bdict_object_handlers;

typedef struct _bdict_object {
    BDict *bdict_data;
    zend_object std;
} bdict_object;

zend_class_entry *bdict_ce;

static void bdict_free_storage(zend_object *object TSRMLS_DC)
{
    bdict_object *intern = (bdict_object *)object;

    // ***Both the following two lines will cause segfault***
    delete intern->bdict_data;
    zend_object_std_dtor(&intern->std TSRMLS_CC);
}

zend_object * bdict_object_new(zend_class_entry *ce TSRMLS_DC)
{
    bdict_object *intern = (bdict_object *)ecalloc(1,
            sizeof(bdict_object) +
            zend_object_properties_size(ce));

    zend_object_std_init(&intern->std, ce TSRMLS_CC);
    object_properties_init(&intern->std, ce);

    intern->std.handlers = &bdict_object_handlers;

    return &intern->std;
}

static inline bdict_object * php_bdict_object_fetch_object(zend_object *obj)
{ …
Run Code Online (Sandbox Code Playgroud)

php c php-extension php-internals php-7

6
推荐指数
1
解决办法
741
查看次数

PHP:在写入时复制和按引用分配在PHP5和PHP7上执行不同的操作

我们有一段简单的代码:

1    <?php
2    $i = 2;
3    $j = &$i;
4    echo (++$i) + (++$i);
Run Code Online (Sandbox Code Playgroud)

在PHP5上,它输出8,因为:

$i为参考,当我们增加$i++i,它会改变zval,而不是做一个副本,因此4号线会4 + 4 = 8.这是按参考分配.

如果我们评论第3行,它将输出7,每次我们通过增加它来改变它,PHP将复制,第4行将是3 + 4 = 7.这是Copy On Write.

但在PHP7中,它总是输出7.

我已经检查了PHP7中的更改:http://php.net/manual/en/migration70.incompatible.php ,但我没有得到任何线索.

任何帮助都会很棒,提前谢谢.

UPDATE1

以下是PHP5/PHP7上代码的结果:https://3v4l.org/USTHR

UPDATE2

操作码:

[huqiu@101 tmp]$ php -d vld.active=1 -d vld.execute=0 -f incr-ref-add.php
Finding entry points
Branch analysis from position: 0
Jump found. Position 1 = -2
filename: …
Run Code Online (Sandbox Code Playgroud)

php php-internals

6
推荐指数
1
解决办法
718
查看次数

如何理解3行c代码?

 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &flag) == FAILURE) {
  return;
 }
Run Code Online (Sandbox Code Playgroud)

特别是在ZEND_NUM_ARGS() TSRMLS_CC做什么?

php c syntax php-internals

5
推荐指数
2
解决办法
665
查看次数