Comments 88
Зачем перед именем класса всегда писать \?
-10
namespace A\B\C;
class Exception extends \Exception {}
$a = new Exception('hi'); // $a - это объект класса A\B\C\Exception
$b = new \Exception('hi'); // $b - это объект класса Exception
$c = new ArrayObject; // фатальная ошибка, класс A\B\C\ArrayObject не найден
Использование пространств имен: переход к глобальной функции/константе
+8
лично очень жду именнованные параметры в методах/функциях, надеялся, что, быть может, придут к консенсусу до PHP 7, но к сожалению нет :(
+6
?? джва десять лет ждал :)
+5
По-мне так просто сахарок. Ничего принципиально нового не вносит. Тренарник + isset() или empty() вполне себе годный для этих целей. Разве что цепочки не так красиво делаются, но цепочки это уже совсем экзотика.
-5
Для красоты всегда хватало
function is(){
foreach(func_get_args() as $v){
if(!is_null($v)){
return $v;
}
}
}
$value = is(null,null,false,true,1);
+1
Дело в isset, а не в проверке на null.
0
function is(&$args) {
foreach (func_get_args() as $v) {
if (!is_null($v)) {
return $v;
}
}
}
$arr = array('a' => 1, 'b' => false);
var_dump(is($arr['c'], $arr['b'], $arr['a']));
Работает как isset
0
Ага, почти:
<?php
ini_set('display_errors', true);
error_reporting(-1);
function is(&$args) {
foreach (func_get_args() as $v) {
if (!is_null($v)) {
return $v;
}
}
}
$arr = array('a' => 1, 'b' => false);
var_dump(is($arr['a'], $arr['b'], $arr['c']));
PHP Notice: Undefined index: c in test.php on line 15 Notice: Undefined index: c in test.php on line 15 int(1)
+1
У меня 5.4.32 версия под винду. Уведомление о несуществующим индексе не выскакивает. Разбираться, почему так происходит, совсем не хочется.
Проверил на убунте, так же версия из 5.4 ветки, уведомление есть.
Печаль, что тут сказать. А счастье было близко.
Проверил на убунте, так же версия из 5.4 ветки, уведомление есть.
Печаль, что тут сказать. А счастье было близко.
0
Разбираться, почему так происходит, совсем не хочется.
Ответ содержится прямо в вопросе:
версия под винду
Используйте идентичное окружение и будет вам счастье.
0
Используйте идентичное окружение и будет вам счастье.
Так исторически сложилось — сервера с виндой, Internet Explorer, бюрократия…
А убунта личная.
0
<?php
function is() {
foreach (func_get_args() as $v) {
if (!is_null($v)) {
return $v;
}
}
}
$arr = array('a' => 1, 'b' => false);
var_dump(is($arr['a'], $arr['b'], $arr['c']));
дерзай
PS сделать надо «default» return значение
0
Если принять тот факт, что первый параметр это «default» значение, то и эта задача решается.
function is($default = null, &$args1 = null, &$args2 = null, &$args3 = null) {
for ($i = 1; func_num_args() > $i; $i++) {
$value = func_get_arg($i);
if (!is_null($value)) {
return $value;
}
}
return $default;
}
$arr = array();
$return = is(false, $arr['a'], $arr['b'], $arr['c']);
var_dump($return);
0
Чуть чуть PHP5.6
function is($default = null, ...$args) {
foreach($args as $arg) {
if (!is_null($arg)) {
return $arg;
}
}
return $default;
}
$arr = array();
$return = is(false, $arr['a'], $arr['b'], $arr['c']);
var_dump($return);
0
А вы запустите мой-то пример вместо своего. У вас там первый и единственный параметр по ссылке передаётся, а вы именно туда отсутствующий подставили, вот и вся разгадка.
+1
Вы абсолютно правы. Получилось повторить ошибку. Можно решить эту проблему с кучей входных параметров по ссылкам, с дефолтным значением null. Не слишком элегантно, но можно:
Ещё вариант для версии 5.6
function is(&$args1=null, &$args2=null, &$args3=null, &$args4=null, ...) {
Ещё вариант для версии 5.6
function is(&...$args) {
0
Да это-то понятно, но тем не менее писать
приятнее чем
$blablabla ?? $default ?? 'None'
приятнее чем
isset($blablabla) ? $blablabla : (isset($default) ? $default : 'None')
+7
Если приходится часто писать isset, это что-то не то с архитектурой.
-10
Ну как сказать, внешние данные же принимать как-то нужно.
В том числе и опциональные. И не всегда можно обойтись указанием $default в $request->param().
+ данные моделей тоже могут быть необязательными.
В том числе и опциональные. И не всегда можно обойтись указанием $default в $request->param().
+ данные моделей тоже могут быть необязательными.
+1
$request->get('key', 'default')
Для «не всегда» — проверка на value lambda внутри обработчика default (как в Laravel):
$request->get('key', function() {
return result_of_some_computations;
});
Для «не всегда» — проверка на value lambda внутри обработчика default (как в Laravel):
$request->get('key', function() {
return result_of_some_computations;
});
-5
Да, признаю, куда удобнее лепить многословное php-замыкание (небось еще и замкнуть внешние переменные придётся через use), чем написать простой one-liner.
+3
Удобнее не нарушать инкапсуляцию. Количество кода — странный аргумент, так можно и переменные начать одной буквой называть.
-4
Каким образом isset() нарушает принципы инкапсуляции?
Не спорю, что красивая архитектура зачастую влечёт за собой большее число абстракций и больше кода, но в данном случае я в упор не вижу, чем пример с замыканием лучше использования isset().
А раз не видно других отличий, то логично уделить внимание читаемости кода, не?
Не спорю, что красивая архитектура зачастую влечёт за собой большее число абстракций и больше кода, но в данном случае я в упор не вижу, чем пример с замыканием лучше использования isset().
А раз не видно других отличий, то логично уделить внимание читаемости кода, не?
+4
Вопрос в том, зачем нам вообще знать напрямую о наличии атрибутов модели вне модели. Такая необходимость — четкий признак применения антипаттерна anemic models.
0
Не все параметры, обрабатываемые в контроллере, являются полями модели.
+2
В контроллере вообще не должны обрабатываться поля модели.
Касаемо же request-объекта — если нужно что-то сложнее, чем присвоение значения по умолчанию, это признак протекания бизнес-логики в контроллер.
Касаемо же request-объекта — если нужно что-то сложнее, чем присвоение значения по умолчанию, это признак протекания бизнес-логики в контроллер.
0
Поля модели не должны, а поля пришедшие от пользователя должны. Нужно что-то сложнее. Конкретно, в зависимости от выбора пользователя выбрать какую модель дернуть и какой метод из контроллера. Соответственно, выбор пользователя тоже нужно проверить.
0
Какой дернуть метод — это уровень роутера.
Какую модель — мм, не могу придумать случая, который не сводится к передаче поля запроса в фабрику. Если вдруг что-то будет зависеть от наличия поля — мм, окей, это будет if ($request->has('foo')), куда тут всунуть оператор ??, все равно непонятно.
Какую модель — мм, не могу придумать случая, который не сводится к передаче поля запроса в фабрику. Если вдруг что-то будет зависеть от наличия поля — мм, окей, это будет if ($request->has('foo')), куда тут всунуть оператор ??, все равно непонятно.
0
Какой дернуть метод — это уровень роутера.
Я про метод модели.
Если вдруг что-то будет зависеть от наличия поля — мм, окей, это будет if ($request->has('foo')), куда тут всунуть оператор ??, все равно непонятно.
Входящее поле не обязано быть таким простым, это может быть JSON, XML, массив и т.д. Его нужно будет распарсить в контроллере, выяснить нужные детали, а потом может и модель вызывать не придется, какой-нибудь редирект получится. И ваш пример с «has» ничем по сути не отличается от isset, вы ведь говорили именно о том, что не нужно проверять наличие существования полей в контроллере.
0
Я говорил именно про isset, намекая на две плохие практики — непосредственную работу с superglobals и anemic models. Касаемо JSON etc — _иногда_ это действительно надо, когда есть какой-то особый случай и такая необходимость возникает в конкретном методе 1 раз. В общем же случае — это признак «толстого контроллера» и звоночек, говорящий о необходимости декомпозиции: JSON принципиально ничем не отличается от form-urlencoded, и точно так же может преобразовываться в request и подлежать маршрутизации.
0
Я говорил именно про isset, намекая на две плохие практики — непосредственную работу с superglobals и anemic models.
Т.е. вы говорили про три несвязанные вещи, про isset, про superglobals и про anemic model. И почему-то это должно было оказаться аргументом против isset.
В общем же случае — это признак «толстого контроллера» и звоночек, говорящий о необходимости декомпозиции: JSON принципиально ничем не отличается от form-urlencoded, и точно так же может преобразовываться в request и подлежать маршрутизации.
В общем случае, нет никаких звоночков, задача контроллера и есть связь между пользователем (запросом) и моделью (бизнес-логикой). А толстый контроллер — это о прямом изменении модели в контроллере. А у нас речь об обработке сложных входящих пользовательских данных, не связанных с моделью.
Конечно, все может преобразовываться в request, только тогда мы придем к другому антипаттерну GodObject.
0
Частое использование isset в контроллере обычно сочетается с superglobals и anemic models. Вот и всё, что имелось ввиду :)
God Object не получится, если не пихать все в одну кучу. Из request-а может делаться FormRequest, из него Criteria и т.д.
God Object не получится, если не пихать все в одну кучу. Из request-а может делаться FormRequest, из него Criteria и т.д.
0
Частое использование isset в контроллере обычно сочетается с superglobals и anemic models. Вот и всё, что имелось ввиду :)
Наконец-то выяснили, что вы имеете в виду. Писали вы совершенно другое.
Если приходится часто писать isset, это что-то не то с архитектурой.
Не все задачи есть сайты. Не все придерживаются MVC. Не каждое MVC такое, как у вас. Любые внешние данные это потенциальный isset. А также,
God Object не получится, если не пихать все в одну кучу. Из request-а может делаться FormRequest, из него Criteria и т.д.
Ага, а кто должен эти объекты производить?
0
это уровень роутера
Есть даже такой уровень? Мне казалось это все уровень фронт-контроллера.
0
Фронт-контроллер — это понятие довольно абстрактное. Много что туда относят: единая точка входа, подключение composer autoloader, инициализация DI, сборка реквеста, подключение какой-нибудь дебаг-консоли в отладочном режиме… Я предпочитаю не использовать этот термин вообще, он слишком широк.
0
ну как, подключение composer autoload я лично считаю процессом бутстрапинга, и это еще не фронт контроллер. Фронт контроллер в моем понимании это вот такой вот простой интерфейс (будем уже писать в терминах PHP7):
а уж что там внутри особо разницы не имеет, маршрутизаторы ли там, иссеты и ифы со свитчами…
interface Controller {
public function handle(Request $request): Response;
}
а уж что там внутри особо разницы не имеет, маршрутизаторы ли там, иссеты и ифы со свитчами…
0
Есть уже гид как старые extensions переписывать чтобы в PHP7 работало? Типа XSLCache того же.
+1
Со всем согласен, но BaseException — это какой-то отвратительный костыль
0
Вынужденный. Слишком уж много людей ленятся наследоваться от \Exception и отлавливать именно свои исключения :(
+3
Можно было бы отнаследоваться от ErrorException. Его в 99% случаев используют по делу.
А код, смешивающий «свои» обработчики исключений с «олдскульной» обработкой engine errors, все равно ж сломается, не?
А код, смешивающий «свои» обработчики исключений с «олдскульной» обработкой engine errors, все равно ж сломается, не?
0
ErrorException extends Exception {
Документация
Тут скорее полезно именно добавление абстрактного
\BaseException
, после которого уже не будет возникать подобных случаевBaseException (abstract)
+- EngineException
+- ParseException
+- Exception
+- ErrorException
+- RuntimeException
+- ...
+- ...
0
А как введение еще одного базового класса поможет остаться работоспособным коду вида
$f = fopen(...);
if (!$f) {
$error = error_get_last();
// handle error…
}
?
Никак же, улетит исключение еще из fopen.
Другое дело, что, наверное, с этой точки зрения необработанное исключение лучше, чем catch чего-то «не того». Но кода, обрабатывающего php-ошибки «по-старинке», не заворачивающего их через set_error_handler, и при этом в принципе использующего исключения, я вообще не встречал на практике. Так что тут лечится какой-то невообразимый сферический говнокод в вакууме, а нормально написанный код, обрабатывающий ErrorException, придется переписывать.
$f = fopen(...);
if (!$f) {
$error = error_get_last();
// handle error…
}
?
Никак же, улетит исключение еще из fopen.
Другое дело, что, наверное, с этой точки зрения необработанное исключение лучше, чем catch чего-то «не того». Но кода, обрабатывающего php-ошибки «по-старинке», не заворачивающего их через set_error_handler, и при этом в принципе использующего исключения, я вообще не встречал на практике. Так что тут лечится какой-то невообразимый сферический говнокод в вакууме, а нормально написанный код, обрабатывающий ErrorException, придется переписывать.
0
Да, php был и остается живее всех живых, если еще после выхода PHP 7 проекты с веток 5.4 — 5.6 удастся почти безболезненно и быстро перевести, то цены не будет. В случае с python конечно грустно получилось, люди так до конца все и не перешли на 3 версию из за медленного перехода пакетов и библиотек.
+2
Посмотрите на коммент ниже от Arilas…
У PHP нет будущего. Принятие рфц, в основном базируется на совместимости, и не способно, исправить архитектурные провалы языка. Дело становится совсем худо, если посмотреть с каким трудом принимаются необходимые для развития языка рфц. Для того чтоб принялись рфц, авторам приходится их извращать до неузнаваемости, а после внедрения подобных фич, приходишь ко мнению, что лучшеб вообще не делали.
В общем, не вырастит этот язык до энтерпрайза, особенно с нынешними конкурентами. Нет, нет, писать большие проекты можно, но это как в м$ пейнте рисовать анимацию.
У PHP нет будущего. Принятие рфц, в основном базируется на совместимости, и не способно, исправить архитектурные провалы языка. Дело становится совсем худо, если посмотреть с каким трудом принимаются необходимые для развития языка рфц. Для того чтоб принялись рфц, авторам приходится их извращать до неузнаваемости, а после внедрения подобных фич, приходишь ко мнению, что лучшеб вообще не делали.
В общем, не вырастит этот язык до энтерпрайза, особенно с нынешними конкурентами. Нет, нет, писать большие проекты можно, но это как в м$ пейнте рисовать анимацию.
-6
Да бросьте. Да у php есть свои недостатки в тех же стандартах, именование функций, но все это постепенно исправляется и улучшается от версии к версии. Свои задачи он прекрасно решает, а это низкий порок вхождения в язык, дешевизна разработки для бизнеса, просто огромное комьюнити которым не каждый язык может похвалиться. Да бывает что встречается плохой код, но это не от языка зависит, а от того, кто на нем пишет.
+1
<irony> Простите был не прав, рфц принимаются на ура и не доводят контрибютеров до желания уйти! Реализация примесей — безупречна. А ооп, джависты обзавидуются! А скорость, еслиб не си, всё писали бы на php!!! синтаксис — эталон, который стоит в университетах подавать как учебный материал. </irony>
С точки зрения бизнеса у php есть право на жизнь, пока… Но сегодня написать «hello world» на play2, проще чем на symfony2. И не надо говорить про порок вхождения, я не о домашних сайтах на коленке.
С точки зрения бизнеса у php есть право на жизнь, пока… Но сегодня написать «hello world» на play2, проще чем на symfony2. И не надо говорить про порок вхождения, я не о домашних сайтах на коленке.
-3
Я уже даже доклад про «особенности» PHP 7 делал, очень много кривых и недоделанных возможностей:
1. Нет nullable, если что-то может вернуть null, тип указать нельзя (привет find по id)
2. declare(strict_types=1); — вот этот вот костыль просто говорит, что входить может int, выйдет string (оно если что отконвертирует), без него Type Hints — это конвертеры типов (написано string, передает объект, оно дергает __toString()).
Несколько примеров, и комменты снизу кода:
Как вам parent?
Нет переопределения return'а, в других языках есть
А почему бы и нет?
Тоже нормально
А тут ошибка, ceil возвращает float (хотя строку в предыдущем примере отконвертировало)
1. Нет nullable, если что-то может вернуть null, тип указать нельзя (привет find по id)
2. declare(strict_types=1); — вот этот вот костыль просто говорит, что входить может int, выйдет string (оно если что отконвертирует), без него Type Hints — это конвертеры типов (написано string, передает объект, оно дергает __toString()).
Несколько примеров, и комменты снизу кода:
class Foo {
public static function test() : self {
return new Foo;
}
}
class Bar extends Foo {
public static function test() : parent {
return new Bar;
}
public function action() : int {
return 5;
}
}
Как вам parent?
namespace Bar;
interface Foo {}
interface FooManager {
public function bind():Foo;
}
class FooImpl implements Foo {}
class FooManagerImpl implements FooManager {
public function bind():FooImpl {
return new FooImpl();
}
}
//Fatal error: Declaration of Bar\FooManagerImpl::bind() must be compatible with Bar\FooManager::bind(): Bar\Foo in *** on line 14
Нет переопределения return'а, в других языках есть
function foo(string $a):bool {
return $a + 1;
}
var_dump(foo(5));//bool(true)
А почему бы и нет?
declare(strict_types=1);
function foo($a):float {
return $a + 1;
}
var_dump(foo("asdf5"));//float(1)
Тоже нормально
declare(strict_types=1);
function foobar(float $abc): int {
return ceil($abc + 1);
}
foobar(123.0);
А тут ошибка, ceil возвращает float (хотя строку в предыдущем примере отконвертировало)
+2
В любом языке можно найти способ выстрелить себе в ногу
0
strict_types — это вынужденный костыль для BC. Отсутствие nullable return types — да, серьезный косяк. С parent странно, конечно; видимо, из-за проблем с производительностью не проверяется цепочка наследования; хотя я бы тут использовал интерфейс. С floor/ceil/round проблема в том, что на 32-битных системах невозможно в общем случае сконвертировать в int без потерь, полагаю.
0
Ну слушайте, чего вы хотите от альфы-то? Про такие вещи пишите в bugs.php.net, сделаете язык лучше.
0
Это не баги, это то, что вошло в PHP 7 и не будет изменено(новые RFC не принимаются в PHP 7).
1. По поводу Nullable — уже есть RFC, который висит очень давно, и даже не рассматривался (хотя ссылки на него есть в Return Type Hints)
2. По поводу переопределения типа возврата, в изначальном RFC по Return Type Hints это было, и даже изначально его таким приняли, потом вспыло про BC и про перекрестную имплементацию, в итоге убрали.
3. По поводу Scalar Type Hints, изначальный RFC был сделан очень интересно, там даже было оптимизировано выделение памяти для типов (по примеру статического анализатора типов в strict mode у hack)
4. По поводу нового оператора ??, зачем-то изобрели новый костыль, могли бы заюзать то, как это допустим в том же js: var name = obj.name || «Name»
5. По поводу нового оператора сравнения <=>, я не совсем понял зачем он (зачем сравнивать массивы и объекты?) а для чисел получать результат сравнения в виде -1 либо 0 (если равны) либо 1 (если больше) тоже не совсем понятно зачем.
Вообще на PHP 7 я возлагал большие надежды, сейчас смотрю на HACK от HHVM, там есть очень много плюшек и нормальные Type Hint's(даже для массивов, Векторов, Мап, Callable и т.д.). А их статический анализатор — это просто сказка, он находит 90% багов прямо во время сохранения файлов.
1. По поводу Nullable — уже есть RFC, который висит очень давно, и даже не рассматривался (хотя ссылки на него есть в Return Type Hints)
2. По поводу переопределения типа возврата, в изначальном RFC по Return Type Hints это было, и даже изначально его таким приняли, потом вспыло про BC и про перекрестную имплементацию, в итоге убрали.
3. По поводу Scalar Type Hints, изначальный RFC был сделан очень интересно, там даже было оптимизировано выделение памяти для типов (по примеру статического анализатора типов в strict mode у hack)
4. По поводу нового оператора ??, зачем-то изобрели новый костыль, могли бы заюзать то, как это допустим в том же js: var name = obj.name || «Name»
5. По поводу нового оператора сравнения <=>, я не совсем понял зачем он (зачем сравнивать массивы и объекты?) а для чисел получать результат сравнения в виде -1 либо 0 (если равны) либо 1 (если больше) тоже не совсем понятно зачем.
Вообще на PHP 7 я возлагал большие надежды, сейчас смотрю на HACK от HHVM, там есть очень много плюшек и нормальные Type Hint's(даже для массивов, Векторов, Мап, Callable и т.д.). А их статический анализатор — это просто сказка, он находит 90% багов прямо во время сохранения файлов.
+1
4. По поводу нового оператора ??, зачем-то изобрели новый костыль, могли бы заюзать то, как это допустим в том же js: var name = obj.name || «Name»Во-первых, зачем использовать то, как в JS, если это не JS?
Во-вторых, $var || $smth имеет тип возвращаемый тип bool, менять это — ломать обратную совместимость.
В-третьих, «||» в JS и «??» в PHP ни разу не эквивалентны. $obj->name()['abc'] ?? $smth сработает в PHP, но не свалится в JS, если $obj не определён.
+1
$obj->name()['abc'] ?? $smth
Оно разве отловит Exception о том, что мы пытаемся вызвать метод у null? Это Recoverable Exception, но все же в определении ?? не указано, что он Exception'ы отлавливает, если бы он так себя вел, то помойму использовать его вообще нельзя (если нужно наружу выкинуть Exception, то что тогда?)
Проверил:
Вывод:
То-есть он аналогичен js по поведению:
Большинство php разработчиков пишет часто на js, сейчас такая специфика, очень много client-side кода, и разное поведение одного и того же функционала часто приводит к банальным ошибкам (в большом проекте всегда есть коммит, который фиксит strpos с === либо сравнение с -1 вместо false во многих случаях)
Оно разве отловит Exception о том, что мы пытаемся вызвать метод у null? Это Recoverable Exception, но все же в определении ?? не указано, что он Exception'ы отлавливает, если бы он так себя вел, то помойму использовать его вообще нельзя (если нужно наружу выкинуть Exception, то что тогда?)
Проверил:
<?php
$a = $obj->name()['abs'] ?? 'asfd';
var_dump($a);
Вывод:
Fatal error: Call to a member function name() on null in *** on line 2
То-есть он аналогичен js по поведению:
var a = obj.some() || 5
Uncaught ReferenceError: obj is not defined
Большинство php разработчиков пишет часто на js, сейчас такая специфика, очень много client-side кода, и разное поведение одного и того же функционала часто приводит к банальным ошибкам (в большом проекте всегда есть коммит, который фиксит strpos с === либо сравнение с -1 вместо false во многих случаях)
0
Нет nullable
Ну тут да, это проблема. К сожалению в момент накала страстей, когда принимали статический тайп хинтинг, разработчица которая ввела эти RFC просто скипнула, и из всех ее RFC (в числе которых был и нуллабл) сделали по сути только тайп хинтинг для скаляров. Думаю к версии 7.1 сделают.
оно если что отконвертирует
при strict_types=1 оно кинет ошибку, если вы что-то не то куда-то передали.
Как вам parent?
уже обсуждалось как-то. Не сказать что это частый кейс, но да, не приятно. Хотя в вашем примере пусть оно уж лучше Foo возвращает.
0
А почему бы и нет?
А что в этом примере плохого? Вы передали значение, которое нельзя без потери данных привести к флоту. В результате там 0.
А если так:
declare(strict_types=1);
function foo(float $a):float {
return $a + 1;
}
var_dump(foo("asdf5"));
//Fatal error: Argument 1 passed to foo() must be of the type float, string given
или так:
declare(strict_types=1);
function foo(float $a):float {
return $a + 1;
}
var_dump(foo("asdf5"));
//Fatal error: Argument 1 passed to foo() must be of the type float, string given
// к слову раньше там писало про catchable error....
0
Если сравнить strict types с тем же HACK, то он обозначает, что в файле должны быть указаны все типы, для всех входящих/выходящих переменных, в PHP 7 strict_types просто отключает некоторые конвертирования типов (то-есть если указан int, а передается string, он не будет строку в int перегонять).
Я знаю как сделать чтобы код, который я скинул работал, проблема в другом, что все равно RFC очень поверхностные. Что дает strict mode в HACK:
1. Полный статический анализ кода, и типов каждой переменной (в hh_client можно узнать тип каждой переменной, указав номер строки и символа, также можно получить автодополнение в любой редактор для любой части кода)
2. Из-за того, что типы известны, есть экономия памяти, потому что не нужно делать структуру как в PHP для хранения значения
3. Исходя из пункта выше, JIT некоторые части кода после прогрева переводит в нативный код (если помните HPHPc, то он компилил тогда весь проект, здесь, только если может, и может отдельные части)
Что дает strict_types в PHP 7:
1. Дополнительные проверки в runtime для того, чтобы проверить, что переменная действительно нужного типа
2. Нельзя статически анализировать(нет полной картины типов, из-за отсутствия Nullable)
Я знаю как сделать чтобы код, который я скинул работал, проблема в другом, что все равно RFC очень поверхностные. Что дает strict mode в HACK:
1. Полный статический анализ кода, и типов каждой переменной (в hh_client можно узнать тип каждой переменной, указав номер строки и символа, также можно получить автодополнение в любой редактор для любой части кода)
2. Из-за того, что типы известны, есть экономия памяти, потому что не нужно делать структуру как в PHP для хранения значения
3. Исходя из пункта выше, JIT некоторые части кода после прогрева переводит в нативный код (если помните HPHPc, то он компилил тогда весь проект, здесь, только если может, и может отдельные части)
Что дает strict_types в PHP 7:
1. Дополнительные проверки в runtime для того, чтобы проверить, что переменная действительно нужного типа
2. Нельзя статически анализировать(нет полной картины типов, из-за отсутствия Nullable)
0
Исходя из пункта выше, JIT некоторые части кода после прогрева переводит в нативный код
JIT все и всегда переводит в нативный код как бэ, просто со временем оптимизирующий компилятор делает все еще лучше, а профит в производительности достигается за счет того что скаляры не оборачиваются в обертку, то есть за счет анбоксинга. Посмотрите на JS, там вообще все типы динамические и оптимизации носят спекулятивный характер. То есть оптимизатор на основе статистики просто говорит что 99% что там инт, если вдруг чего откатывайся.
В PHP7 нет JIT, а к 8-ой версии в принципе не проблема это сделать. Ну и да, судя по тому что от билда к билду поведение того же тайп хинтинга меняется, можно судить что это еще не стабильная реализация. И да, если вы считаете что-то багом, надо бежать в багтрекер а не пилить RFC.
+1
За все время использования PHP в своих проектах, так и не придумал задачи с использованием генераторов… Пользуется, кто ими и для какой цели?
0
Как альтернатива lock'ам в cron job'ах, из PDOStatement каждый раз выбираем только одну вещь(ей сразу ставим статус, чтобы она не подходила под условия выборки), и если запрос достаточно большой, то это дает профит(несколько cron job одновременно в несколько процессов могут спокойно несколько часов работать, что дает хороший профит).
-1
Ну самая стандартная задача генерировать id внутри транзакции еще какой-то дополнительный.
Lazy evaluation/Stream function типа чтения из файлов и т.д. Ну вообщем-то не сказать, чтоб обширное поле деятельности было, но вполне себе имеет право на жизнь.
Lazy evaluation/Stream function типа чтения из файлов и т.д. Ну вообщем-то не сказать, чтоб обширное поле деятельности было, но вполне себе имеет право на жизнь.
0
Есть хорошая статья на эту тему: Генераторы в действии
+1
Например, если нам нужно перевести массив в вид [userId => user]. Преимущество — не расходуется память на лишнюю переменную.
К тому же, разница на лицо
К тому же, разница на лицо
function users()
{
foreach($users as $user)
yield $user['id'] => $user;
}
function users()
{
$_users = [];
foreach($users as $user)
$_users[$user['id']] = $user;
return $_users;
}
+2
Вы посмотрите языки, где они есть давно, это лучший способ их понят. Мне вспоминается хорошая статья Вани Сагалаева, где он рассказывал как он применил генераторы для конкретной задачи (язык там — «Пайтон», но кажется это не мешает восприятию): softwaremaniacs.org/blog/2010/09/18/ijson
0
Самый распространенный пример использования генераторов — реализация xrange для экономии памяти на больших размерах массивов.
А еще есть такие клевые штуки как корутины.
А еще есть такие клевые штуки как корутины.
0
Самый распространенный пример использования генераторов — реализация xrange для экономии памяти на больших размерах массивов.xrange с лёгкостью заменяется циклом. Это где же это самый распространённый пример?
0
Да как бы все на что-то слегкостью заменяется. Генераторы это ни что иное как сахар для итераторов. В контексте питона удобно, в контексте PHP единственный кейс когда мне пригодились генераторы — корутины.
А ну и еще стрим-парсеры удобно делать.
А ну и еще стрим-парсеры удобно делать.
+1
Ну, короткого синтаксиса (генераторный выражений из «Пайтона») мне в ПХП не хватает, но в основном — годно. Для интереса запилил пайтонячий itertools на генераторах ПХП, получилось вполне съедобно.
0
Как правило это длинные задачи, когда процесс работает больше секунд. Например работа в режиме демона с сокетами, или парсинг, обсчёт большого количества данных, постороение каких нибудь кайнтеров или коэфициентов.
0
Заключение особо порадовало :) PHP — уже велик! (ударение поставьте сами :))
+2
Круто! — уходит функция at(), которую я вечно пишу где-то
function at($array, $index, $default)
{
return isset($array[$index]) ? $array[$index] : $default;
}
...
$name = at($_POST, 'name', '');
// Стало
$name = $_POST['name'] ?? '';
0
Давно уже можно так:
И без всякого ??
<?php
$a = $_POST['a'] ?: 'asdf';
var_dump($a);
И без всякого ??
-2
Надо будет проверить, насколько работает «Элвис». Он в PHP относительно недавно, а т.к. я не профессионал, за этим не слежу.
1) Как я понял, он работает по вычислимости в true, т.е. дока скрывает, что будет, когда такой переменной вообще нет.
2) По той же причине для строки '0', скорее всего, вернёт значение по умолчанию.
1) Как я понял, он работает по вычислимости в true, т.е. дока скрывает, что будет, когда такой переменной вообще нет.
2) По той же причине для строки '0', скорее всего, вернёт значение по умолчанию.
0
$a ?: $b это аналог $a? $a: $b, а $a ?? $b — isset($a)? $a: $b
совершенно разные вещи.
совершенно разные вещи.
0
Sign up to leave a comment.
Чего ждать, когда ждешь ребенка: PHP 7, часть 2