如何判断zend_hash_key是整数还是字符串?


How can I tell whether a zend_hash_key is an integer or a string?

我试图将C函数应用于HashTablezend_hash_apply_with_arguments中的每个元素。要做到这一点,我的C函数需要有一个匹配apply_func_args_t的签名。最后一个参数需要是一个zend_hash_key,它是一个既包含整数又包含字符串的结构体。我怎么知道我应该检查哪些字段来获得键呢?

我不知道Zend,但我一直在挖掘源代码(PHP 5.5.14)。我在zend_hash.c中发现了以下函数,它可能对您有帮助,也可能没有帮助:

ZEND_API int zend_hash_get_current_key_type_ex(HashTable *ht, HashPosition *pos)
{
  Bucket *p;
  /* ... */
      if (p->nKeyLength) {
        return HASH_KEY_IS_STRING;
      } else {
        return HASH_KEY_IS_LONG;
      }
  /* ... */

zend_hash_apply_with_arguments()中,您会发现hash_key.nKeyLength被设置为Bucket->nKeyLength:

ZEND_API void zend_hash_apply_with_arguments(/* ... */)
{
  Bucket *p;
  /* ... */
  Zend_hash_key hash_key;
  /* ... */
      hash_key.nKeyLength = p->nKeyLength;
  /* ... */
}

因此,您可以通过检查zend_hash.nKeyLength来区分类型。应该在Zend内部之外这样做吗?我不知道。

在PHP7中,zend_hash_key结构体已更改为:

typedef struct _zend_hash_key {
    zend_ulong h; // numeric key
    zend_string *key; // string key
} zend_hash_key;

您可以在PHP源代码中看到Zend/zend_hash.c并搜索以下内容:

if (p->key) {  // p is a Bucket and assign to the zend_hash_key struct
    return HASH_KEY_IS_STRING;
} else {
    return HASH_KEY_IS_LONG;
}

来确定变量在PHP中是字符串还是数字试试这样写

<?php
  $a = "123456";
  if (gettype($a)=="string" ){ echo $a," is a string<br>";}
  $a = 123456;
  if (gettype($a)=="integer" ){ echo $a," is an integer<br>";}
?>