Использование вызова функции в цикле foreach

Существуют ли какие-либо проблемы с точки зрения эффективности использования вызова функции в цикле foreach. Например:

foreach ($this->getValues() as $value) { //Do something with $value } 

против

 $values = $this->getValues(); foreach ($values as $value) { //Do something with $value } 

По сути, достаточно php достаточно, чтобы вызвать $ this-> getValues ​​() только один раз в первом примере, или он вызывает его на каждой итерации. Если он называет это на каждой итерации, то как он отслеживает, какой элемент находится в данный момент,

Они оба по существу одинаковы:

 foreach ($this->getValues() as $value) { // } $values = $this->getValues(); foreach ($values as $value) { // } 

$this->getValues() будет запускаться только один раз, поскольку он не находится внутри самого цикла. Если вам нужно снова использовать возвращаемое значение getValues позже, перейдите к нему и назначьте его переменной, поэтому вам не нужно снова вызывать эту функцию. Если нет, вам не нужна переменная.

Это может быть разница, но она будет незначительной для 99,9% случаев в реальном мире. В любом случае PHP будет вызывать вашу функцию / метод только один раз. Что происходит внутри, когда вы используете foreach это то, что PHP оценивает итерацию (часть перед as ) один раз, сохраняет результат и затем перебирает его, помещая текущий элемент в локальную переменную, указанную после as . Если вы сами напишите iteratee на локальную переменную, вы практически просто дублируете усилия PHP, поэтому первый подход может нести дополнительные накладные расходы, но этого не будет достаточно, чтобы беспокоиться. Вместо этого я бы оптимизировал для чтения: если вызов функции короткий и самоописательный, включите его; если он сложный или неясный, сохраните его в описательной переменной.

Обратите внимание, что ситуация отличается от типичных for и while циклов, что, вероятно, связано с этим понятием. Например, в следующем коде:

 for ($number = 0; $number < $this->getNumberOfItems(); ++$number) { // do stuff... } 

… метод getNumberOfItems() на каждой итерации. В этой ситуации имеет смысл предварительно вычислить его и сохранить в локальной переменной.