PHP相当于Ruby符号

时间:2011-03-17 21:09:14

标签: php ruby string symbols

PHP有像Ruby一样的符号吗?或者,我应该只使用字符串作为PHP关联数组中的键吗?

我猜它与问题Is there a Python equivalent to Ruby symbols?

的答案相同

6 个答案:

答案 0 :(得分:2)

PHP有可定义的常量,但在这种情况下这并不是非常有用。

所以没有。使用字符串作为键。

答案 1 :(得分:2)

如果您关注的是使用字符串作为数组键的重载以及每次复制数组而不是作为引用传递的事实,我建议您使用stdClass,这基本上是一个对象类,可以动态修改,类似于数组,但它的行为与对象相同。

答案 2 :(得分:1)

PHP没有像符号那样,甚至常量在PHP中的工作也与在ruby中的工作明显不同。数组键必须是字符串或数字。您可以为常量指定字符串或数字,然后将常量“使用”作为数组键。但是,常量在PHP中是静态的,所以这可能不是你想要的,需要更多的“样板”代码,而实际的数组键仍将最终成为字符串或数字(基于常量的值)。

答案 3 :(得分:1)

不,PHP没有这样的东西。 PHP中最接近的近似是对哈希键使用单引号字符串 - 只是为了确保它们中没有“插值”。

几个例子:

  • $arr[key] - 在大多数情况下,这会像$arr['key']一样工作,但有一些缺点: a)如果确实有一个定义的常数(例如,define('key', 'rubbish') - 你将访问$arr['rubish']。所以,它只是不安全。 b)它会产生“PHP Notice”消息(除非通知被禁止)

  • $arr[@key] - 就像之前一样,但没有通知。事实上,在可维护性方面,错误抑制非常糟糕。

  • $arr["key"] - 绝对有效的方式,除非你在双引号字符串中有一些特殊的符号。例如:"ab\ntc" != 'ab\ntc'"ab$c" != 'ab$c'等。但我相信,考虑这种情况有点偏执。

  • $arr['key'] - 就我而言,这是最接近Ruby的arr[:key],因为你可以用PHP获得。

答案 4 :(得分:0)

关联数组是您唯一的选择。

http://railsforphp.com/reference/array/array - 第二个标题。

答案 5 :(得分:0)

您可以使用简单对象来获得与ruby中的符号类似的效果。某些数据库函数具有FETCH_OBJECT选项以模拟此效果。

class StoreMe {
    public $A;
    public $B;
    public $C;
    public $D;
}

符号的主要优点是用作散列键来优化性能和内存使用。由于PHP使用“Copy on write”来存储变量,因此字符串可能与ruby中的符号相同。但PHP使用某种类型的转换表来从散列键获取数组的索引。所以每个小阵列都有一定的开销。

<强> Testscript

我写了这个小脚本来测试PHP的内存占用。

error_log("Start:  " . memory_get_usage());
$iterations = 10000;

$hash = [];
for ($i=0; $i<$iterations; $i++) {
    $hash[] = [
        "A" => "Test",
        "B" => "Test",
        "C" => "Test",
        "D" => "Test",
    ];
}
error_log("String: " . memory_get_usage());    
$hash = null;
error_log("Reset:  " . memory_get_usage());

$hash = [];
for ($i=0; $i<$iterations; $i++) {
    $hash[] = [
        "Test",
        "Test",
        "Test",
        "Test",
    ];
}
error_log("Raw:    " . memory_get_usage());
$hash = null;
error_log("Reset:  " . memory_get_usage());

$hash = [];
$copy = [
        "Test",
        "Test",
        "Test",
        "Test",
    ];
for ($i=0; $i<$iterations; $i++) {
    $hash[] = $copy;
}
error_log("Copy:   " . memory_get_usage());
$hash = null;
error_log("Reset:  " . memory_get_usage());

$hash = [];
for ($i=0; $i<$iterations; $i++) {
    $store = new StoreMe();
    $store->A = "Test";
    $store->B = "Test";
    $store->C = "Test";
    $store->D = "Test";
    $hash[] = $store;
}
error_log("Object: " . memory_get_usage());
$hash = null;
$store = null;
error_log("Reset:  " . memory_get_usage());

以下是PHP官方Docker镜像的结果。正确的值是以字节为单位的内存消耗。

PHP 5.6

Start:  225680
String: 8837400
Reset:  226088
Raw:    8837400
Reset:  226088
Object: 5580488
Reset:  1209264

PHP 7.0

Start:  355400
String: 4643840
Reset:  355400
Raw:    4643840
Reset:  355400
Copy:   884216
Reset:  355776
Object: 2127096
Reset:  478656

PHP 7.1

Start:  355336
String: 883776
Reset:  355336
Raw:    883776
Reset:  355336
Copy:   883776
Reset:  355336
Object: 2126656
Reset:  478216

<强>结论

对象确实需要更少的内存。但PHP 5.6似乎存在使用对象进行垃圾收集的问题。 PHP 7.1的结果似乎是某种编译器优化,因为“写入时复制”和创建数组没有区别。