Переменная undefined при использовании в качестве ключа массива [duplicate]

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

>>> import regex as re
>>> match = re.findall(r'\w\w', 'hello', overlapped=True)
>>> print match
['he', 'el', 'll', 'lo']

137
задан Taryn 22 March 2017 в 17:16
поделиться

3 ответа

Что такое «переменная область»?

Переменные имеют ограниченный «объем» или «места, из которых они доступны». Только потому, что вы написали $foo = 'bar'; один раз где-то в вашем приложении, это не значит, что вы можете ссылаться на $foo из всюду else внутри приложения. Переменная $foo имеет определенную область действия, в пределах которой она действительна, и только код в той же области доступа имеет доступ к переменной.

Как область, определенная в PHP?

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

Пример:

<?php

$foo = 'bar';

function myFunc() {
    $baz = 42;
}

$foo находится в области global , $baz находится внутри локального области внутри myFunc. Только код внутри myFunc имеет доступ к $baz. Только код вне myFunc имеет доступ к $foo. Ни один из них не имеет доступа к другому:

<?php

$foo = 'bar';

function myFunc() {
    $baz = 42;

    echo $foo;  // doesn't work
    echo $baz;  // works
}

echo $foo;  // works
echo $baz;  // doesn't work

Сфера охвата и включенные файлы

Границы файлов не разделяют область :

a.php

<?php

$foo = 'bar';

b.php

<?php

include 'a.php';

echo $foo;  // works!

Те же правила применяются к коду include d как применяется к любому другому коду: только отдельная область function. Для области видимости вы можете включить такие файлы, как копирование и вставка кода:

c.php

<?php

function myFunc() {
    include 'a.php';

    echo $foo;  // works
}

myFunc();

echo $foo;  // doesn't work!

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

Что касается функций внутри функций и классов?

Каждое новое объявление function вводит новую область, это так просто.

(анонимные) функции внутри функций

function foo() {
    $foo = 'bar';

    $bar = function () {
        // no access to $foo
        $baz = 'baz';
    };

    // no access to $baz
}

classes

$foo = 'foo';

class Bar {

    public function baz() {
        // no access to $foo
        $baz = 'baz';
    }

}

// no access to $baz

Что такое область видимости?

Работа с проблемами определения области может показаться раздражающей, но ограниченная переменная область важна для написания сложных приложений! Если каждая переменная, которую вы объявляете, будет доступна везде, где бы вы ни находились, вы будете переключаться со всеми своими переменными без реального способа отслеживать, что изменит что. Есть только так много разумных имен, которые вы можете дать своим переменным, вы, вероятно, захотите использовать переменную «$name» в нескольких местах. Если бы вы могли использовать только одно уникальное имя переменной в своем приложении, вам придется прибегать к действительно сложным схемам именования, чтобы убедиться, что ваши переменные уникальны и что вы не меняете неправильную переменную из неправильной части кода.

Обратите внимание:

function foo() {
    echo $bar;
}

Если не было области, что бы сделала эта функция выше? Откуда $bar? Какое состояние оно имеет? Он даже инициализирован? Вы должны проверять каждый раз? Это не поддерживается. Это приводит нас к ...

границы границ пересечения

Правильный путь: передача переменных в и из

function foo($bar) {
    echo $bar;
    return 42;
}

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

$baz   = 'baz';
$blarg = foo($baz);

Расширение области видимости в анонимных функциях

$foo = 'bar';

$baz = function () use ($foo) {
    echo $foo;
};

$baz();

Анонимная функция явно включает $foo из ее окружения. Обратите внимание, что это не то же самое, что область global .

Неправильный путь: global

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

$foo = 'bar';

function baz() {
    global $foo;
    echo $foo;
    $foo = 'baz';
}

Эта функция использует и изменяет глобальную переменную $foo. Не делай это! [Если вы действительно действительно действительно знаете, что делаете, и даже тогда: не делайте этого!) [/ ​​G45]

Все вызывающие функции этой функции видят следующее:

baz(); // outputs "bar"
unset($foo);
baz(); // no output, WTF?!
baz(); // outputs "baz", WTF?!?!!

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

Вам следует избегать использования глобальной области в любом случае насколько это возможно; конечно, вы не должны «вытягивать» переменные из глобальной области в локальную область.

152
ответ дан deceze 15 August 2018 в 18:22
поделиться
  • 1
    Вы просто сказали неверный путь для global , поэтому, пожалуйста, сообщите нам, когда мы должны использовать global? И, пожалуйста, объясните (немного) что это static ..? – user 28 June 2015 в 10:14
  • 2
    @stack Нет "right & quot; путь для global. Это всегда неправильно. Параметры передаваемой функции являются правильными. static хорошо объясняется в руководстве и не имеет большого отношения к сфере применения. В двух словах это можно рассматривать как «глобальную переменную с ограниченной областью». Я немного расширяю его использование здесь kunststube.net/static . – deceze♦ 28 June 2015 в 12:15
  • 3
    Моя простая мысль заключается в том, что переменная php достаточно важна, чтобы заслужить глобальный статус, она заслуживает столбца в базе данных. Может быть, это перебор, но это безупречный подход, который подходит моему посредственному программированию – Arthur Tarasov 3 August 2017 в 08:22
  • 4
    @Arthur Есть так много, чтобы распаковать там ... ಠ_ಠ Это, безусловно, не подход, который я бы одобрил. – deceze♦ 3 August 2017 в 08:24
  • 5
    @deceze wee бит аргумента, происходящего здесь сегодня stackoverflow.com/q/51409392 - где OP упоминает, что дубликат (здесь) не упоминает о include_once и, возможно, require_once, также должен быть добавлен где-то; просто говорю. ОП проголосовал за возобновление своего вопроса. Будет ли их сообщение частным случаем и что с этим нужно сделать? – Funk Forty Niner 18 July 2018 в 19:31

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

Что это за «статическая переменная»?

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

function countSheep($num) {
 static $counter = 0;
 $counter += $num;
 echo "$counter sheep jumped over fence";
}

countSheep(1);
countSheep(2);
countSheep(3);

Результат:

1 sheep jumped over fence
3 sheep jumped over fence
6 sheep jumped over fence

Если бы мы определили $counter без static, то каждый раз эхо-значение будет будет таким же, как параметр $num, переданный функции. Использование static позволяет построить этот простой счетчик без дополнительного обхода.

Использование прецедентов статических переменных

  1. Чтобы сохранить значения между последовательными вызовами функции.
  2. Сохранять значения между рекурсивными вызовами, когда нет пути (или нет цели) для передачи их в качестве параметров.
  3. К кеш-значению, которое обычно лучше извлекать один раз. Например, результат чтения неизменяемого файла на сервере.

Трюки

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

Статическая переменная может быть определена только как скалярным или как скалярное выражение (с PHP 5.6). Присвоение других ценностей неизбежно приводит к отказу, по крайней мере, на момент написания этой статьи. Тем не менее вы можете сделать это только на следующей строке вашего кода:

function countSheep($num) {
  static $counter = 0;
  $counter += sqrt($num);//imagine we need to take root of our sheep each time
  echo "$counter sheep jumped over fence";
}

Результат:

2 sheep jumped over fence
5 sheep jumped over fence
9 sheep jumped over fence

Статическая функция «разделена» между методами объектов тот же класс. Это легко понять, просмотрев следующий пример:

class SomeClass {
  public function foo() {
    static $x = 0;
    echo ++$x;
  }
}

$object1 = new SomeClass;
$object2 = new SomeClass;

$object1->foo(); // 1
$object2->foo(); // 2 oops, $object2 uses the same static $x as $object1
$object1->foo(); // 3 now $object1 increments $x
$object2->foo(); // 4 and now his twin brother

Это работает только с объектами того же класса.

Является ли статическая переменная единственным способом сохранить значения между вызовами функции?

Другим способом сохранения значений между вызовами функций является использование замыканий. Закрытие было введено в PHP 5.3. В двух словах они позволяют ограничить доступ к некоторому набору переменных внутри области функций другой анонимной функцией, которая будет единственным способом доступа к ним. Быть в закрывающих переменных могут имитировать (более или менее успешно) концепции ООП, такие как «константы класса» (если они были переданы в закрытии по значению) или «частные свойства» (если они переданы по ссылке) в структурированном программировании.

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

9
ответ дан alex_edev 15 August 2018 в 18:22
поделиться

Объем переменной - это контекст, в котором он определен. По большей части все переменные PHP имеют только одну область. В эту единую область охвата включены и требуемые файлы. Например:

<?php
$a = 1;
include 'b.inc';
?>

Здесь переменная $a будет доступна в включенном скрипте b.inc. Однако в пользовательских функциях вводится локальная функция. Любая переменная, используемая внутри функции, по умолчанию ограничена областью локальных функций. Например:

<?php
$a = 1; /* global scope */ 

function test()
{ 
    echo $a; /* reference to local scope variable */ 
} 

test();
?>

Этот сценарий не будет выдавать какой-либо вывод, потому что оператор echo ссылается на локальную версию переменной $ a, и ей не присваивается значение в этой области. Вы можете заметить, что это немного отличается от языка C в том, что глобальные переменные в C автоматически доступны для функций, если они не переопределены локальным определением. Это может вызвать некоторые проблемы в том, что люди могут непреднамеренно изменить глобальную переменную. В PHP глобальные переменные должны быть объявлены глобальными внутри функции, если они будут использоваться в этой функции.

6
ответ дан Josip Ivic 15 August 2018 в 18:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: