А какие преимущества у тестирования с помощью PhantomJS? Скорость запуска? Отсутствие необходимости ставить X-server на CI-сервере? Я, например, тестирую модули для ExtJS с помощью JsTestDriver, который позволяет тестировать код сразу во всех браузерах, в которых должно работать приложение, но требует X-server и выполняет тесты относительно медленно (если каждый раз регенерировать окружение для тестов). Вы сами какой фреймворк для тестирования используете?
Вот приведём отрывок из того, что в Воронеже, в конце января, сказал на «разборе полётов» глава Роскосмоса Владимир Поповкин: «Там микросхемы, которые были применены, в отличие от тех микросхем, которые раньше применялись на „Фрегате“, — они меньше по типономиналу. Там вместо 200 нанометров где-то 90 нанометров. Но это импортная компонентная база, и, конечно, вот причина, наверное, в этом». Так. Поразительно интересно! Что, существует закон природы, согласно которому переход на следующее поколение микросхем, с меньшими допусками, сам по себе должен сопровождаться снижением их надёжности? Надо же…
Видимо автор не удосужился подумать о том, что чем меньше тех. процесс, тем больше влияние ионизирующей радиации на чип.
Не обязательно, у моего провайдера DNS дико тормозит, и часто пакеты вообще теряются. Поэтому пользуюсь гугловскими. И вообще, всегда можно протестировать скорость DNS с помощью namebench
Я что-то говорил о доверии к сырым данным и что я им доверяю? Мою точку зрения по этому поводу можете почитать в этом комментарии, например. Но в статье речь о PDO, и соответственно я хотел бы видеть в ней использование prepared statements как еще одного рубежа защиты от SQL-инъекций. Не всегда можно с уверенностью сказать, что разработчик, который использует твой код, будет проверять входящие данные.
Я это прекрасно знаю, но в SELECT-запросах prepared statements для условий выборки позволять избежать SQL-инъекций, если в условия подставляются сырые данные от пользователя. Я бы рассматривал именно эту сторону вопроса. Кроме того, существует достаточно узкий круг задач, например обработка больших объемов порциями, где prepared statements дадут и выигрыш в производительности.
А почему вы используете prepared statements только для UPDATE и INSERT запросов? Добавили бы в виде примера SELECT с использованием WHERE и prepared statements для безопасного заполнения условий выборки.
Толсто. Сразу же после аварии пожилые японцы стали записываться добровольцами для ликвидации аварии, чтобы не гробить молодое поколение. А роботы были не в состоянии работать в условиях завалов и густого пара в помещениях АЭС, поэтому их использование свелось к минимуму.
Почитайте Спольски, венгерская нотация должна использоваться не для указания типа переменной, а для указания какого-либо аспекта хранящихся в ней данных.
Безусловно да :) Но поскольку я считаю, что дисциплинировать программиста можно только тогда, когда код максимально строг, и за ошибки бьет по рукам, то хинтинг типов будет одним из способов заставить программистов, использующих мой код, пользоваться встроенными средствами валидации, а не бездумно пихать непроверенные данные в нижележащее ядро фреймворка. Вариация технофашизма, я бы сказал.
Если вы имеете в виду ТОЛЬКО приведение к типу — то использование (int) безусловно нагляднее. Я же говорю о комплексной работе с запросом, раз уж ветка началась с идеи «все входящие параметры — строки, что делать дальше». Продолжим дальше на примере с id, полученным из браузера пользователя вместе с запросом:
use /Project/Validator/ValidatorI as V,
/Project/Validator/Exceptions/ValidatorException;
// класс обладает знаниями о том, как выполняется определенное действие,
// запрошенное пользователем, и о том, какие типы и граничные значения
// имеют входящие параметры
class SomeActionController
{
protected function validate_query(array $params)
{
try
{
// $params['id'] передается по ссылке
// и после валидации имеет заданный тип
$this->validator->validate($params['id'], V::INT|V::UNSIGNED|V::NOT_NULL);
}
catch (ValidatorException $e)
{
// обработка ошибки
}
$this->some_method($params['id']);
}
}
В этом примере я пытаюсь показать, что если вы работаете в рамках фреймворка / CMS, то есть следующие особенности архитектуры:
1. Встроенный механизм комплексной проверки значений, с возможностью приведения к типу
2. Проверка значения и, соответственно, его типа происходит в одной точке и если проверка провалилась, то код сообщает об ошибке и прерывает исполнение. Далее используется уже проверенное и приведенное к типу значение, а не сырое значение из запроса
3. В модуле, который использует данные, имеются необходимые для проверки типа / границ допустимых значений знания
4. Переменная меняет свой тип в результате изменения логики работы модуля, а не наоборот
5. Соответственно, указание типа в сигнатуре должно применяться именно в тех случаях, когда от него зависит работоспособность кода, что хорошо демонстрирует пример с id, который всегда имеет тип integer, не может быть отрицательным, и обычно больше нуля
$query->get('id', 'int') лучше, чем (int)$_POST['id']. Если вы не хотите везде указывать тип, то можно реализовать метод set_type($key, $type), который будет приводить значение ключа к типу и хранить его с этим типом в объекте запроса в дальнейшем. Тогда приведение нужно будет сделать только один раз, а если это не было сделано, то об этом подскажут сообщения о несоответствии типов.
imenem@localhost:~
$ test
PHP Strict standards: Only variables should be passed by reference in /var/www/bank-soft.local/www/test.php on line 21
PHP Stack trace:
PHP 1. {main}() /var/www/bank-soft.local/www/test.php:0
Strict standards: Only variables should be passed by reference in /var/www/bank-soft.local/www/test.php on line 21
Call Stack:
0.0001 634352 1. {main}() /var/www/bank-soft.local/www/test.php:0
first
class MyClass
{
public function __construct()
{
$query = $this->registry
->get_service('InputQueryBuilder')
->get_query_object();
$this->some_method($query->get('id', 'int')); // первый параметр - ключ, второй - ожидаемый тип
}
protected function some_method(int $id)
{
// тело метода
}
}
Используйте инкапсуляцию запроса в объекте и будет вам счастье.
Инкапсуляция говорит, что максимум знаний о том, как происходит обработка данных объекта класса должно находиться внутри самого объекта. Теперь представим себе следующую ситуацию: вам потребовалось изменить алгоритм взаимодействия с данными поля класса, например добавить проверку или конвертацию. Ваш класс является частью фреймворка, на котором написано уже несколько десятков проектов другими разработчиками. Если вы предоставили для доступа к данным защищенный метод, то никаких проблем нет, вы можете изменить его. А если вы предоставили защищенное свойство, то единственное что вы можете сделать — переопределять магический метод __set() с изменением имени свойства. Таким образом замена защищенных свойств на пару приватное свойство + защищенный метод (если нет необходимости выносить метод в интерфейс) увеличивает степнь инкапсуляции, что, в свою очередь, делает проект более расширяемым, так как при изменении внутренних особенностей работы с данными нет необходимости оповещать всех клиентов класса о нем.
Видимо автор не удосужился подумать о том, что чем меньше тех. процесс, тем больше влияние ионизирующей радиации на чип.
В этом примере я пытаюсь показать, что если вы работаете в рамках фреймворка / CMS, то есть следующие особенности архитектуры:
1. Встроенный механизм комплексной проверки значений, с возможностью приведения к типу
2. Проверка значения и, соответственно, его типа происходит в одной точке и если проверка провалилась, то код сообщает об ошибке и прерывает исполнение. Далее используется уже проверенное и приведенное к типу значение, а не сырое значение из запроса
3. В модуле, который использует данные, имеются необходимые для проверки типа / границ допустимых значений знания
4. Переменная меняет свой тип в результате изменения логики работы модуля, а не наоборот
5. Соответственно, указание типа в сигнатуре должно применяться именно в тех случаях, когда от него зависит работоспособность кода, что хорошо демонстрирует пример с id, который всегда имеет тип integer, не может быть отрицательным, и обычно больше нуля
Но вы можете получить первый элемент массива так:
Используйте инкапсуляцию запроса в объекте и будет вам счастье.
А если в POST будет не form-urlencoded, а multipart/form-data, что тогда?