PHP эквивалентный символу Ruby - PullRequest
8 голосов
/ 18 марта 2011

Есть ли в PHP символы вроде Ruby?Или я должен просто использовать строки в качестве ключей в ассоциативном массиве PHP?

Я предполагаю, что это тот же ответ, что и вопрос Есть ли Python-эквивалент символов Ruby?

Ответы [ 6 ]

2 голосов
/ 12 мая 2011

Если вас беспокоит перегрузка использования строк в качестве ключей массива и тот факт, что массив копируется вместо того, чтобы каждый раз передаваться как ссылка, я могу предложить вам использовать stdClass, то есть, по сути, класс объекта, который может быть изменяется динамически, как массив, но ведет себя как объект.

2 голосов
/ 18 марта 2011

PHP имеет определяемые константы, но это не очень полезно в этом контексте.

Так что нет.Используйте строки в качестве ключей.

1 голос
/ 16 марта 2017

Нет, PHP не имеет ничего подобного.Наиболее близким приближением в PHP было бы использование строк в одинарных кавычках для ваших хеш-ключей - просто чтобы убедиться, что в них не будет «интерполяций».

Несколько примеров:

  • $arr[key] - это будет работать как $arr['key'] в большинстве случаев, но имеет несколько недостатков: a) если действительно определенная константа (например, define('key', 'rubbish') - вы получите доступ к $arr['rubish']., это просто небезопасно, б) он будет генерировать сообщения «Уведомление PHP» (если уведомления не подавлены)

  • $arr[@key] - как и раньше, но без уведомлений.На самом деле, подавление ошибок очень плохо с точки зрения удобства сопровождения.

  • $arr["key"] - абсолютно верный способ, если у вас нет специальных символов внутри строки в двойных кавычках.Например: "ab\ntc" != 'ab\ntc', "ab$c" != 'ab$c' и т. Д.Но я полагаю, что немного странно думать о таких случаях.

  • $arr['key'] - это, на мой взгляд, самый близкий к Ruby's arr[:key], как вы могли бы получить в PHP.

1 голос
/ 18 марта 2011

В PHP нет ничего похожего на символы, и даже константы в PHP работают значительно иначе, чем в ruby. Ключи массива должны быть строковыми или числовыми. Вы можете присвоить строку или число константе, а затем «использовать» константу в качестве ключа массива. Но константы являются статическими в PHP, поэтому это может быть не то, что вам нужно, требуется больше «шаблонного» кода, и фактический ключ массива все равно будет либо строкой, либо числом (в зависимости от значения константы).

0 голосов
/ 06 сентября 2017

Вы можете использовать простые объекты, чтобы иметь такой же эффект, как символы в ruby. Некоторые функции базы данных имеют опцию FETCH_OBJECT для эмуляции этого эффекта.

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

Основным преимуществом символов является использование в качестве хэш-ключей для оптимизации производительности и использования памяти. Поскольку PHP использует «Копировать при записи» для хранения переменных, строки могут быть эквивалентны символам в 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());

Вот результаты с официальными изображениями Docker для PHP. Правильное значение - это потребление памяти в байтах.

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, похоже, являются своего рода оптимизацией компилятора, потому что нет разницы в «Копировании при записи» и создании массивов.

0 голосов
/ 18 марта 2011

Ассоциативные массивы - ваш единственный выбор.

http://railsforphp.com/reference/array/array - 2-й заголовок.

...