• Дает ли строгая типизация в PHP 7 прирост производительности?

    Начал писать ответ комментарий https://toster.ru/answer?answer_id=937197, но ответ получился большим и поэтому решил поместить его отдельно.

    DevMan , я попробую уточнить ваше утверждение, что немного снижает.
    На самом деле, при использовании скалярных тайпхинтов снижается производительность вызова функций, поскольку возникает некий дополнительный оверхед на валидацию аргументов и приведение значений к нужным типам (если не используется strict_types). Но! Так как внутри функции значения аргументов уже приведены к нужным типам, то при использовании аргументов не происходит неявного приведения типа.
    Поясню на синтетическом примере:
    function foo($x) {
        $result = 0;
        for ($i = 0; $i < 100; $i++) {
            $result += $i + $x;
        }
        return $result;
    }


    Если вызвать эту функцию так: "foo('123')", то в таком случае внутри цикла аргумент будет неявно приводится к целому числу 100 раз. Если вызвать функцию так: "foo(123)", то в таком случае аргумент не будет внутри цикла приводится к целому числу. Очевидно, что второй вариант более производительный:
    ~$ time php70 -r 'function foo($x) { $result = 0; for ($i = 0; $i < 10000000; $i++) { $result += $i + $x; } } foo("123");'
    
    real    0m0.860s
    user    0m0.855s
    sys     0m0.005s

    ~$ time php70 -r 'function foo($x) { $result = 0; for ($i = 0; $i < 10000000; $i++) { $result += $i + $x; } } foo(123);'
    
    real    0m0.508s
    user    0m0.500s
    sys     0m0.008s


    В то же самое время, если добавить к аргументу скалярный тайпхинт, то тогда значение аргумента один раз будет приведено к тайпхинту и внутри функции уйдёт весь оверхед связанный с неявным приведением типа:
    ~$ time php70 -r 'function foo(int $x) { $result = 0; for ($i = 0; $i < 10000000; $i++) { $result += $i + $x; } } foo("123");'
    
    real    0m0.502s
    user    0m0.498s
    sys     0m0.003s

    ~$ time php70 -r 'function foo(int $x) { $result = 0; for ($i = 0; $i < 10000000; $i++) { $result += $i + $x; } } foo(123);'
    
    real    0m0.504s
    user    0m0.495s
    sys     0m0.008s


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

    Зато использование строгой типизации не даст запустить функцию в неконтроллируемом состоянии: когда функция ожидает на вход целое число, а по какой-то причине подсунули массив:
    $var = $_GET['foo'];
    bar($var);
    , для get-параметра foo=123 вызов будет корректным, а для foo[]=123 вызов функции приведёт к TypeError; для foo=abc тоже будет TypeError. Разумеется, этот пример сильно надуман и тут нужно использовать "нормальный" валидатор.
    Ответ написан
    1 комментарий
  • Как останавливать выполнение php при обрыве запроса?

    Есть функция в php: ignore_user_abort(): php.net/manual/function.ignore-user-abort.php
    И соответствующая ей опция в php.ini

    Должно помочь.

    UPD.
    Раздел в документации по php: php.net/manual/features.connection-handling.php
    Ответ написан
    Комментировать
  • Почему из php не выполняется sql запрос из php?

    В mysqli_query нельзя засовывать несколько запросов. Если это сделать, то выполнится только первый, в вашем случае - "set @today:=date('2016-12-11')"
    Если нужно выполнить несколько запросов, то тогда
    * либо разбейте их на отдельные запросы и каждый по-отдельности засовывайте в mysqli_query
    * либо используйте mysqli_multi_query
    Ответ написан
    5 комментариев
  • Есть ли хороший онлайн сервис для обфускации PHP-кода?

    Код сам по себе никому не нужен если это специализированное решение для конкретного проекта.
    И, по большей части ценность представляет не сам код, а тот кто его написал и данные, которыми этот код оперирует. Да монетизация делается другими способами нежели продажей (перепродажей) кода. Посмотрите: Bitrix распространяется открытым исходником, что не мешает 1С зарабатывать на нём.

    Выше сказанное — личное имхо.
    Ответ написан
    Комментировать
  • Как изменить json в вид array?

    Это:
    $nprice = json_encode(array_pop($stmt->fetchAll(PDO::FETCH_OBJ)), JSON_NUMERIC_CHECK);
    выброси и замени на
    $pricesPerMonth = array_pop($stmt->fetchAll(PDO::FETCH_OBJ));
    Ответ написан
    5 комментариев
  • Стретила такую конструкцию, что означает?

    В старых версиях PHP нельзя было делать так: (new static())->getData();. Поэтому каждый выкручивался как мог. В Ларавеле, например, сделали функцию "with", чтобы можно было в старых версиях писать так: with(new static())->getData();
    Ответ написан
    Комментировать
  • Как оптимизировать выборку строк из базы данных?

    2500 тысячи строк в месяц --- это мелочь. MySQL без проблем переваривает таблицы на несколько миллионов строк.
    Ответ написан
    Комментировать
  • Использование PHP PDO предотвращает SQL injection?

    PDO само по себе --- нет. Защищают подготовленные выражения.
    Ответ написан
    4 комментария
  • PHP функциональный язык или объектно-ориентированный?

    PHP — какой угодно язык, но точно не функциональный.

    З.Ы.
    Жаль, что тут нельзя писать в какой именно конторе такое спросили.

    UPD
    Может в вопросе имелось ввиду не "функциональный", а "процедурный"? Вы не поверите как много людей путают процедурные и функциональные языки.
    Если так, то PHP — и тот и другой. Точнее говоря, думаю, что правильный ответ в вашем случае был бы, что PHP — мультипарадигменный язык.
    Ответ написан
    Комментировать
  • Как добавить в массив несколько значений при использовании тернарного оператора?

    $arr = array_merge(
      [
        'key1',
        'key2',
        'key3',
      ],
      true ? ['key10', 'key55', 'key88'] : ['key11']
    );
    Ответ написан
    Комментировать
  • Чем дебажить утечки памяти в php?

    Да простят меня модераторы, но когда-то мне помог этот ответ: stackoverflow.com/a/36288686
    Ответ написан
    Комментировать
  • Почему php-fpm грузит цп опд 100%?

    1. Если есть opcache, то xcache, в общем-то, не нужен.
    2. У вас есть /var/log/php-fpm.log.slow --- там можно увидеть какие запросы являются медленными. Возьмите топ-5 самых медленных запросов и профилируйте код, чтобы увидеть что именно там тормозит. Воспользуйтесь функцией php.net/manual/function.getrusage.php --- она покажет использование ресурсов процессом. Это дело можно логировать и строить графики. Таким образом найдёте того "гадёныша", который грузит процессор.

    UPD.
    Без профилирования и детальных логов невозможно сказать где именно находится проблема.
    Ответ написан
    1 комментарий
  • Создание объекта внутри другого класса?

    Потому что до версии 7.0 у PHP был весьма убогий парсер, основанный на алгоритме LALR. Но без AST, он накладывает существенные ограничения на возможности разбора и последующей компиляции.
    В 7.0 запилили AST, которое открывает более широкие возможности, связанные с парсом и анализом программы, но до вышеописанной конструкции они не дошли, т.е. получающиеся узлы в AST никак не анализируются, но, потенциально, возможность использования неконстантных выражений в объявлении полей класса сейчас есть.
    Можете написать разработчикам в рассылку "php internals" с просьбой реализовать. Может быть кто-то поможет. А может и нет.

    UPD.
    Вот, RFC от Никиты Попова (один из разработчиков ядра PHP), объясняющий необходимость реализации AST: https://wiki.php.net/rfc/abstract_syntax_tree
    И веб-интерфейс рассылки "php internals": externals.io

    UPD2.
    Я не слишком силён в ядре и в runtime'е PHP, поэтому не смогу дать вам полный ответ на ваш вопрос. Лучше всего если вы спросите у непосредственно разработчиков в этой рассылке.
    Ответ написан
    Комментировать
  • Возникает ошибка Syntax error, unexpected T_WHILE, expecting ',' or ';'. Как синтаксически правильно написать код?

    Вот так должно быть:
    echo "<td><select>"; while ($row = mysql_fetch_assoc($subs)) { echo "<option value='".$row['user']."'>".$row['user']."</option>"; } echo "</select></td>";


    Вы пропустили "точку с запятой" после первого "echo", не поставили "echo" внутри цикла, не поставили "точку с запятой" после "</option>"; не поставили "echo" перед "</select&gt.

    Вы очень невнимательны.
    И ещё, перестаньте пользоваться функциями mysql_
    Ответ написан
    Комментировать
  • Почему не работает pdo?

    Ходить в базу под пользователем "root" не секурно. Вы уверены, что пароль от пользователя "root" - 111111
    Ответ написан
    Комментировать
  • Как перенаправить Notice в текстовый файл?

    error_reporting(-1);
    ini_set('display_errors', 'Off');
    error_log('...');
    Ответ написан
    Комментировать
  • Что не так в этом коде?

    Хм.. что в этом коде "не так"? Короткий ответ: в этом коде всё не так.
    Если по-длиннее, то:
    1. Микс из mysqli_ и mysql_ функций - они друг к другу отношения не имеют и вместе не работают.
    2. Не закрыта кавычка в mysqli_connect у второго аргумента.
    3. Вы ходите в базу под пользователем root
    4. В require используется относительный путь.
    5. У mysqli_select_db перепутаны аргументы.
    6. Не делаете mysqli_set_charset.
    7. Закрыт PHP-тег ("?>")
    8. Не понимаете как работает оператор "or"
    9. Используете подавление ошибок.
    10. Используете die вместо логирования и обработки ошибок.
    11. die - хреновый способ обработки ошибок, но хоть какой-то. А вы его удаляете при выкладке в продакшн.
    12. А что если в продакшене не получится подключиться к mysql, то как ваш код обработает и отреагирует на эту ситуацию?

    А теперь подробнее об операторе "or". В отличии от Perl этот оператор возвращает не один из своих аргументов, а всегда возвращает либо true либо false.
    Таким образом, выражение @$_REQUEST['user_name'] or die("YOU BRAIN ERROR") работает следующим образом: если @$_REQUEST['user_name'] содержит значение эквивалентное булевому значению истинности, то всё выражение вернёт true, иначе будет вычислен правый операнд: die(...), т.е. будет вызвана "функция" die и скрипт аварийно завершится.
    Ключевой момент: оператор "or" не возвращает значение одного из своих операндов. Он всегда возвращает либо true, либо false.
    Таким образом, если в запросе присутствует параметр "user_name", и он содержит значение эквивалентное булевому значению истинности, (т.е. непустое значение), то оператор "or" вернёт true. Далее, т.к. функция mysql_real_escape_string должна принять на вход строку, то возвращённое оператором значение true будет неявным образом приведено к строке. В результате приведения true к строке получится строка "1". Не число 1, а строка "1". Которая и будет скормлена в mysql_real_escape_string, который эту строку заэкранирует и в переменную $user_name ляжет значение "1".
    То же самое происходит и с "age".

    Надеюсь, я достаточно подробно разжевал.
    Ответ написан
    Комментировать
  • Почему обрезаются urlencoded данные передаваемые в post?

    Расширение suhosin стоит на сервере? (это для начала).
    Бывает ограничение на размер тела запроса. Оно бывает как у веб-сервера, так и у PHP.
    Ответ написан
    Комментировать
  • Как сделать сложение массива?

    1. Инлайновые комментарии начинаются с"//", а не "#". Комментарии, начинающиеся с "решётки" - анахронизм и его почти нигде не используют.
    2. Ваши имена переменных ужасны: где-то нормальные английские слова, где-то --- транслит.
    3. Вы сформулировали задачу на удивление непонятно. 3 раза перечитал и толком не понял что вам нужно.
    4. Если уж собираете запрос через конкатенацию, то надо хотя бы использовать экранирование. Откройте для себя метод real_escape_string. А иначе, привет sql-инъекции.

    Если я правильно понял то, что вам нужно, то..
    $sql = $mysqli->query("SELECT * FROM rich_ninja WHERE nick = '".$usdat['nick']."' AND ninja_type='n1'");
    $totalSum = 0;
    while (null !== $nj1 = $sql->fetch_array()) {
        $totalSum += SumCalc($nj1['percent'], $nj1['price'], $nj1['sbor']);
    }
    $sql->free();
    Ответ написан