Pull to refresh

Comments 35

Как раз сегодня видел шутку в тему


UFO just landed and posted this here

Тут дело не только в авторе статьи, но и в переводчике. Ляпов хватает и у того, и у другого, а всё вместе — получилась так себе статья...

Вы имеете в виду, что mb_string по умолчанию не включен?

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

mb_string достаточно популярный модуль
Только не для англоговорящих, коим и является автор оригинальной статьи.

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

Это точно. Англоязычные разработчики не особо парятся по этому поводу. Совсем недавно столкнулся с такой проблемой в climate.
Автор и переводчик, видимо, не знают, что illuminate/support это не только 4 килограмма диетического мяса хэлперов, но ещё и базовые классы фреймворка типа сервис-провайдера и менеджер, и что из упомянутых 6000+ пакетов большая часть является именно пакетами для ларавел.

dd бесполезен в терминале
Феерично, просто феерично…
Так речь идет только о framework agnostic пакетах которые зависят от illuminate/support, если вы пишете пакет который будет работает только с laravel или lumen то ничего плохого в использовании illuminate/support нет.
Это сначала речь идёт только о framework agnostic пакетах, а потом упоминаются некие «более 6000 пакетов».
То есть на самом деле повторное использование кода — зло? :)

Тогда не используйте вообще фреймворки.
> а dd бесполезен в терминале
Ахаха, делает http запрос к сайту и удивляется, что ему в консоль падает html от dd… К слову, в cli — dd не генерирует html.
isset($arr[$k])? $arr[$k]: null

Я немного отстал от жизни, но зачем писать так?

Ведь «isset(expr)» по сути означает «expr !== null» (точнее, isset ещё не показывает ошибки в случае несуществования переменной/индекса, поэтому на самом деле «@expr !== null»). Т.е. приведенный выше кусок кода по сути означает «@$arr[$k] !== null ? $arr[$k] : null», только больше запутан. Почему не написать просто «@$arr[$k]»?

Я понимаю, если бы было «array_key_exists($k, $arr) ? $arr[$k] : null» — это, хоть и длинно, но передаёт логический смысл.
Я собственно тоже не понимаю зачем так пишут, но многие пишут просто «потому что так короче».
А, собственно, я понял. Вы, наверное, имели в виду не «@$arr[$k] !== null ? $arr[$k] : null», а «@$arr[$k] !== null ? $arr[$k] : $default»?
Чем array_key_exists($k, $arr)? $arr[$k]: null
А символ @ я вообще не использую.
Часто пишу вот так:
$arr = ['key' => 'value'];

$a = @$arr['key'] ?: NULL;
$b = @$arr['nonexistent'] ?: NULL;

var_dump($a); // string(5) "value"
var_dump($b); // NULL

И коротко, и логический смысл вполне понятен, как мне кажется.
А 0, '' и array() у Вас никогда не бывают значениями массива?
Чаще всего в таких случаях это используется в качестве значения по умолчанию.
Ничего же не мешает написать:
$a = @$arr['key'] ?: [];
Ну, это уже более осмысленно (ИМХО).
Но всё же в случае со строками (как в исходном Вашем примере) Вы потеряете значение '0'.
Т.е. «@$arr['key'] ?: ''» вернёт '' и для значения '', и для значения '0'.
UFO just landed and posted this here
Ну не на порядок медленнее:

Заголовок спойлера
<?php

$iters = 1000000;

$arr = [];
foreach (range(1, $iters) as $i) {
    $arr[$i*2] = $i;
}



$t = microtime(true);
foreach (range(1, $iters) as $i) {
    $a = $arr[$i] ?? null;
}
print microtime(true)-$t;
print "\n";


$t = microtime(true);
foreach (range(1, $iters) as $i) {
    $a = isset($arr[$i]) ? $arr[$i] : null;
}
print microtime(true)-$t;
print "\n";


$t = microtime(true);
foreach (range(1, $iters) as $i) {
    $a = array_key_exists($i, $arr) ? $arr[$i] : null;
}
print microtime(true)-$t;
print "\n";


$t = microtime(true);
foreach (range(1, $iters) as $i) {
    $a = @$arr[$i];
}
print microtime(true)-$t;
print "\n";



??               1.3513998985291
isset            1.6450479030609
array_key_exists 9.281585931778
@                4.6198010444641

У нас используется error handler. Поэтому оператор подавления ошибок не используем.
Добавьте error handler и тогда время, затраченное на "@" улетит в космос.
Да, с пустым хэндлером как раз на порядок:

1.4448421001434
1.7445378303528
8.413987159729
10.663077116013
Все, кто пользуется в таком контексте @, будут гореть в аду.
Часто пишу вот так:

обновляйтесь на php7 и прекращайте


$a = $arr['key'] ?? null;
$b = $arr['nonexistent'] ?? null;

Оператор подавления ошибок — лучше бы его в PHP вообще небыло.

Про "??" безусловно согласен (мне непонятно зачем вообще вводили "?:" без среднего операнда вместо того, чтобы сразу ввести нормальный coalesсe; учитывая, что в PHP ошибка/отсутствие индицируется либо возвратом null, либо возвратом false, PHP нужны два а-ля-coalesce оператора: «coalesceNull(a, b) = a!==null ? a : b» и «coalesceStrictFalse(a, b) = a!==false? a : b»; первый уже НАКОНЕЦ-ТО ввели в виде "??", теперь ждём второго).

Но про подавление ошибок не понимаю. Ведь isset и "??" (а также empty) и так логически (зачем-то) включают в себя подавление ошибок. Что не так-то? По-моему, было бы лучше, если бы они как раз НЕ включали в себя подавление ошибок и одним оператором делалась ровно одна вещь (писали бы «@$arr[$key] ?? $default» или «array_key_exists($key, $arr) ? $arr[$key] : $default»), без смешения сущностей.
и так логически (зачем-то) включают в себя подавление ошибок

нет, они не "подавляю ошибки", они просто их не вызывают. Вы просто проверяете есть там значение или нет.

Я-то это понимаю. Но считаю это неправильным. В смысле:
1. Если выражение «expr» вызывает ошибку, то логично, чтобы любое выражение, содержащее «expr» (в том числе, например, «isset(expr)» и т.п.) в качестве операнда вызывало ту же ошибку. Не вызывать в таком случае ошибку глупо — для проверки без вызова ошибки должны использоваться отдельные конструкции (например, «array_key_exists($key, $array)» вместо «isset($array[$key])» и какое-то пока несуществующее «variable_exists('varname')» вместо «isset($varname)» и т.д.).
2. Даже если допустить, что существование какого-то оператора «op(…)», не вызывающего ошибку для вызывающего ошибку выражения «expr», логично — то к isset всё равно это не относится. Так как isset дважды нелогично — кроме описанного в предыдущем пункте, оно ещё пытается выполнить два действия сразу: оно проверяет наличие (переменной, индекса, поля) и проверяет на неравенство null. Т.е. я бы ещё согласился использовать какой-то оператор «exists(…)», не вызывающий ошибку для вложенного выражения — если бы он просто проверял наличие.

Короче говоря. Я понимаю, что isset быстрее @/array_key_exists. Я понимаю, что isset не является полным эквивалентом "@expr !== null" (кроме разного поведения в случае наличия обработчиков ошибок, оно ещё по-разному реагирует на ошибки в подвыражениях, например, «isset($arr[f()])» не подавит ошибку внутри фукнции f, а «@$arr[f()]» — подавит). Но лучше я потеряю несколько микросекунд, чем буду писать уродливый код с isset.

Что же касается "??", то как я уже говорил выше, хорошо, что его наконец-то ввели (не понимаю, почему так поздно, в частности позднее уродливого бинарного "?:"), плохо, что на него распространяется «магия» в стиле isset/empty (лучше бы сделали array_key_exists встроенным оператором для быстродействия) — но использовать его мне, думаю, не придётся, потому что я завязал с PHP задолго до появления даже 5.6-й версии.
На счёт проблемы версии illuminate/support, можно свободно писать в composer-е вашего пекиджа: 5.1.*|5.2.*|5.3.* если конечно уверены что все они подходят для вашего package.
Sign up to leave a comment.

Articles