PHP что НАДО знать новичку
5674
7
Создам тему дабы не уплыла полезная ссылка. Да и добавлять будет куда новые "фичи"...

Вот этот перечень "особенностей" считаю надо знать наизусть любому, кто хочет с пользой что-то делать на этом псевдоязыке: http://habrahabr.ru/post/142140/

Из неожиданного поведения:


// как известно, функция может получать параметр разного типа (mixed):
function myFunc( $param ) {

if( !empty($param['myKey']) ) {
echo 'param-mykey is not empty';
} else {
echo 'param-mykey is empty or not present';
}
return;
}

// 1-й вызов:
myFunc( array('myKey1'=>123) ); // ... is empty or not present

// 2-й вызов:
myFunc( '123' ); // ... is not empty! при этом $param['myKey'] будет равно 1!



Неожиданно, не правда ли? А всё объяснимо и достаточно просто:
1. В PHP строка есть массив, соответственно вполне допустимо $param['myKey']...
2. Идентификатора (ключа) myKey в псевдомассиве интерпретатор есстественно НЕ находит и поскольку false эквивалентен 0, то ноль и возвращается как номер элемента массива.
3. Ошибки не возникает по причине того, что любая переменная может быть объявлена "на ходу" по мере необходимости.
4. А вот псевдомассив - строка, как раз имеет элемент с номером 0. Значение которого и равно в данном примере 1.

В ряде случаев может породить весьма неприятное поведение...
tolstopuz
добавлю в тему - для новичков, если нужно определить существует ли переменная или ключ массива, юзайте isset($var), и только после этого проверяйте, empty эта переменная (если есть) или не empty.
keys
+1 Хороший совет, и его можно обобщить: учитывая, что переменные могут объявляться "на лету", любую проверку желательно предварять проверкой на наличие переменной, а ещё важнее - элементов массивов или свойства объектов (которые тоже практически массивы).

То есть, по-просту перед любой проверкой желательно втыкать isset($var) && ...далее собственно проверка.

Дополню: ... и не важно, что в описании empty() включает в себя проверку isset()... вот такой он PHP.:миг:
tolstopuz
Ещё маразм, который трудно понимается и мало где описан:


1. echo 'тут какой-то текст =' . $pos=myfunc($part1) . ', тут продолжение строки';

2. echo 'тут какой-то текст =' . ( $pos=myfunc($part1) ) . ', тут продолжение строки';


Второй вариант верен, а первый - нет. Любые подвыражения, вычисляемые внутри операторов echo, передаваемых параметрах, if и т.д. НАДО заключать в отдельные, собственные скобки.

Иначе - результат не предсказуем
, или не делать так ваще. То есть втыкать присваивание внутрь других операторов - писать неоднозначно работающий код.
tolstopuz
или не делать так ваще.
Вот на этом остановиться и другие варианты даже не рассматривать...
tolstopuz
Ещё маразм
А помоему все верно, оноже вычесляемое. Навскидку в томже баше апсолютно также.
tolstopuz
Так, а я не пойму, что тут неожиданного? По-моему, это в ТД PHP написано. Строка не относится к объектному типу данных, но ведет себя в некоторых случаях подобно массиву))
stroryte11er
Объектные типы данных - тут ваще не причем.

Да, то что строка является массивом - написано в мануале. Но, (ещё одна "особенность"!) попробуйте запустить по ней цикл, скажем foreach() и будете неприятно удивлены.

Именно, что только "иногда". Ни разу не пгобовали пробежаться по строке "посимвольно"? Это не такая тривиальная задача, как может показаться с первого взгляду.

Почему поведение интерпретатора - кривое, я описал в предыдущем примере (как он додумывается до такого). Там только один "изъян":

выражение $var['const'] должно интерпретироваться как элемент ассоциативного массива. И никак иначе.
Псевдофункция empty() - в том числе ОБЯЗАНА проверять наличие элемента именно ассоциативного массива в данном случае (часть описания isset).

Потому что по тексту сначала идет разименование имени параметра, и дополнительно указание на выборку для проверки элемента параметра - ассоциативного массива. Вот эта, вторая операция интерпретатора и должна была выдать результат проверки "отсуствует". Потому как поиск отсутствующего элемента должен был уже на этом этапе вернуть null. Который и есть true для empty(). Строка - массив, но нумерованный, а не ассоциативный. и Разыскать в ней ассоциативный член, попутно создав его - просто "верх пилотажа".

Проблема в том, что empty() и не заморачивается на проверку структуры. Действительно - нафига?

Любой нормальный ЯП - обладает таким явлением как Синтасическая Диаграмма. Её прелесть в том, что любая ситуация для LL-грамматик (и не только, но это - бОльшая часть ЯП) - однозначны.

Дело в том, что ПХП - ваще не ЯП. Это набор библиотек и способов их использования (внешне похожих на ЯП) для сервера Apache. И все эти "иногда" - как раз легко и просто объясняются этим фактом.

Может он и "хочет стать языком"... но только идет уж очень кружным путем.