PHP 相当于 Ruby 符号

发布于 2024-10-22 06:29:18 字数 199 浏览 3 评论 0原文

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

我猜这与问题的答案相同 是否有Python 相当于 Ruby 符号?

Does PHP have symbols like Ruby? Or, should I just use strings as the keys in a PHP associative array?

I'm guessing it's the same answer as that of the question Is there a Python equivalent to Ruby symbols?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

黑色毁心梦 2024-10-29 06:29:18

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

所以不。使用字符串作为键。

PHP has definable constants, but that's not really very useful in this context.

So no. Use strings as keys.

披肩女神 2024-10-29 06:29:18

如果您担心使用字符串作为数组键的过载以及数组每次都被复制而不是作为引用传递的事实,我可以建议您使用 stdClass,它基本上是一个对象类可以像数组一样动态修改,但它的行为就像一个对象。

If your concern is the overload of using strings as array keys and the fact that the array is copied instead of passed as reference every time, I can suggest you to use stdClass, that is basically an object class that can be modified dynamically, array-like, but it behaves as an object.

另类 2024-10-29 06:29:18

PHP 没有类似符号的东西,甚至常量在 PHP 中的工作方式也与在 Ruby 中的工作方式显着不同。数组键必须是字符串或数字。您可以将字符串或数字分配给常量,然后“使用”该常量作为数组键。但是,常量在 PHP 中是静态的,因此这可能不是您想要的,需要更多“样板”代码,并且实际的数组键最终仍将是字符串或数字(基于常量的值)。

PHP has nothing like symbols, and even constants work significantly different in PHP than they do in ruby. Array keys must be string or numeric. You can assign a string or number to a constant, and then "use" the constant as the array key. But, constants are static in PHP so this might not be what you want, requires more "boilerplate" code, and the actual array key will still end up being either a string or number (based on the value of the constant).

走过海棠暮 2024-10-29 06:29:18

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

几个例子:

  • $arr[key] - 在大多数情况下,这与 $arr['key'] 一样工作,但有几个缺点:
    a) 如果确实存在定义的常量(例如,define('key', 'rubbish') - 您将访问$arr['rubish']。所以,这根本不安全。
    b) 它将生成“PHP 通知”消息(除非通知被抑制)

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

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

  • $arr['key'] — 在我看来,这是最接近 PHP 中的 Ruby 的 arr[:key]

No, PHP does not have anything like this. The most close approximation in PHP would be to use single-quoted strings for your hash keys — just to make sure there would be no "interpolations" in them.

Few examples:

  • $arr[key] — this would work like $arr['key'] in most cases, but has couple of drawbacks:
    a) if there is indeed a defined constant (e.g., define('key', 'rubbish') — you'll access $arr['rubish']. So, it's simply unsafe.
    b) it would produce "PHP Notice" messages (unless notices are suppressed)

  • $arr[@key] — just like before, but without notices. In fact, errors suppressing is very bad in terms of maintainability.

  • $arr["key"] — absolutely valid way, unless you have some special symbols inside the double-quoted string. For example: "ab\ntc" != 'ab\ntc', "ab$c" != 'ab$c' and so on. But its a bit paranoid to think of such cases, I believe.

  • $arr['key'] — this is, to my opinion, the closest to Ruby's arr[:key] as you could get in PHP.

一枫情书 2024-10-29 06:29:18

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

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

Associative arrays are your only option.

http://railsforphp.com/reference/array/array - 2nd header.

千秋岁 2024-10-29 06:29:18

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

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

符号的主要优点是用作哈希键来优化性能和内存使用。由于 PHP 使用“写入时复制”来存储变量,因此字符串可能与 ruby​​ 中的符号等效。但是 PHP 使用某种类型的转换表从哈希键获取数组的索引。所以每个小数组都有一定的开销。

测试脚本

我编写了这个小脚本来测试 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 的结果似乎是某种编译器优化,因为“写入时复制”和创建数组没有区别。

You can use simple objects to have a similar effect like symbols in ruby. Some database functions have an FETCH_OBJECT option to emulate this effect.

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

The main advantage of symbols is the use as hash keys to optimize performance and memory usage. Since PHP uses "Copy on write" for storing variables, strings might be equivalent like symbols in ruby. But PHP uses some type of translation table to get index for an array from an hash key. So every small array has a certain overhead.

Testscript

I wrote this small script to test the memory footprint with 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());

Here are the results with the official Docker images for PHP. The right value is the memory consumption in bytes.

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

Conclusion

Objects do need less memory like expected. But PHP 5.6 seems to have problems with garbage collection using objects. The results from PHP 7.1 seem to be some kind of compiler optimization, cause there is no difference on "Copy on write" and creating the arrays.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文