Назначение деструктурирования в php для объектов / ассоциативных массивов

в CoffeeScript, Clojure, ES6 и многих других языках мы имеем разрушение объектов / карт / и т. д. Примерно так:

obj = {keyA: 'Hello from A', keyB: 'Hello from B'}
{keyA, keyB} = obj

Я нашел list функции в php, который позволяет вам разрушать массивы так:

$info = array('coffee', 'brown', 'caffeine');
list($drink, $color, $power) = $info;

есть ли способ уничтожить объекты или ассоциативные массивы в PHP? Если не в основных библиотеках, может быть, кто-то написал какую-то умную вспомогательную функцию?

2 ответов


для PHP 7.0 и ниже, что выходит за рамки функциональности list. В документах указано:

list работает только с числовыми массивами и предполагает, что числовые индексы начинаются с 0.

одна из вещей, которые могли бы удовлетворить ваши цели будут extract() функция, которая импортирует переменные из массива в текущую таблицу символов. В то время как с list вы можете явно определить имена переменных,extract() не дает вам эта свобода.

извлечение ассоциативного массива

С extract вы могли бы сделать что-то вроде этого:

<?php

$info = [ 'drink' => 'coffee', 'color' => 'brown', 'power' => 'caffeine' ];
extract($info);

var_dump($drink); // string(6) "coffee"
var_dump($color); // string(5) "brown"
var_dump($power); // string(8) "caffeine"

извлечение объекта

извлечение объекта работает почти так же. С extract только принимает массив в качестве аргумента, мы должны получить свойства объектов в виде массива. get_object_vars делает это для вас. Он возвращает ассоциативный массив со всеми общественные свойства как ключ и их значения как значение.

<?php

class User {

    public $name = 'Thomas';

}

$user = new User();
extract( get_object_vars($user) );

var_dump($name); // string(6) "Thomas"

подводные камни

extract() - это не то же самое как list поскольку это не позволяет явно определить имена переменных, которые экспортируются в таблицу символов. Имена переменных по умолчанию соответствуют ключам массива.

  • list - это языковая конструкция, а extract() функция
  • может случиться, что вы перезаписать переменные, которые вы определили заранее непреднамеренно
  • ключи массива могут быть недопустимыми в качестве имен переменных

С $flags параметр, который можно передать в качестве второго аргумента в extract() вы можете влиять на поведение в случае столкновения или неверные переменные. Но все же важно знать, как extract() строительство и использовать его с cauton.

Edit: начиная с PHP 7.1 это возможно:

теперь вы можете указать ключи в list () или его новый синтаксис стенографии []. Это позволяет разрушать массивы с нецелочисленными или не последовательными ключами. - http://php.net/manual/en/migration71.new-features.php#migration71.new-features.symmetric-array-destructuring

синтаксис сокращенного массива ([]) теперь может использоваться для деструкции массивов для назначений (в том числе в foreach) в качестве альтернативы существующему синтаксису list (), который все еще поддерживается. - http://php.net/manual/en/migration71.new-features.php#migration71.new-features.support-for-keys-in-list

например это:

$test_arr = ['a' => 1, 'b' => 2];
list('a' => $a, 'b' => $b) = $test_arr;
var_dump($a);
var_dump($b);

выведет следующее С 7.1.0

int(1) 
int(2)

переменные переменные-один из способов сделать это. А foreach сохраняет вас в области видимости, поэтому вы можете явно определить свои переменные из массива следующим образом:

$args = ['a' => 1, 'b' => 2, 'c' => 3];
foreach (['a', 'c'] as $v) $$v = $args[$v];
// $a is 1, $b is undefined, $c is 3

это действительно не очень красиво, и, к счастью, это было рассмотрено в 7.1 https://wiki.php.net/rfc/short_list_syntax . Это позволит вам сказать ['a' => $a, 'c' => $c] = $args; В приведенном выше примере.

поскольку 7.1 включает способ использовать другое имя для вашего var, чем ключ массива assoc, я упомяну, что это довольно прямолинейно, используя мой подход здесь тоже.

foreach (['a' => 'eh', 'b' => 'bee'] as $k => v) $$v = $args[$k];
// $eh is 1, $bee is 2