Синтаксис PHP для результата функции разыменования

Задний план

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

Однако в PHP это выглядит не так просто:

example1 (результат функции – массив)

<?php function foobar(){ return preg_split('/\s+/', 'zero one two three four five'); } // can php say "zero"? /// print( foobar()[0] ); /// <-- nope /// print( &foobar()[0] ); /// <-- nope /// print( &foobar()->[0] ); /// <-- nope /// print( "${foobar()}[0]" ); /// <-- nope ?> 

example2 (результат функции – объект)

 <?php function zoobar(){ // NOTE: casting (object) Array() has other problems in PHP // see eg, http://stackoverflow.com/questions/1869812 $vout = (object) Array('0'=>'zero','fname'=>'homer','lname'=>'simpson',); return $vout; } // can php say "zero"? // print zoobar()->0; // <- nope (parse error) // print zoobar()->{0}; // <- nope // print zoobar()->{'0'}; // <- nope // $vtemp = zoobar(); // does using a variable help? // print $vtemp->{0}; // <- nope 

Может ли кто-нибудь предложить, как это сделать в PHP?

Related of "Синтаксис PHP для результата функции разыменования"

Это, в частности, разбор разыменования массивов, который в настоящее время не поддерживается в php5.3, но должен быть возможен в следующей версии 5.4. С другой стороны, разыменование объектов возможно в текущих версиях php. Я также с нетерпением жду этой функциональности!

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

Так что вам нужно это делать.

 $var = foobar(); print($var[0]); 

Выделение массива возможно с PHP 5.4:

Пример ( источник ):

 function foo() { return array(1, 2, 3); } echo foo()[2]; // prints 3 

с PHP 5.3 вы получите

 Parse error: syntax error, unexpected '[', expecting ',' or ';' 

Оригинальный ответ:

Об этом уже говорили . Ответ – нет. Это невозможно.

Процитировать Andi Gutmans на эту тему:

Это хорошо известный запрос функции, но не поддерживается в PHP 5.0. Я не могу сказать вам, будет ли это когда-либо поддерживаться. Это требует некоторых исследований и много мыслей.

Вы также можете найти этот запрос несколько раз в PHP Bugtracker. Для получения технических подробностей я предлагаю вам проверить официальный RFC и / или спросить на PHP Internals .

Ну, вы можете использовать любое из следующих решений, в зависимости от ситуации:

 function foo() { return array("foo","bar","foobar","barfoo","tofu"); } echo(array_shift(foo())); // prints "foo" echo(array_pop(foo())); // prints "tofu" - function foo() { return array("foo","bar","foobar","barfoo","tofu"); } echo(array_shift(foo())); // prints "foo" echo(array_pop(foo())); // prints "tofu" 

Или вы можете получить определенные значения из возвращаемого массива, используя list () :

 list($foo, $bar) = foo(); echo($foo); // prints "foo" echo($bar); // print "bar" 

Изменить: код примера для каждого (), который я дал ранее, был неправильным. each () возвращает пару ключ-значение. Поэтому было бы проще использовать foreach () :

 foreach(foo() as $key=>$val) { echo($val); } 

К сожалению, этого не сделать, хотя это и есть на большинстве других языков программирования.

Если вы действительно хотите сделать один лайнер, вы можете сделать функцию под названием a () и сделать что-то вроде

 $test = a(func(), 1); // second parameter is the key. 

Но кроме этого, func () [1] не поддерживается в PHP.

Как уже отмечали другие, это невозможно. Синтаксис PHP не позволяет этого. Однако у меня есть одно предложение, которое атакует проблему с другого направления.

Если вы контролируете метод getBarArray и имеете доступ к стандартной библиотеке PHP (установленной на многих хостах PHP 5.2.X и устанавливаемой по умолчанию с помощью PHP 5.3), вам следует рассмотреть возможность возврата ArrayObject вместо собственного массива / коллекции PHP. ArrayObjects есть метод offetGet , который можно использовать для извлечения любого индекса, поэтому ваш код может выглядеть примерно так:

 <?php class Example { function getBarArray() { $array = new ArrayObject(); $array[] = 'uno'; $array->append('dos'); $array->append('tres'); return $array; } } $foo = new Example(); $value = $foo->getBarArray()->offsetGet(2); 

И если вам когда-либо понадобится собственный массив / коллекция, вы всегда можете отдать результаты.

 //if you need $array = (array) $foo->getBarArray(); 

Напишите функцию обертки, которая выполнит то же самое. Из-за легкого выбора типа PHP это может быть довольно открытым:

 function array_value ($array, $key) { return $array[$key]; } 

Если вы просто хотите вернуть первый элемент в массиве, используйте функцию current ().

 return current($foo->getBarArray()); 

http://php.net/manual/en/function.current.php

Фактически, я написал библиотеку, которая допускает такое поведение:

http://code.google.com/p/php-preparser/

Работает со всем: функциями, методами. Кэши, так быстро, как сам PHP 🙂

Вы не можете array_test() выражения, подобные этому в PHP, поэтому вам нужно сохранить результат array_test() в переменной.

Попробуй это:

 function array_test() { return array(0, 1, 2); } $array = array_test(); echo $array[0]; 

Это слишком надуманно, но если вам действительно нужно быть в одной строке:

 return index0( $foo->getBarArray() ); /* ... */ function index0( $some_array ) { return $some_array[0]; } 

Конечно, вы могли бы вернуть объект вместо массива и получить доступ к нему следующим образом:

 echo "This should be 2: " . test()->b ."\n"; 

Но я не нашел возможности сделать это с помощью массива 🙁

мое обычное обходное решение – иметь такую ​​общую функцию, как эта

  function e($a, $key, $def = null) { return isset($a[$key]) ? $a[$key] : $def; } 

а потом

  echo e(someFunc(), 'key'); 

в качестве бонуса это также предотвращает предупреждение «неопределенного индекса», когда оно вам не нужно.

Что касается причин, почему foo()[x] не работает, ответ довольно невежлив и не собирается публиковаться здесь. 😉

Это некоторые способы приблизиться к вашей проблеме.

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

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

 function test() { return array(1, 2); } list($a, $b) = test(); echo "This should be 2: $b\n"; function test2() { return new ArrayObject(array('a' => 1, 'b' => 2), ArrayObject::ARRAY_AS_PROPS); } $tmp2 = test2(); echo "This should be 2: $tmp2->b\n"; function test3() { return (object) array('a' => 1, 'b' => 2); } $tmp3 = test3(); echo "This should be 2: $tmp3->b\n"; 

Исключительно гетто, но это можно сделать, используя только PHP. Это использует лямбда-функцию (которые были введены в PHP 5.3). Смотрите и удивляйтесь (и, гм, испугавшись):

 function foo() { return array( 'bar' => 'baz', 'foo' => 'bar', } // prints 'baz' echo call_user_func_array(function($a,$k) { return $a[$k]; }, array(foo(),'bar')); 

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

Для записи я делаю что-то похожее на то, что делает Нолте. Извините, если я сделал чьи-то глаза кровоточащими.

После дальнейших исследований я считаю, что ответ отрицательный, временная переменная вроде этого действительно канонический способ обработки массива, возвращаемого функцией.

Похоже, это изменится, начиная с PHP 5.4.

Кроме того, этот ответ был первоначально для этой версии вопроса:

Как избежать временных переменных в PHP при использовании массива, возвращаемого функцией

Если это просто эстетично, тогда нотация объекта будет работать, если вы вернете объект. Что касается управления памятью, временная копия не производится, а только изменение ссылки.

Короткий ответ:

Да. Можно работать с возвращаемым значением функции в PHP, пока результат функции и ваша конкретная версия PHP поддерживают ее.

Пример ссылки2:

 // can php say "homer"? // print zoobar()->fname; // homer <-- yup 

случаи:

  • Результат функции – массив, и ваша версия PHP достаточно современна
  • Результат функции – это объект, и член объекта, который вы хотите, доступен

Существует три способа сделать одно и то же:

  1. Как говорит Chacha102, используйте функцию для возврата значения индекса:

     function get($from, $id){ return $from[$id]; } 

    Затем вы можете использовать:

     get($foo->getBarArray(),0); 

    для получения первого элемента и т. д.

  2. Ленточный способ использования current и array_slice:

     $first = current(array_slice($foo->getBarArray(),0,1)); $second = current(array_slice($foo->getBarArray(),1,1)); 
  3. Используя ту же функцию для возврата обоих, массив и значение:

     class FooClass { function getBarArray($id = NULL) { $array = array(); // Do something to get $array contents if(is_null($id)) return $array; else return $array[$id]; } } 

    Затем вы можете получить весь массив и один элемент массива.

     $array = $foo->getBarArray(); 

    или

     $first_item = $foo->getBarArray(0); 

Ранее в PHP 5.3 вы должны были сделать это:

 function returnArray() { return array(1, 2, 3); } $tmp = returnArray(); $ssecondElement = $tmp[1]; 

Результат: 2

Начиная с PHP 5.4 можно разыменовать массив следующим образом:

 function returnArray() { return array(1, 2, 3); } $secondElement = returnArray()[1]; 

Результат: 2

Начиная с PHP 5.5:

Вы даже можете сообразить:

 echo [1, 2, 3][1]; 

Результат: 2

Вы также можете сделать то же самое со строками. Это называется разыменованием строк:

 echo 'PHP'[1]; 

Результат: H

Это работает?

  return ($foo->getBarArray())[0]; 

В противном случае вы можете опубликовать функцию getBarArray ()? Я не понимаю, почему это не сработало бы с того, что вы опубликовали до сих пор.

Вы можете использовать ссылки:

 $ref =& myFunc(); echo $ref['foo']; 

Таким образом, вы не создаете дубликат возвращаемого массива.