65536 > а за is_numeric(strpos( предусматривается казнь?
Почему же?))
При получении из Request объекта и базовой валидации через is_numeric - это вполне ок, просто далее идет обязательный каст в float/int, которые уже будут браздить просторы. Правда для int > 0 лучше использовать ctype_digit.
sim3x > если в пхп-иде есть возможность проверить кодстайл автоматом, то лучше поставить пункт с проверкой кодстайла вначале - так быстрее можно будет вернуть код на доработку ватору
Так обычно и делается.
Arris > А чем кошерно заменять while ($row = ... ) ?
$row = ...;
while(!is_null($row)) {
...
$row = ...;
}
> даже если я гарантированно знаю, что сравниваю два integer'а - все равно писать $i === $j ?
Верно. Работая в команде вы можете поручиться только за себя. Другой программист будет решать свою задачу и может накосячить, просто забыв, что у него есть несоответствие типов.
Цена этого запрета на порядки ниже профита, который он дает.
> и совсем отказаться от контролируемого приведения типов?
не путайте мягкое и соленое. Привидение типов - это ок, только оно обязательно должно быть ЯВНЫМ.
> а если операнды заведомо однотипны?
В этом случае тоже пишем ===, или !==. Еще раз, цена этого запрета очень низкая, по сравнению с профитом. Код не пишется один раз и на всегда, он рефакторится и расширяется, зачем прописывать кучу преобразований и проверок, если достаточно делать неявное приведение типов? Так и будет написано. Потом добавится еще тип, и в один прекрасный момент у вас в одном условии могут быть int, float и string. Да, оно как-то будет работать, но опять же - это говнокод.
65536 Вы все верно поняли. Не типизированные проверки запрещены. in_array и тому подобные методы тоже с обязательной проверкой типа. Например strpos($a, $b) может вернуть как 0, так и false, что значит принципиально разные вещи: подстрока начинается с нулевого символа, или подстрока не найдена вовсе соответственно.
jacksparrow Для крупных проектов характерно использование одних и тех же моделей в разных контекстах. Как следствие - ваша модель спокойно за весь процесс выполнения может гулять по всему проекту - это нормально. Но проблема AR в том, что помимо данных по всему проекту гуляет еще и подключение к БД. Как следствие - непосредственно работа с одной, или несколькими таблицами может происходить вообще где угодно. По сути это размазывает работу с БД (не с моделью, как объектом данных) по всему проекту.
Паттерн Repository явно разделяет:
- Entity (иногда называют моделью) - это объект данных, все что он умеет - это содержать в себе данные и бросать исключения, если вы туда каку запихиваете.
- Repository - объект для работы с БД и Entity.
Entity может абсолютно спокойно гулять по всему проекту, это просто обертка над данными, не более того. Но вот работа с БД у вас сконцентрирована в одном месте - Repository.
Как полезная фича - репозиторий может работать по интерфейсу, тогда Entity можно создавать разные под каждый конкретный случай бизнес логики вашего проекта. Это вносит серьезную гибкость.
Для тестирования компонент, работающих с Repository все, что нужно сделать - это замокать Repository и проверять, что в него влетает правильное Entity.
В случае с AR - это на порядки сложнее потому, что нужно проверять не только объект данных, но и работу с БД для каждого случая (можно конечно мокать драйвер БД, но попробовав это сделать вы поймете, что где-то свернули не туда). Для AR тестировать создание и запись модельки в внешней компоненте - тоже весело, вам придется в этой самой компоненте делать кучу вспомогательных методов, а потом их же мокать, что тоже хреновенькая практика.
Если AR модель реально "толстая" (содержит в себе бизнес логику) - будьте готовы к тому, что она рано, или поздно станет "божественным" объектом, умеющим во все. Это плохо потому, что малейшее ее изменение может привести к не предсказуемым последствиям.
В случае Repository проблем будет на порядки меньше потому, что репозиторий работает ТОЛЬКО с БД и Entity, он не содержит в себе бизнес логики, вообще.
----
Я не спорю, AR для маленьких проектов с простенькими CRUD-ами вполне норм, но опять же, с ростом проекта - проблемы будут расти экспоненциально.
Под БД берите MySQL и не парьтесь.
Под ферймворк - смотрите Silex, либо таки лучше Symfony. У первого порог вхождения маленький, второй - на порядки мощнее, но и порог вхождения повыше.
это я понял, собственно разница во времени загрузки как раз потому и происходит, что вы картинку подгружаете в момент наведения, а не до того. css - это один из вариантов решить проблему, учитывая, что вы показали меню - там динамика расчетов картинок никому не нужна.
На контакт человек все равно не идет, какая разница?)) В случае работы с ним велика вероятность, что он будет поступать так же. Если оно вам надо - не отклоняйте.
'Missing PHPDoc comment': Severity: Error
[ ] Constant
[x] Function [x] Skip if empty
[ ] Class
[x] Method [x] Skip if empty
[x] Field
[ ] Class constant
Рекомендую юзать такую штуку: https://github.com/ko-ko-ko/php-assert во всех методах, принимающих аргументы.
Используется примерно так:
/**
* @param int $length
*/
public function checkLength($length)
{
. Assert::assert($length, 'length')->int()->positive();
Читается это следующим образом:
Утверждаю(переменная_length, называемая_length)->целое_число()->больше_нуля();
Если что либо из этих утверждений не сработает - будет исключение.
Смысл в том, что львиную долю проблем безопасности решите + с таким кодом на порядки проще работать. Вы всегда будете знать что принимает функция на вход, а в случае исключения - знать место вокруг этой функции, которое выполнилось не правильно.
> 1) что подразумевается под проверкой? где влететь может что угодно...
(new Model)->get(new \stdClass, new Exception("I could not work here"))
> 2) фигурные скобки - это WHERE code={$user_code}?
Нет, я имел ввиду вот это:
if ($this->code != '') {
return true;
}
А вот такое писать вообще нельзя: WHERE code={$user_code} от слова СОВСЕМ! Используйте плейсхолдеры PDO.
> 3) отправка почты... это что-то вроде вызов статичного метода в классе Mail? MAIL::mail() условно?
Если у вас толстые модели - условно да, но лучше все же отправку почты выполнять во вне логики модели, ее задача - содержать в себе данные + связь с БД (в случае AR). В случае репозитория - моделька - это просто набор геттеров и сеттеров с проверками по типу, в репозитории уже происходит вся кухня.
> 4) про неймспейсы полезное замечание... изучая фреймворки как раз к этому пришел, но! после namespace и use... все равно идет Class Model_asdmin extends Model... в чем соль тогда?...
WAT? Соль в том, что вы не правильно их готовите. Почитайте внимательно PSR-0 и PSR-4, думаю ясности это прибавит. Если от модели могут отпочковываться - вероятно ее имеет смысл сделать абстрактной.
Почему же?))
При получении из Request объекта и базовой валидации через is_numeric - это вполне ок, просто далее идет обязательный каст в float/int, которые уже будут браздить просторы. Правда для int > 0 лучше использовать ctype_digit.
if (strpos('some', 'someString') === false) {
...