Это копия, сохраненная 29 апреля 2015 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
Это тред для начинающих. Не написал за свою жизнь ни одной программы? Ты наш человек.
Устанавливать пока что ничего не требуется, разве что редактор кода вроде Sublime Text 3, Notepad++, Netbeans PHP или PhpStorm (необязательно).
Предыдущий тред был тут: >>449425
Правила: ведем себя воспитанно, помогаем новичкам, постим ссылки на решения задачек, ОП их проверяет и дает советы и замечания. ОП отвечает даже на самые нубские вопросы. ОП заходит где-то раз в день, не жди его, решай задачки дальше.
У нас есть уроки по основам PHP, они собраны и выложены по адресу http://archive-ipq-co.narod.ru/ Это учебник для изучающих с нуля, то есть если ты вообще ничего не знаешь, то надо начать с него. Он простой и понятный (по крайней мере в начале). Там есть задачи, их надо решать обязательно (чтобы стать программистом, надо писать код — иначе никак). Пости ссылки на решения в тред, мы их проверим, напишем замечания и дадим советы по улучшению.
Если не знаешь как решать, запости код, напиши в каком месте остановился и попроси подсказку.
Учебник дает основы языка PHP, но чтобы делать сайты, этого недостаточно. Если ты его прошел, то надо переходить в более серьезным задачкам, которые научат тебя как выдавать страницы в браузер, работе с таблицами в БД, работе с формами, MVC.
- Простая, но полезная задача сделать список студентов: https://github.com/codedokode/pasta/blob/master/student-list.md
- Более сложная задача сделать файлообменник на микрофреймворке Slim: https://gist.github.com/codedokode/9424217
- Еще более сложная и долгая задача на Yii/Yii2: https://gist.github.com/codedokode/8733007
- После нее можно изучать автоматизированное тестирование
- Если ты все решил, переходи к Symfony 2/Doctrine 2
Чтобы делать эти задания, тебе надо установить Апач + PHP (можно заодно сразу и MySQL) на компьютер. Вот полезные инструкции:
https://gist.github.com/codedokode/10774100
https://gist.github.com/codedokode/7054af4a03865c4cc863
Может тебе понадобится пользоваться командной строкой, вот гайд https://gist.github.com/codedokode/10539568
Вот небольшой туториал по тому как начать использовать PHP на сервере для отдачи странички в браузер: https://php.net/manual/ru/tutorial.php Увы, уроков плавно подводящих к тому, как сделать задачи выше, пока нет, так что если что, задавай вопросы.
Решения задач лучше показать мне, особенно на ООП,так как сам ты вряд ли увидишь все ошибки. Пости свой код на гитхаб и вкидывай ссылку в тред по мере решения. Я прокомментирую и укажу на ошибки.
Также, у нас есть задачи которые позволят тебе изучить или подтянуть до нормального уровня знания JS/HTML/CSS/SQL. Решай их параллельно с задачами выше.
- HTML/CSS: https://gist.github.com/codedokode/58ebc90bd006baf4b35c
- JS: https://gist.github.com/codedokode/ce30e7a036f18f416ae0
- Проверялка решений на JS: http://dkab.github.io/jasmine-tests/
- MySQL: https://gist.github.com/codedokode/10539213
Что почитать
- Мануал по PHP — http://www.php.net/manual/ru/langref.php
- Сайт phptherightway (перевод на русский: http://getjump.github.io/ru-php-the-right-way/ )
- По PHP: Профессиональное программирование на PHP Джордж Шлосснейгл
- По PHP: Мэтт Зандстра — PHP: Объекты, шаблоны, методики программирования
- JS: learn.javascript.ru
- Про Git:
Нужен ли ООП, фреймворки, MVC? — Да, однозначно. Посмотри любую вакансию.
Сайт опять упал!!!!! — Не паникуй, а открой http://rghost.net/45000175
Оформляй код аккуратно!!! — например пропусти через phpformatter.com . Также, если ты пользуешься IDE вроде PhpStorm, Netbeans, Eclipse, то в них эта опция встроена, подробнее: https://gist.github.com/codedokode/8759492
ОП, сделай за меня мою работу или домашнее задание? — Это конечно, хорошая идея, но нет.
Где искать работу и заказы — hh.ru, geekjob.ru, brainstorage.me, fl.ru, odesk.com. Имей в виду, что кроме фриланса есть еще постоянная удаленная работа (remote job) когда тебе не надо тратить время на поиск заказов и переговоры с неадекватными заказчиками.
Если тебе лень выравнивать код руками, закачай его на http://beta.phpformatter.com/ и нажми «format». Робот исправит выравнивание и отступы в мгновение ока (да, прогресс не стоит на месте). Если ты используешь мощную IDE вроде PhpStorm, там тоже есть функция форматирования кода.
Горячие клавиши для форматирования кода в разных IDE: https://gist.github.com/codedokode/8759492
Сам код не надо постить в тред, пости только ссылку на ideone c кодом.
Вообще, в PHP долгое время не было единого стандарта оформления кода, все писали как попало и было много бардака, но сейчас дело лучше — есть стандарты PSR-1 и 2. Вот как надо оформлять код:
- переменные и функции пишутся с маленькой буквы, подчеркивание не используется, используется camelCase, пример: $x, $numberOfPeople, printResults()
- Название функции начинается с глагола, в стиле «сделайЧтоТо»
- не знаешь английский? Не беда, в 21 веке есть решение этой проблемы. Не пиши транслитом, открой лучше Гугл Транслейт или slovari.yandex.ru и найди название для переменной там
- в именах классов используется CamelCase, первая буква большая, «_» может использоваться
- мы предпочитаем подстановку переменных вместо конкатенации строк: "I am $age years old" — хорошо, 'I am ' . $age . ' years old' — плохо из-за обилия точек и кавычек
- мы используем для отступов 4 пробела (можно настроить редактор, чтобы при нажатии Tab он вставлял 4 пробела)
Вот ссылка на стандарты, где все это описано и даны примеры оформления:
PSR-1: https://github.com/php-fig/fig-standards/blob/master/accepted/ru/PSR-1-basic-coding-standard.md
PSR-2: https://github.com/php-fig/fig-standards/blob/master/accepted/ru/PSR-2-coding-style-guide.md
Какой язык лучше начать учить, чтобы стать фрилансером? Я знаю, что для каждой конкретной области применяются разные языки, но наверняка есть что-то общее, что-то с чего можно начать делать деньги
Важно ли вузовское образование? учиться иду на инженера
html + css нужны для любого веба, а это половина всей разработки на сегодня, держи и вперед
https://htmlacademy.ru/
Спасибо, что откликнулся. Я на данный момент владею программированием если то, что я умею можно назвать владением, лел, в общем могу в школьный курс При ежедневных занятиях по 5-6 часов, как скоро получиться извлекать хоть какой-нибудь профит?
Добавлю, проги в школе писали самые простые, что-то уровня решалки квадратных уравнений и простецкие циклы
{ a => [18:31, 'Привет' ], b => [18:32, 'Здаров' ], a => [ 18:33, 'Как дела?' ] }
Есть ли смысл объединить user_a и user_b в users формата { a => '3', b => '7' } где 3 и 7 айдишники? По идее между участниками диалога разницы нет. Какой поиск будет работать быстрее - по двум полям или по одному полю с распарсиванием жсона?
Вообще нормальное ли это решение или муть полная и я в упор не вижу более разумного? Наверное можно хранить все диалоги в той же таблице Users в мегасложном жсон-объекте, но как-то мне это не нравится.
>Есть ли смысл объединить user_a и user_b в users формата { a => '3', b => '7' } где 3 и 7 айдишники?
Или, допустим, не объект, а строку формата '3@7' и дальше експлод по собаке. Или, допустим, вместо a => [18:31, 'Привет' ] хранить a => '18:31@Привет'
Что будет быстрее/надежнее?
> отбивай четырьмя пробелами
Анус себе четырьмя пробелами отбей. Для PHP идеальный вариант - два пробела. Четыре - для JavaScript.
> пробел перед скобкой после if и for
Воткнул тебе ножницы в глаза.
Мой многолетний опыт показал, что JavaScript с двумя пробелами нихуя не читаем. При этом 45 пробела для PHP - избыточно и даже ухудшает читаемость по сравнению с двумя. Алсо, для тех, кто не переносит { на следующую строку в аду есть отдельный котёл.
Bitrix
Я воспользовался твоим советом продампать каждый раз переменную, и опытным путем установил, что действительно та функция обращалась к пустому массиву, это происходило с теми департаментами где не было сотрудников нужного нам типа. Вылечил таким образом: https://github.com/someApprentice/Vector-Com/blob/master/Classes/Direction.php#L59
>>454140
>сделать в базовом классе абстрактный метод getsomething() и переопределять его в потомках
Я думаю, логично спросить - А зачем нужны абстрактные методы, если мы их все равно переопределяем?
Спасибо, ОП.
Я не могу понять, что это за белый отступ справа и что с ним делать. Указывать width 100% для каждого блока? Тогда блоки будут выходить за пределы экрана.
>а сайтах обычно делают середину тянущейся в ширину от и до определенного размера
>У тебя ничего не тянется.
А как же media правило для services? Надо как-то по другому делать?
Везде по разному. Мне удавалось устроиться в своем мухосранске с одним лишь знанием php, но на хорошую работу было бы желательно знать и остальные языки что ты перечислил. Не бойся, они такие уж и сложные. Если не лениться можно быстро выучить их все.
Нет, дело не в паддинге. Причина в том, что я указал 1600px как максимальное разрешение, как оп посоветовал, а у меня экран больше. Получается мне либо нужно изменить максимальную ширину, либо выравнить body по центру, но по бокам будут белые полосы.
А ты выровняй и поставь замени белые полосы, например.
>с одним лишь знанием php
Это была работа для веба, или же связанная с чем-то другим? Значит, в штате был верстальщик, который все это делал?
Да, у меня внизу был див с картинками фиксированной ширины. Короче фиксированная ширина это зло, впредь буду выравнивать все маржинами, да паддингами.
Дизайн так сделан так, что его можно тянуть в стороны до бесконечности, добавляя поля. Дизайн же состоит из изущих вертикально блоков с простым одноцветным фоном и ты можешь эти блоки в стороны тянуть хоть сколько.
Ну например самый верхний блок с меню растягивается добавлением черных полей, шапка серыми полями, дальше светлыми ит.д.
На узком экране у нас есть только середина с небольшими полями с краев.
По мере увеличения ширины середина растягивается, поля остаются те же до определенного предела.
После этого предела середина больше не увеличивается и увеличиваются только поля с краев.
Это все делается без @media.
У тебя на первой и на третьей картинке макет не тянется в ширину, а обрывается белой полосой слева/справа. А надо чтобы тянулся.
Картинки в портфолио находятся по центру. А ты почему-то сделал что они прижаты к левому краю с отступом в 100px. Надо просто центрировать и все.
прочти оппост.
>>454810
Прочти PSR.
>>454797
php/html/css/js/sql
От полгода до года + в офис устроиться проще чем на фрилансе что-то заработать.
>>454806
Какая БД используется?
Напиши запросы которые ты будешь использовать для выборки данных. Так неясно.
>>454810
>>454827
Глупость. Зачем нужен незаметный отступ в 2 пробела если рекомендуемая ширина до 80 символов и у нас будет 2-3 уровня отступов? Или это для быдлокода с 10 уровнями вложенности требуется? Алсо есть PSR.
>>454845
Было бы лучше если бы в департаменты был метод назначения (смены) босса. Сравни:
$dep->setBoss($newBoss);
как логично и просто. Мечта любого программиста. Сравни с твоим:
> $department->dismissLeaders( );
> if (isset($newLeader)) {
>\t\t\t\t$newLeader->setLeader(true);
У тебя надо для смены босса сделать 2 действия на разных объектах вместо одного и из-за if есть шанс что мы уволим старого босса и не назначим нового. Это надежно? надежнее сначала подобрать нового босса и потом увольнять старого, а не наоборот.
прочти оппост.
>>454810
Прочти PSR.
>>454797
php/html/css/js/sql
От полгода до года + в офис устроиться проще чем на фрилансе что-то заработать.
>>454806
Какая БД используется?
Напиши запросы которые ты будешь использовать для выборки данных. Так неясно.
>>454810
>>454827
Глупость. Зачем нужен незаметный отступ в 2 пробела если рекомендуемая ширина до 80 символов и у нас будет 2-3 уровня отступов? Или это для быдлокода с 10 уровнями вложенности требуется? Алсо есть PSR.
>>454845
Было бы лучше если бы в департаменты был метод назначения (смены) босса. Сравни:
$dep->setBoss($newBoss);
как логично и просто. Мечта любого программиста. Сравни с твоим:
> $department->dismissLeaders( );
> if (isset($newLeader)) {
>\t\t\t\t$newLeader->setLeader(true);
У тебя надо для смены босса сделать 2 действия на разных объектах вместо одного и из-за if есть шанс что мы уволим старого босса и не назначим нового. Это надежно? надежнее сначала подобрать нового босса и потом увольнять старого, а не наоборот.
Эти языки несложные и ты их максимум недели за 4-5 осилишь. В оп посте есть хорошие задания по ним.
>>454850
Старайся вообще указывать ширину только там где без этого невоpможно а в остальных пусть стоит auto. Меньше цифр — проще код.
>>454860
> Что за херня?
Как ты наверстал, так браузер и отображает.
>>454892
Это потому что ты зачем-то прописал им абсолютную ширину. Сделай чтобы они занимали не N пикселей а 1/4 родителя.
Можно но в случае с колонками это решается указанием процентной ширины. Вообще всегда колонки делаются процентами а не фиксированной ширины.
Ширина области с контентом должна ограничиваться как я нарисовал выше. То есть тянутся они до определенного предела, а после тянутся уже поля, а колонки остаются неизменными.
Предел можно взять с макета. Давай считать что на макете нарисован как раз переломный момент после которого середина не растягивается, а тянутся только поля.
То есть шире чем на макете колонки (и другие части страницы) быть не должны. Уже — можно, а шире нет.
> Зачем нужен незаметный отступ в 2 пробела если рекомендуемая ширина до 80 символов и у нас будет 2-3 уровня отступов?
Чтобы глазики не разъезжались в разные стороны когда код читаешь. Чем больше отступов влево, тем хуже начинаешь соображать что тут вообще написано. Синтаксис PHP позволяет писать код с 2 пробелами и при этом он не сливается в ебучую лапшу (хотя эстетически PHP очень уродлив). Javascript же не имеет специальных знаков для обозначения переменных и приходится пидорасить 4 пробела, поскольку всё сливается.
> Алсо есть PSR.
Мамку иху в рот ибал.
Ты смотри не на сколько указано в CSS, а сделай скриншот браузера и на скриншоте меряй. Может ты что-то не учел.
Было раньше еще такое расширение к браузеру pixel perfect которое накладывало на страницу прозрачный PNG файл с макетом, но я погуглил, оно то ли не работает сейчас, то ли еще что-то.
>>454913
так как на моем мониторе 80 символов это примерно половина экрана то у меня глаза никуда не разбегаются потому проблемы я не вижу.
> Чем больше отступов влево, тем хуже начинаешь соображать
не надо ставить много отступов
код неправильный. Например почему ты думаешь что document.write выполнится после получения запроса? Он выполнится сразу после отправки.
Почитай про аякс, например на learn.javascript.ru или на http://xmlhttprequest.ru/
Ну и не используй document.write
> так как на моем мониторе 80 символов
Ну вот не надо сказок. 80 символов это пожелание, а смотреть надо в глаза суровой действительности. И не 80, а 72. Если в твоём коде не бывает строк длиннее 80 и вложений больше 3, то вероятно твой код состоит из решения олимпийских задачек.
> не надо ставить много отступов
Отступов надо ставить столько, сколько нужно. Маленький размер отступа удобнее, чем большой, но только в тех языках, где синтаксис позволяет этой хуйне не сливаться. Код на PHP с отступом в 4 и тот же самый код с отступом в 2 - две большие разницы.
Забавный баг: логотип не грузится, потому-что обращается по адресу images/logo.png, а у меня файл логотипа начинается с большой буквы. Если локальный файл запускать то все отображается. Но самая мякотка в том, что я не могу ни в имени файла поставить строчную l ни в css Документе, она автоматически преобразуется в заглавную, даже если скопировать строчную и вставить.
Да, это была веб-контора. И да, там был версталищик.
Набери строчку в блокноте или браузере и скопируй. Ну и вообще конечно было бы лучше переименовать файл чтобы он был с маленькой буквы, но там надо какую-то настройку в гите сначала переключить чтобы он различал регистр букв на WIndows.
А может у тебя просто клавиша Shift заедает?
Я же говорю, я пробовал копировать, но при вставке буква становится заглавной. И файл я каким-то чудом смог переименовать, но от этого гит не стал его видеть.
Хочу, чтоб все запросы проходили через index.php, где вызывается роутер (пик1). При URI = '/' всё ок. При попытке зайти на '/userpage' апач выдаёт ошибку (пик2).
Содержимое .htaccess прилагается (пик3).
В чём может быть проблема?
Сейчас загуглю, посмотрю и скажу.
Неоч.
>Какая БД используется?
mysql вестимо
>Напиши запросы которые ты будешь использовать для выборки данных. Так неясно.
Да самый обычный - пользователь логиниться и хочет почитать историю приватных диалогов, соот-но нужно взять его айди и достать либо вообще все диалоги если он клацает на ссылку My Messages либо конкретный, если дальше он кликает на любого пользователя. Ну как вконтакте же.
Теперь вот что: при переходе на '/userpage' браузер показывает абсолютно пустую страницу. В лог ошибок ничего не приходит (лог рабочий).
Вот код:
https://gist.github.com/uniunicorn/baad94f24dfcb5ddee6b
напиши примеры SQL запросов которые ты будешь выполнять. Ну типа выбрать определенные диалоги для пользвоателя и т д. По этим запросам будет видно как удобнее хранить данные.
К чему ты прикопался?
Новосибирск.
Ну основы пхп знаю, прорешал все задачи из учебника треда в плоть до ООП, сейчас сижу на второй задаче о векторе.
Могу в простые запросы и работу с mysql, html немного и css на уровне первых нескольких уроков с htmlacademy.
В целом я уже давно пытаюсь учиться, но у меня нет четкой системы и я часто делаю перерывы, что меня откатывает назад.
Ну если по тому варианту который я придумал то как-то так.
$id = $_GET['id']; //получаем айди пользователя
$id_receiver = $_GET['id_receiver']; //получаем айди собеседника
SELECT `messages` FROM `dialogs` WHERE `user_a`=$id OR `user_b`=$id_receiver // получаем поле messages, в котором лежит жсон объект, декодируем, показываем
Ну ты и лолка. Если не хочешь учить SQL (что было бы правильно) то зайди в phpMyAdmin посоздавай там базы, импортируй левые екселевские таблицы и смотри какими запросами это делается, дальше подгоняешь под те данные что даны в задаче.
Вот сделал задачку про абитуриентов. Оп или еще кто-нибудь знающий, покритикуйте плз мой быдлокод.
Я примерно такой же (делаю регистрацию студентов), но чет пока боюсь стучаться в компании. Правда, я из ДС.
Интересно, тут требования к джунам такие же или выше?
Ты усложняешь ситуацию добавляя JSON. Зачем? Что тебе мешает нормально данные в таблице хранить?
> Пока надумал вариант с отдельной таблицей типа Dialogs, с полями типа `user_a`, `user_b` и `messages`, в поле меседжес хранить жсон-объект формата
{ a => [18:31, 'Привет' ], b => [18:32, 'Здаров' ], a => [ 18:33, 'Как дела?' ] }
зачем JSON тут? Ты при большой истории диалога будешь вынужден вытаскивать все сообщения.
> Есть ли смысл объединить user_a и user_b в users формата { a => '3', b => '7' } где 3 и 7 айдишники?
В чем смысл?
> По идее между участниками диалога разницы нет. Какой поиск будет работать быстрее - по двум полям или по одному полю с распарсиванием жсона?
Как ты собрался искать «с распарсиванием жсона» ? Каким запросом?
Ну и имей в виду, у той же MySQL есть ограничение на количество транзакций записи в секунду, фактически это сотня или несколько сотен операций. на высоконагруженном сайте ты можешь в это упереться.
> `user_a`=$id OR `user_b`=$id_receiver
не подставляй переменные в запрос, используй плейсхолдеры
Не очкуй, составь резюме и вперед, требования в каждой конторе могут быть очень разными даже на джуна. В ДС рынок труда куда более насыщен чем у меня тут, где раз в месяц появляется вакансия. Начни гонять по собеседованиям, кому-нибудь да подойдешь. Алсо слышал от одного анона, что там есть конторы, которые берут просто всех подряд прямо с улицы на ЗП в 20к, и через пару месяцев отсеивают совсем никудышных. Если бы у меня была возможность, я бы пошел к таким ребятам, за два месяца бы точно что-то впитал там, даже если бы и не оставили.
>Ты усложняешь ситуацию добавляя JSON. Зачем? Что тебе мешает нормально данные в таблице хранить?
Вот честно в упор не вижу как тут по-другом можно все хранить. Предложи как бы ты сделал?
>Ты при большой истории диалога будешь вынужден вытаскивать все сообщения.
Ну ВК же их и хранит и вытаскивает.
> Вот честно в упор не вижу как тут по-другом можно все хранить.
Это значит что ты совсем плохо знаешь MySQL
from | to | time | msg
1 | 2 | 12:00:00 | Hello
2 | 1 | 12:01:00 | Goodbye
тут конечно появляется вопрос, как сделать индексы для эффективной выборки? Никак. Потому ради эффективности можно
1) чуть перестроить схему, чтобы в диалоге from и to имели одинаковые значения:
from | to | type | msg
1 | 2 | incoming | Hello
1 | 2 | outgoing | Goodbye
2) дублировать каждое сообщение 2 раза — во «входящих» у получателя и в «исходящих» у отправителя. это позволит им независимо чистить историю.
Если ты этого не знал то тебе стоит начать с изучения SQL, у нас есть неплохие задачки и сссылки на туториалы.
> Ну ВК же их и хранит и вытаскивает.
А разве он все сразу подгружает при большой истории7 Не по частям? ну и ВК конечно их не в SQL базе хранит, с их-то объемами и нагрузкой.
бмп
<form action="zagruzit'_kartinku_na_server.php" method="post">
<input type="file">
<input type="submit">
</form>
[code]
public function checkFields()
{
$charRegExp = "/^[а-яa-zё-]{2,100}$/ui";
$numRegExp = "/^[0-9]+$/";
$mailRegExp = "/@/"; Бля, что это ?
[/code]
мануал читал? https://php.net/manual/ru/features.file-upload.php
Также помни что злоумышленник может попытаться закачать тебе на сервер файл php и выполнить или .htaccess чтобы изменить настройки и тоже что-нибудь выполнить.
>>455073
enctype не забыл?
Забыл.
Нормально я его знаю и по правде твой вариант мне вообще не нравится если я его правильно понял. Хранить все сообщения в такой каше?
1 | 2 | 18:00 | текст //тут вася с петей общаются
1 | 2 | 18:01 | текст ...
1 | 2 | 18:02 | текст ...
3 | 4 | 12:00 | текст //тут другие типосы
1 | 2 | 18:03 | текст //тут опять вася с петей
7 | 9 | 01:54 | текст //тут еще кто-то
Причем вот этих одинаковых 1 | 2 там будут сотни, а самих записей миллионы и перебирать их надо все в поисках айди.
Мой вариант номер 1:
1 | 2 | json ( 1 => "время:текст", 2 => "время:текст") // вася с петей
3 | 4 | json ( 3 => "время:текст", 4 => "время:текст") // другие типосы
7 | 9 | json ( 3 => "время:текст", 4 => "время:текст") // еще кто-то
Других "1 | 2" в нем не будет.
Вариант номер 2:
1@2 | json ( 1 => "время:текст", 2 => "время:текст")
В этом случае запрос будет какой-то такой:
$id = $_GET['id'];
$id_receiver = $_GET['id_receiver'];
$members=$id.@.$id_receiver;
SELECT `messages` FROM `dialogs` WHERE `users`=$members
у тебя в классе Student есть геттеры:
[code]
public function getName()
{
return $this->name;
}
public function getSurname()
{
return $this->surname;
}
public function getGender()
{
return $this->gender;
} [/code]
но нет сеттеров, вместо этого у тебя один метод:
[code] setFields($sentData) [/code]
ты либо запили сеттеры, либо сделай 1 метод
[code] getField($code) [/code]
в методах должна присутствовать симметрия, есть есть гет должен быть и сет
> Причем вот этих одинаковых 1 | 2 там будут сотни, а самих записей миллионы и перебирать их надо все в поисках айди.
Ты знаешь как mySQL выбирает и перебирает записи?
>>455088
> в методах должна присутствовать симметрия, есть есть гет должен быть и сет
Вообще, не всегда. Некоторые поля могут быть например предназначены только для чтения или только для записи. Но тут конечно можно и добавить сеттеры. А можно не добавлять.
Я знаю что выбрать одну запись из сотни точно быстрее чем сто из миллиона. Да, потом из нее надо вытащить жсон и декодировать, тут уже можно спорить что быстрее, но в любом случае то что ты предлагаешь - каша.
> Вообще, не всегда. Некоторые поля могут быть например предназначены только для чтения или только для записи. Но тут конечно можно и добавить сеттеры. А можно не добавлять.
В данном случае аффтар поддерживает инкапсуляцию, но почему-то сетает всё одним методом за раз, а гетает по одному методу на свойство. Как-то семантически непоследовательно, делай или так или сяк уже
А это нормально устанавливать все поля в одном методе, или лучше для каждого поля отдельный сет? В данном случае я думаю переделывать смысла нет, но на будущее буду иметь ввиду.
для каждого поля - свой сет/гет
для каждого сета/гета - свой класс
для каждого класса - свой пакет
для каждого пакета - свой солюшен
Пришел на двач я, советов мудрых хочу...
Итак, теперь ссылка на скачивание у меня имеет вид.
<a href="http://localhost/uppy/download/FjGZBh05wu/%D0%B3%D1%80%D0%B0%D1%84%D0%B8%D0%BA.mp4" title="график.mp4">Скачать</a>
с кракозябрами у меня борется функция getNameForSave(). Выдаёт в нужной кодировке имена на сохранение.
https://github.com/tokotun/uppy/blob/master/uppy/app/File.php#L16
Далее, у меня провал в образовании. И я не знаю как связать ссылку, загрузку файла и X-SendFile.
И вот что в итоге имеем.
Жмем ссылку скачать. Слим парсит URL
https://github.com/tokotun/uppy/blob/master/index.php#L127
И выполняет эту функцию.
https://github.com/tokotun/uppy/blob/master/uppy/app/functions.php
Выкидывает нас по адресу ссылки.
Белая страница, ничего не проиcходит. Но если файл без русских букв, то нормально скачивает.
Отладчик в браузере пишет
Запрос
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://localhost/uppy/FjGZBh05wu
Connection: keep-alive
Ответ
Connection: Keep-Alive
Content-Length: 0
Content-Type: text/html
Date: Wed, 25 Mar 2015 18:54:44 GMT
Keep-Alive: timeout=5, max=96
Server: Apache/2.4.7 (Win64) PHP/5.5.6
x-powered-by: PHP/5.5.6
Пришел на двач я, советов мудрых хочу...
Итак, теперь ссылка на скачивание у меня имеет вид.
<a href="http://localhost/uppy/download/FjGZBh05wu/%D0%B3%D1%80%D0%B0%D1%84%D0%B8%D0%BA.mp4" title="график.mp4">Скачать</a>
с кракозябрами у меня борется функция getNameForSave(). Выдаёт в нужной кодировке имена на сохранение.
https://github.com/tokotun/uppy/blob/master/uppy/app/File.php#L16
Далее, у меня провал в образовании. И я не знаю как связать ссылку, загрузку файла и X-SendFile.
И вот что в итоге имеем.
Жмем ссылку скачать. Слим парсит URL
https://github.com/tokotun/uppy/blob/master/index.php#L127
И выполняет эту функцию.
https://github.com/tokotun/uppy/blob/master/uppy/app/functions.php
Выкидывает нас по адресу ссылки.
Белая страница, ничего не проиcходит. Но если файл без русских букв, то нормально скачивает.
Отладчик в браузере пишет
Запрос
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://localhost/uppy/FjGZBh05wu
Connection: keep-alive
Ответ
Connection: Keep-Alive
Content-Length: 0
Content-Type: text/html
Date: Wed, 25 Mar 2015 18:54:44 GMT
Keep-Alive: timeout=5, max=96
Server: Apache/2.4.7 (Win64) PHP/5.5.6
x-powered-by: PHP/5.5.6
лол, спасиб
> Но если файл без русских букв, то нормально скачивает
Попробуй тогда убрать filename из заголовка
`public function generateCode()
{
$string = "qwertyuiopasdfghjklzxcvbnm1234567890";
$strLen = mb_strlen($string);
$newString = "";
for ($i = 0; $i < 32; $i++) {`
Тут название метода можно уточнить, какой именно код ты генерируешь и еще в цикле используется целое число 32, это не очень хорошо, это т.н. магические числа, хуй знает, что оно означает, лучше создай константу `const STUDENT_CODE_LENGTH` и используй её.
Лучше отдельный. Но допонительно иметь метод для выставления полей из массива тоже нормально.
header("Content-Disposition: attachment;");
Эффект тот же
Отладчик в браузере написал то же самое
>>45505
Когда подряд идут несколько строк инициализации
protected $name = "";
protected $surname = "";
protected $gender = "";
protected $groupNumber = "";
protected $email = "";
Выравнивай их так, это более читабельно
protected $name = "";
protected $surname = "";
protected $gender = "";
protected $groupNumber = "";
protected $email = "";
ЛАЛ
Спасибо, осталось узнать что в файлике ""zagruzit'_kartinku_na_server.php". Не подскажешь?
Вроде нашел. Путаница была в кодировках путей к файлам. Которые передавал в заголовки.
Теперь файлы с русскими названиями скачиваются.
Пользуясь случаем хочу спросить.
> >А просто приписывать к имени файла номер id. Вот так 23_picture.jpg
>В этом случае php файл остается php файлом — довольно опасно.
Как правильно переименовывать файл? Как насчёт такого варианта 23_picture_jpg ?
Спасибо.
В голове у тебя каша. С твоей реализацией на json у будет такой геморрой, что тебе и не снился. То что выбирается одна строка, а не 150 например не даёт ничего. При нормальном покрывающем индексе БД выплюнет все сообщения на несколько порядков быстрее, чем у тебя займёт время работа с большой строкой (чем и является твой json).
Короче говоря, производительности можешь не ждать при сколь нибудь малой нагрузке. Как обновлять json в базе ты небось и не думал? Гонять весь лог туда сюда? Поиск по истории тоже сделать не сможешь, никакой SQL не справится.
Единственная адекватная возможность юзать json - для хранения последних N сообщений (вместе с нормализованными данными), и их сразу вытягивать, а остальное подгружать по надобности.
В общем кури нормальные формы в контексте реляционных БД. Тут я вижу классическую ситуацию 3-НФ.
Хотя, все задачи из их теста решил.
Рассказал про джоины, нормализацию.
Не сделал только простую ЖС задачку, но сказал что с ним знаком и с документацией быстро бы сделал.
И не ответил какие есть виды рекурсии.
Еще нет опыта работы с Битрикс, но это же вообще хуйня.
ЧЯДНТ
NotBadCode
>И не ответил какие есть виды рекурсии.
кажется, я бы тоже не ответил сходу. Вроде хвостовая и еще какая-то.
>Еще нет опыта работы с Битрикс, но это же вообще хуйня.
Лучше и не суйся туда, где работают с битриксом. Не надо, анон, твоя нервная система дороже. Поверь мне, уже год работаю в конторе на битриксе, это такой пиздец. Было бы куда съебать в моей мухосрани, давно бы съебал.
Вообще рекурсий вроде около 6 видов.
Бро, в ДС с 0 опыта мало вакансий(3-4) и больше половины это Битрикс.
Да, сейчас наверное кризис, и никто особо не выебывается нанимая с улицы кучу джунов, проводя стажировки среди вчерашних студентов и отбирая из них по 1-2.
Такой вопрос, работаешь ли ты с хуйхайлоадом на пыхе и как ты вкатился в него ? Несколько лет работаю, в основном цмски либо фреймворки, с нагрузкой не работал, все вакансии содержат обязательный пункт - работа с нагруженными системами и на такие вакансии ессно меня не берут. Так вот, как прокачать енту нагрузку и возможно ли это самому ? Подскажи анаончик
http://ideone.com/e7C9ea#stdin
Ну а что делать то?
Я понял что если продолжу в вузике учиться, то меня точно хуй куда возьмут
Проверьте.
И ещё вопрос :
С какого момента можно начинать искать работу фриланс/удаленную, так в офисе?
http://ideone.com/0Hi0lw
http://ideone.com/Tb533M
Жги!
Когда начинаешь подходить по требованиям, тогда и начинаешь искать.
Для достижения максимального экстрима рекомендуется дропать базу на продакшне вечером в пятницу накануне сдачи проекта.
Чет я у Кента Бека этого не помню, еще раз перечитаю, спасибо!
Скорее всего в том коде который ты вписываешь через doc.write содержится новый скрипт который снова выполняется, отправляет запрос и вставляет еще один скрипт и так до бесконечности.
>>454953
Вот замечания. Часть замечаний ты бы и сам мог заметить конечно.
- меню зачем-то смещено вниз на 10px от центра блока
- надпись We Are у тебя имеет вес 400, а надо сделать ее легче
- надпись Webpaint наоборот легче чем надо. Я советую не использовать относительный вес, а указывать абсолютный
- в блоке услуг с заголовком Consectetur маленькое межстрочное расстояние, буквы стоят слишком тесно
- в блоке услуг иконки (андроид, монитор) не выровнены по центру, а смещены влево или вправо от центра
- у блока услуг (где 4 колонки с иконками и текстом) поле справа больше чем поле слева
- надпись Curabitur blandit tempus portittor. надо сделать более легким шрифтом
- если навести мышь чуть ниже кнопки See portfolio, она все равно меняет цвет. Активная зона больше чем кнопка. Если посмотреть CSS код то видно что ты вместо правильного решения начал ставить свойства наугад в надежде что это заработает. Это неправильно. Верстальщик должен понимать что он делает и как заставить элементы располагаться как ему нравится, а не ставить свойства наугад
- в самом низу страницы, под подвалом есть белая полоска высотой пикселей 8 (это маргин body или html по умолчанию)
- на большой ширине экрана надо бы ограничить ширину портфолио чтобы в нем больше 4 картинок в ряд не вставало, так как при 5 картинках снизу остается 2 лишних
Обращай внимание на такие вещи. Я не требую верстки пиксель-в-пиксель, но тут слишком явные косяки, которые надо замечать и исправлять. Уж неправильно выровненного андроида увидеть нетрудно если посмотреть на заголовок под ним.
Теперь по коду
> <div class="spritecontainer" id="android"></div>
Этот див можно заменить на псевдоэлемент
> <div id="featuredworks">
> <div id="touch">
без этих дивов ведь можно обойтись?
> social-yellow
Это значок RSS :)
> body{
> text-align: center;
На body или html надо ставить стили для текста по умолчанию. Чтобы, если мы например выведем страницу с заголовком и парой абзацев текста, мы видели нормально оформленный текст. Ставить центрирование на body неправильно так как в этом случае страница с парой тегов вроде h1 и p будет выглядеть ужасно. Сделай чтобы с твоим CSS страница с простыми тегами выглядела нормально. Для этого надо задать на html/body стандартный для этого макета шрифт стандартного размера. Я думаю, это Lato размером 14.
> <h2>Consectetur</h2>
Я думаю тут должен стоять h3 так как это явно заголовки более низкого уровня чем h2 и размер шрифта у них меньше
> font-size: 25px;
Всегда когда задаешь font-size задавай line-height
> nav{
> float: right;
этим ты меняешь стили для всех элементов nav. Даже если сейчас у тебя нет других тегов nav, когда твою страницу натянут на CMS и добавят другие страницы, они могут появиться и этим ты портишь жизнь тем кто будет работать с версткой позже. Сделай чтобы стили применялись только к этому меню, а не к любым элементам nav
> font-weight: 600;
У тебя все равно нет шрифта с таким весом
> font-family: 'Lato', Arial;
В конец надо дописывать стандартный шрифт (serif, sans-serif, cursive, fantasy, monotype)
> font-family: "Lato", "Times New Roman",
Странно для шрифта без засечек указывать альтернативу с засечками
> .serviceblock{
>\tmax-height: 280px;
Непонятно зачем это тут стоит
> .servicecontents{
> width: 20%;
> margin-right: 50px;
Ты зря смешиваешь вместе пикселы и проценты. Они в сумме никогда не дадут 100% и получится либо меньше либо больше.
> input.button{
А зачем input писать? Разве класса недостаточно?
Далее, в логотипе ты исплоьзуешь a вложенный в div, но там можно оставить просто a, div лишний.
Если ты смещаешь nav вправо за счет float то он должен идти перед нормальным не-float контентом, а не после. Иначе есть риск что он провалится на одну строчку ниже.
> .slider span
Плохая идея использовать тут span. Если мы захотим добавить в шапку еще спан, к нему применятся эти стили.
> .portfolio-button a {
> overflow: hidden;
зачем это?
> .portfolio-button a {
> height: 100%;
Лучше просто указывать высоту кнопки на теге a, тогда на его родителе div высоту можно не указывать вообще (более того div вообще не нужен будет). Ну а в твоем случае лучше было бы сделать так:
.portfolio-button сделать блоком, без указания ширины или высоты, но с указанием text-align: center
ссылку внутри сделать inline-block с указанием размеров
Это позволит легко добавить например еще одну кнопку рядом или надпись и они по-прежнему будут центрироваться.
У правого .servicecontents не должно быть margin-right
> .serviceblock {
> display: inline-block;
Это лучше наверно было обычным блоком сделать
> .button + .portfolio-selector {
> margin-top: 30px;
Почему на внутреннем спане внутри кнопки стоит такой margin-top?
> .socialnetworks {
> margin-top: 30px;
Опять же лучше верхний отступ ставить на родительском диве, а не на внутренних элементах
Скорее всего в том коде который ты вписываешь через doc.write содержится новый скрипт который снова выполняется, отправляет запрос и вставляет еще один скрипт и так до бесконечности.
>>454953
Вот замечания. Часть замечаний ты бы и сам мог заметить конечно.
- меню зачем-то смещено вниз на 10px от центра блока
- надпись We Are у тебя имеет вес 400, а надо сделать ее легче
- надпись Webpaint наоборот легче чем надо. Я советую не использовать относительный вес, а указывать абсолютный
- в блоке услуг с заголовком Consectetur маленькое межстрочное расстояние, буквы стоят слишком тесно
- в блоке услуг иконки (андроид, монитор) не выровнены по центру, а смещены влево или вправо от центра
- у блока услуг (где 4 колонки с иконками и текстом) поле справа больше чем поле слева
- надпись Curabitur blandit tempus portittor. надо сделать более легким шрифтом
- если навести мышь чуть ниже кнопки See portfolio, она все равно меняет цвет. Активная зона больше чем кнопка. Если посмотреть CSS код то видно что ты вместо правильного решения начал ставить свойства наугад в надежде что это заработает. Это неправильно. Верстальщик должен понимать что он делает и как заставить элементы располагаться как ему нравится, а не ставить свойства наугад
- в самом низу страницы, под подвалом есть белая полоска высотой пикселей 8 (это маргин body или html по умолчанию)
- на большой ширине экрана надо бы ограничить ширину портфолио чтобы в нем больше 4 картинок в ряд не вставало, так как при 5 картинках снизу остается 2 лишних
Обращай внимание на такие вещи. Я не требую верстки пиксель-в-пиксель, но тут слишком явные косяки, которые надо замечать и исправлять. Уж неправильно выровненного андроида увидеть нетрудно если посмотреть на заголовок под ним.
Теперь по коду
> <div class="spritecontainer" id="android"></div>
Этот див можно заменить на псевдоэлемент
> <div id="featuredworks">
> <div id="touch">
без этих дивов ведь можно обойтись?
> social-yellow
Это значок RSS :)
> body{
> text-align: center;
На body или html надо ставить стили для текста по умолчанию. Чтобы, если мы например выведем страницу с заголовком и парой абзацев текста, мы видели нормально оформленный текст. Ставить центрирование на body неправильно так как в этом случае страница с парой тегов вроде h1 и p будет выглядеть ужасно. Сделай чтобы с твоим CSS страница с простыми тегами выглядела нормально. Для этого надо задать на html/body стандартный для этого макета шрифт стандартного размера. Я думаю, это Lato размером 14.
> <h2>Consectetur</h2>
Я думаю тут должен стоять h3 так как это явно заголовки более низкого уровня чем h2 и размер шрифта у них меньше
> font-size: 25px;
Всегда когда задаешь font-size задавай line-height
> nav{
> float: right;
этим ты меняешь стили для всех элементов nav. Даже если сейчас у тебя нет других тегов nav, когда твою страницу натянут на CMS и добавят другие страницы, они могут появиться и этим ты портишь жизнь тем кто будет работать с версткой позже. Сделай чтобы стили применялись только к этому меню, а не к любым элементам nav
> font-weight: 600;
У тебя все равно нет шрифта с таким весом
> font-family: 'Lato', Arial;
В конец надо дописывать стандартный шрифт (serif, sans-serif, cursive, fantasy, monotype)
> font-family: "Lato", "Times New Roman",
Странно для шрифта без засечек указывать альтернативу с засечками
> .serviceblock{
>\tmax-height: 280px;
Непонятно зачем это тут стоит
> .servicecontents{
> width: 20%;
> margin-right: 50px;
Ты зря смешиваешь вместе пикселы и проценты. Они в сумме никогда не дадут 100% и получится либо меньше либо больше.
> input.button{
А зачем input писать? Разве класса недостаточно?
Далее, в логотипе ты исплоьзуешь a вложенный в div, но там можно оставить просто a, div лишний.
Если ты смещаешь nav вправо за счет float то он должен идти перед нормальным не-float контентом, а не после. Иначе есть риск что он провалится на одну строчку ниже.
> .slider span
Плохая идея использовать тут span. Если мы захотим добавить в шапку еще спан, к нему применятся эти стили.
> .portfolio-button a {
> overflow: hidden;
зачем это?
> .portfolio-button a {
> height: 100%;
Лучше просто указывать высоту кнопки на теге a, тогда на его родителе div высоту можно не указывать вообще (более того div вообще не нужен будет). Ну а в твоем случае лучше было бы сделать так:
.portfolio-button сделать блоком, без указания ширины или высоты, но с указанием text-align: center
ссылку внутри сделать inline-block с указанием размеров
Это позволит легко добавить например еще одну кнопку рядом или надпись и они по-прежнему будут центрироваться.
У правого .servicecontents не должно быть margin-right
> .serviceblock {
> display: inline-block;
Это лучше наверно было обычным блоком сделать
> .button + .portfolio-selector {
> margin-top: 30px;
Почему на внутреннем спане внутри кнопки стоит такой margin-top?
> .socialnetworks {
> margin-top: 30px;
Опять же лучше верхний отступ ставить на родительском диве, а не на внутренних элементах
>- надпись We Are у тебя имеет вес 400, а надо сделать ее легче
Там же ligter стоит, 400 у меня стояло до этого.
>надпись Webpaint наоборот легче чем надо. Я советую не использовать относительный вес, а указывать абсолютный
Это же картинка, а не надпись, я её из псд файла взял. Как она может быть легче чем надо?
А лол, там же еще одна надпись, я подумал про логотип сначала.
Да, было несколько задач на пхп
как бы на пхп такое декомпрессировать?
Ты зря убрал поля из базового класса Employee. Смотри сам:
https://github.com/someApprentice/Vector-Com/blob/master/Classes/Employee.php#L16
Тут ты обращаешься к полю, которого нет в классе. так нельзя.
Правильно делать так:
class Employee {
protected $baseSalary;
..
class Analyst extends Employee {
protected $baseSalary = 500; // переопределяем значение по умолчанию
Поля у которых нет начальных значений (isLeader, rank) достаточно определить только в базовом классе.
По моему ты не до конца разобрался как работают private/protected и из-за этого все напутал. private виден только в одном классе. protected во всей цепочке наследования (но использовать его можно только в классе где он определен и его потомках, в предках нельзя так как они еще не знают об этом свойстве).
> public function getName() {
>\t\treturn self::class;
Вообще наверно можно было в Employee написать return static::class и это бы сработало, хотя я не уверен. Проверь-ка.
Отличие self от static:
http://php.net/manual/ru/language.oop5.late-static-bindings.php
http://habrahabr.ru/post/23066/
Ты наверно заметишь что различия довольно тонкие а примеры кода сложные для понимания. Потому не стоит особо пользоваться такими вещами.
> public function setLeader($newLeader) {
тут хорошо бы проверять что лидер работает в этом департаменте. Иначе этот тест провалится:
$newLeader = new Analyst;
$dep->setLeader($newLeader);
$leaders = $dep->getLeaders( );
// должны получить не пустой массив а получим пустой
assert(!empty($leaders));
assert($leaders[0] === $newLeader);
Согласись, неправильно когда ты назначил лидера, но департамент его не видит. Надо либо запрещать назначать сторонних боссов либо автоматически принимать их в департамент.
В общем, в остальном меня все устраивает. Надеюсь, ты извлек из задачи какое-то понимание ООП и умение строить модели предметной области (да, это так называется — domain model) для решения задачи. Если ты захочешь еще помучать ООП, то у меня есть дополнительная задача написать свой аналог DOM, в которой объектов и классов будет больше, а их связи сложнее. ну или ты можешь решать задачки из оп-поста, про студентов, файлообменнник, они больше не на ООП, а на практические навыки создания сайтов, форм, вывода данных, работы с базой.
Ты зря убрал поля из базового класса Employee. Смотри сам:
https://github.com/someApprentice/Vector-Com/blob/master/Classes/Employee.php#L16
Тут ты обращаешься к полю, которого нет в классе. так нельзя.
Правильно делать так:
class Employee {
protected $baseSalary;
..
class Analyst extends Employee {
protected $baseSalary = 500; // переопределяем значение по умолчанию
Поля у которых нет начальных значений (isLeader, rank) достаточно определить только в базовом классе.
По моему ты не до конца разобрался как работают private/protected и из-за этого все напутал. private виден только в одном классе. protected во всей цепочке наследования (но использовать его можно только в классе где он определен и его потомках, в предках нельзя так как они еще не знают об этом свойстве).
> public function getName() {
>\t\treturn self::class;
Вообще наверно можно было в Employee написать return static::class и это бы сработало, хотя я не уверен. Проверь-ка.
Отличие self от static:
http://php.net/manual/ru/language.oop5.late-static-bindings.php
http://habrahabr.ru/post/23066/
Ты наверно заметишь что различия довольно тонкие а примеры кода сложные для понимания. Потому не стоит особо пользоваться такими вещами.
> public function setLeader($newLeader) {
тут хорошо бы проверять что лидер работает в этом департаменте. Иначе этот тест провалится:
$newLeader = new Analyst;
$dep->setLeader($newLeader);
$leaders = $dep->getLeaders( );
// должны получить не пустой массив а получим пустой
assert(!empty($leaders));
assert($leaders[0] === $newLeader);
Согласись, неправильно когда ты назначил лидера, но департамент его не видит. Надо либо запрещать назначать сторонних боссов либо автоматически принимать их в департамент.
В общем, в остальном меня все устраивает. Надеюсь, ты извлек из задачи какое-то понимание ООП и умение строить модели предметной области (да, это так называется — domain model) для решения задачи. Если ты захочешь еще помучать ООП, то у меня есть дополнительная задача написать свой аналог DOM, в которой объектов и классов будет больше, а их связи сложнее. ну или ты можешь решать задачки из оп-поста, про студентов, файлообменнник, они больше не на ООП, а на практические навыки создания сайтов, форм, вывода данных, работы с базой.
Я все понял! Я понял! Это маленькая l, просто в курсивном начертании у нее есть хвостик. Попробуй рядом напечатать большую L и увидишь что она выглядит по-другому.
Кстати я и в первый раз на видео воспринял ее как маленькую, но я подумал, может это я что-то не так понял, и решил промолчать.
Курсивные буквы это не просто наклоненные на бок буквы, они пишутся немного по-другому, как бы имитируя рукописный шрифт. Если буквы просто наклонены, то это называется механический курсив (faux italic) и обычно смотрится плохо. Браузеры (или операционная система? не помню) используют механический курсив если в шрифт не заложено курсивное начертание. Например у шрифта Tahoma нет курсива и если ты попытаешься его исплоьзовать, то получишь некрасивые наклоненные буквы. Как верстальщик ты должен это понимать.
Аналогично существует искуственное ожирнение букв (faux bold). Вот подробная статья на английском (на русском не нашел, но ты можешь посмотреть картинки и увидеть сам) http://alistapart.com/article/say-no-to-faux-bold
Это скорее всего из-за того что nav идет после логотипа.
>>455030
Ты тоже
>>455038
Сделай в роутере var_dump для REQUEST_URI и добавь в switch пункт default.
Ну и то что у тебя это не роутер а испорченный FrontController ( http://design-pattern.ru/patterns/front-controller.html )
Роутер ничего не вызывает, а просто возвращает информацию о том какой контроллер с какими параметрами вызвать:
$url = '/hello/1';
$result = $router->route($url);
// [ '_controller' => 'HelloController::index', 'id' => 1 ]
Ну и не используй статические метоыд вместо нормальынх. Этим ты отказываешься почти от всех преимуществ ООП и начинаешь писать практически процедурный код. Ведь ты например не можешь создать 2 объекта с разными настройками или передать объект класса-наследника вместо базового класса.
> class ModelUserpage
Это вообще непонятно что. Модель — это гм, модель чего-то. Например модель работника или департамента в задаче про Вектор. Что представляет объект этого класса? Непонятно.
> prepareDataForView
таких методов по идее быть не должно, так как навзание ничего не говорит, а сам метод непонятно что делает. Зачем подготавливать данные для view? Почему модель должна знать что-то про view? Почему она должна как-то подготавливать данные?
И тем более с каких это пор в MVC модель генерирует представление?
> ViewUserpage::generate($user);
Ты по моему не понял толком как работает MVC. Давай я в помощь приведу описание из задания про студентов:
===========
Подход MVC заключается в том, что мы разбиваем приложение на 3 слабо связанных части: Модель (Model), Представление (View) и Контроллер (Controller).
Модель хранит и обрабатывает данные приложения, не взаимодействуя с внешним миром. Например, сохранение информации в БД, проверка правильности введенных данных — это задача Модели, но вывод информации — нет. Модель не должна обращаться к внешним переменным вроде $_GET/$_POST/$_SESSION/$_COOKIE и не должна ничего выводить. В этой задаче модель может состоять из классов, описывающих абитуриента и работающих с БД.
Представление отображает данные. Оно не должно обращаться к внешним переменным или к базе данных, его задача просто выводить те данные, которые ему передал контроллер. В этой задаче представление скорее всего будет содержать только шаблоны.
Контроллер отвечает за взаимодействие с внешним миром (пользователем) и управление всем процессом. Обычно контроллер разбирает параметры запроса из $_POST/$_GET, обращается к модели, чтобы получить какие-то данные или сделать какое-то действие, и в конце вызывает Представление, чтобы отобразить результат. Здесь контроллерами могут быть скрипты, которые отвечают за вывод списка и обработку формы редактирования/регистрации.
Если ты будешь искать в интернете информацию о MVC, учти что этот подход изначально придуман в 80-е годы для десктопных приложений (с окошечками и кнопочками), а не веб-приложений и «MVC для десктопа» чуть-чуть отличается от «MVC для веба», так как десктопные приложения в отличие от PHP-скрипта, не завершаются после вывода информации на экран, а продолжают работать. Но общие принципы те же.
Если следовать MVC, разделяя код на части, то он будет проще и надежнее.
===========
> public static function editData($input)
тут ты используешь массивы хотя мог бы передавать объект. Это какое-то массиво-ориентированное программирование, а не ООП.
Ну в общем, код очень странный, если ты делаешь задание про студентов.
Это скорее всего из-за того что nav идет после логотипа.
>>455030
Ты тоже
>>455038
Сделай в роутере var_dump для REQUEST_URI и добавь в switch пункт default.
Ну и то что у тебя это не роутер а испорченный FrontController ( http://design-pattern.ru/patterns/front-controller.html )
Роутер ничего не вызывает, а просто возвращает информацию о том какой контроллер с какими параметрами вызвать:
$url = '/hello/1';
$result = $router->route($url);
// [ '_controller' => 'HelloController::index', 'id' => 1 ]
Ну и не используй статические метоыд вместо нормальынх. Этим ты отказываешься почти от всех преимуществ ООП и начинаешь писать практически процедурный код. Ведь ты например не можешь создать 2 объекта с разными настройками или передать объект класса-наследника вместо базового класса.
> class ModelUserpage
Это вообще непонятно что. Модель — это гм, модель чего-то. Например модель работника или департамента в задаче про Вектор. Что представляет объект этого класса? Непонятно.
> prepareDataForView
таких методов по идее быть не должно, так как навзание ничего не говорит, а сам метод непонятно что делает. Зачем подготавливать данные для view? Почему модель должна знать что-то про view? Почему она должна как-то подготавливать данные?
И тем более с каких это пор в MVC модель генерирует представление?
> ViewUserpage::generate($user);
Ты по моему не понял толком как работает MVC. Давай я в помощь приведу описание из задания про студентов:
===========
Подход MVC заключается в том, что мы разбиваем приложение на 3 слабо связанных части: Модель (Model), Представление (View) и Контроллер (Controller).
Модель хранит и обрабатывает данные приложения, не взаимодействуя с внешним миром. Например, сохранение информации в БД, проверка правильности введенных данных — это задача Модели, но вывод информации — нет. Модель не должна обращаться к внешним переменным вроде $_GET/$_POST/$_SESSION/$_COOKIE и не должна ничего выводить. В этой задаче модель может состоять из классов, описывающих абитуриента и работающих с БД.
Представление отображает данные. Оно не должно обращаться к внешним переменным или к базе данных, его задача просто выводить те данные, которые ему передал контроллер. В этой задаче представление скорее всего будет содержать только шаблоны.
Контроллер отвечает за взаимодействие с внешним миром (пользователем) и управление всем процессом. Обычно контроллер разбирает параметры запроса из $_POST/$_GET, обращается к модели, чтобы получить какие-то данные или сделать какое-то действие, и в конце вызывает Представление, чтобы отобразить результат. Здесь контроллерами могут быть скрипты, которые отвечают за вывод списка и обработку формы редактирования/регистрации.
Если ты будешь искать в интернете информацию о MVC, учти что этот подход изначально придуман в 80-е годы для десктопных приложений (с окошечками и кнопочками), а не веб-приложений и «MVC для десктопа» чуть-чуть отличается от «MVC для веба», так как десктопные приложения в отличие от PHP-скрипта, не завершаются после вывода информации на экран, а продолжают работать. Но общие принципы те же.
Если следовать MVC, разделяя код на части, то он будет проще и надежнее.
===========
> public static function editData($input)
тут ты используешь массивы хотя мог бы передавать объект. Это какое-то массиво-ориентированное программирование, а не ООП.
Ну в общем, код очень странный, если ты делаешь задание про студентов.
Спасибо, ОП. Попробую переделать всё с нуля.
Но сначала разберусь, почему не отображается "/userpage".
Библиотекой для работы с xlsx.
Тестовое задание проверяет твои знания, а не наши, и умение гуглить.
>>455051
Код знакомый. Ты наверно вдохновлялся кодом другого анона? Имей в виду, чем больше ты пишешь сам с нуля, тем больше пользы ты получаешь.
https://github.com/sgscode/students/blob/master/students.sql#L40
> ) ENGINE=InnoDB DEFAULT CHARSET=latin1
Ты таким образом легко можешь сломать русские буквы. Надо при создании таблицы либо явно указывать utf-8 либо для базы данных поставить utf-8 по умолчанию.
> https://github.com/sgscode/students/blob/master/formpage.php#L13
А что если студент не найден в БД? У тебя будет false в переменной student и код может сломаться.
> fetchStudent
Более удачное название было бы getStudentByCode
> https://github.com/sgscode/students/blob/master/formpage.php#L18
> if ($formXsrf == $cookieXsrf) {
тут лучше использовать ===, а то из-за нестрогого сравнения можно получить ошибку. Например var_dump(0 == "asas"); выведет true, и был случай когда таким способом обходили проверку то ли капчи, то ли пароля (не уверен сработает ли это тут но лучше использовать === ):
http://habrahabr.ru/post/190440/
http://php.net/manual/ru/language.operators.comparison.php
> https://github.com/sgscode/students/blob/master/lib/Student.php#L15
Ошибки, мне кажется, лучше не хранить в студенте, так как мы усложняем пользование классом:
$s = new Student;
$s->setFields([
'name' => '0000'
]);
$e = $s->getErrors('surname');
// казалось бы мы должны получить кучу ошибок, а их нет
https://github.com/sgscode/students/blob/master/lib/Student.php#L24
> $string[mt_rand(0, $strLen - 1)];
Нельзя обращаться к строке как к массиву так как с utf-8 это не работает, потому лучше так не писать.
> https://github.com/sgscode/students/blob/master/lib/Student.php#L36
> if (isset($sentData['code'])) {
> $this->code = $sentData['code'];
А зачем переопределять код доступа из полученных данных?
> $charRegExp = "/^[а-яa-zё-]{2,100}$/ui";
Вот китаец с фамилией Ю обрадуется: https://ru.wikipedia.org/wiki/%D0%92%D0%B0%D0%BD,_%D0%94%D0%B6%D0%B8%D0%BC%D0%BC%D0%B8_(%D0%B0%D0%BA%D1%82%D1%91%D1%80)
> https://github.com/sgscode/students/blob/master/lib/Student.php#L49
Функция checkFields сделана так что если исправить ошибки и вызвать ее повторно, старые сообщения об ошибке не удаляются. Потому я советую не хранить их вообще.
> https://github.com/sgscode/students/blob/master/lib/StudentMapper.php#L90
В таких случаях надо писать не return (значение которого ты все равно не проверяешь?) а выбрасывать исключение либо ставить безопасное значение по умолчанию.
При использовании PDO::FETCH_CLASS PDO проставляет поля до вызова конструктора (что абсурдно с точки зрения ООП так как конструктор должен вызываться раньше). Стоит добавить еще один флаг PDO::FETCH_PROPS_LATE: http://php-zametki.ru/php-prodvinutym/57-pdo-konstanty-vyborki-dannyx.html
> https://github.com/sgscode/students/blob/master/lib/PageNavigator.php#L73
лучше бы не использовать PHP_SELF, а передавать URL снаружи, класс будет более универсальным
> https://github.com/sgscode/students/blob/master/lib/bootstrap.php#L10
Здесь нужен SET NAMES задающий кодировку соединения
http://gahcep.github.io/blog/2013/01/05/mysql-utf8/
http://fstrange.ru/coder/mysql/kodirovka-krakozyably.html
http://phpfaq.ru/charset
> https://github.com/sgscode/students/blob/master/lib/bootstrap.php#L15
это лучше вынести в соотв. файлы наверно?
> https://github.com/sgscode/students/blob/master/lib/bootstrap.php#L6
Вообще лучше инклудить файл только если он существует. Это позволит избежать проблем когда ты подключишь библиотеку у которой свой автолоадер и свои классы.
> https://github.com/sgscode/students/blob/master/lib/functions.php
Работу с CSRF лучше вынести в класс со статическими методами (паттерн Utility Class http://en.wikipedia.org/wiki/Utility_pattern )
> <?php } ?>
надо использовать операторы с двоеточием вместо скобок в шаблоне ради читаемости https://php.net/manual/ru/control-structures.alternative-syntax.php
> https://github.com/sgscode/students/blob/master/templates/list.php#L34
> as $key => $value
дай переменным понятные названия и прочитай статью: http://learn.javascript.ru/write-unmain-code#будьте-абстрактны-при-выборе-имени
> https://github.com/sgscode/students/blob/master/templates/list.php#L35
> 10):
Здесь у тебя спрятано число записей на странице. Хороший же будет сюрприз когда кто-то поменяет число записей в php файле, а тут забудет и текущая страница перестанет выделяться!
Число записей должно храниться только в одном месте в коде.
> https://github.com/sgscode/students/blob/master/templates/list.php#L38
Сылки тоже надо пропускать через h() не ради безопасности а ради правильного HTML кода, так как в & ссылках должен писаться как &
> https://github.com/sgscode/students/tree/master/templates/bootstrap
это надо вынести из папки шаблонов в папку css или static
Для полей ввода чисел лучше исплоьзовать специальный тип input, а не text. Тогда например на мобильных устройствах будет выезжать клавиатура с цифрами: http://htmlbook.ru/html5/forms
> https://github.com/sgscode/students/blob/master/templates/form.php#L54
тут checked лучше поставить внутри if
Так вообще, пока выглядит неплохо.
Библиотекой для работы с xlsx.
Тестовое задание проверяет твои знания, а не наши, и умение гуглить.
>>455051
Код знакомый. Ты наверно вдохновлялся кодом другого анона? Имей в виду, чем больше ты пишешь сам с нуля, тем больше пользы ты получаешь.
https://github.com/sgscode/students/blob/master/students.sql#L40
> ) ENGINE=InnoDB DEFAULT CHARSET=latin1
Ты таким образом легко можешь сломать русские буквы. Надо при создании таблицы либо явно указывать utf-8 либо для базы данных поставить utf-8 по умолчанию.
> https://github.com/sgscode/students/blob/master/formpage.php#L13
А что если студент не найден в БД? У тебя будет false в переменной student и код может сломаться.
> fetchStudent
Более удачное название было бы getStudentByCode
> https://github.com/sgscode/students/blob/master/formpage.php#L18
> if ($formXsrf == $cookieXsrf) {
тут лучше использовать ===, а то из-за нестрогого сравнения можно получить ошибку. Например var_dump(0 == "asas"); выведет true, и был случай когда таким способом обходили проверку то ли капчи, то ли пароля (не уверен сработает ли это тут но лучше использовать === ):
http://habrahabr.ru/post/190440/
http://php.net/manual/ru/language.operators.comparison.php
> https://github.com/sgscode/students/blob/master/lib/Student.php#L15
Ошибки, мне кажется, лучше не хранить в студенте, так как мы усложняем пользование классом:
$s = new Student;
$s->setFields([
'name' => '0000'
]);
$e = $s->getErrors('surname');
// казалось бы мы должны получить кучу ошибок, а их нет
https://github.com/sgscode/students/blob/master/lib/Student.php#L24
> $string[mt_rand(0, $strLen - 1)];
Нельзя обращаться к строке как к массиву так как с utf-8 это не работает, потому лучше так не писать.
> https://github.com/sgscode/students/blob/master/lib/Student.php#L36
> if (isset($sentData['code'])) {
> $this->code = $sentData['code'];
А зачем переопределять код доступа из полученных данных?
> $charRegExp = "/^[а-яa-zё-]{2,100}$/ui";
Вот китаец с фамилией Ю обрадуется: https://ru.wikipedia.org/wiki/%D0%92%D0%B0%D0%BD,_%D0%94%D0%B6%D0%B8%D0%BC%D0%BC%D0%B8_(%D0%B0%D0%BA%D1%82%D1%91%D1%80)
> https://github.com/sgscode/students/blob/master/lib/Student.php#L49
Функция checkFields сделана так что если исправить ошибки и вызвать ее повторно, старые сообщения об ошибке не удаляются. Потому я советую не хранить их вообще.
> https://github.com/sgscode/students/blob/master/lib/StudentMapper.php#L90
В таких случаях надо писать не return (значение которого ты все равно не проверяешь?) а выбрасывать исключение либо ставить безопасное значение по умолчанию.
При использовании PDO::FETCH_CLASS PDO проставляет поля до вызова конструктора (что абсурдно с точки зрения ООП так как конструктор должен вызываться раньше). Стоит добавить еще один флаг PDO::FETCH_PROPS_LATE: http://php-zametki.ru/php-prodvinutym/57-pdo-konstanty-vyborki-dannyx.html
> https://github.com/sgscode/students/blob/master/lib/PageNavigator.php#L73
лучше бы не использовать PHP_SELF, а передавать URL снаружи, класс будет более универсальным
> https://github.com/sgscode/students/blob/master/lib/bootstrap.php#L10
Здесь нужен SET NAMES задающий кодировку соединения
http://gahcep.github.io/blog/2013/01/05/mysql-utf8/
http://fstrange.ru/coder/mysql/kodirovka-krakozyably.html
http://phpfaq.ru/charset
> https://github.com/sgscode/students/blob/master/lib/bootstrap.php#L15
это лучше вынести в соотв. файлы наверно?
> https://github.com/sgscode/students/blob/master/lib/bootstrap.php#L6
Вообще лучше инклудить файл только если он существует. Это позволит избежать проблем когда ты подключишь библиотеку у которой свой автолоадер и свои классы.
> https://github.com/sgscode/students/blob/master/lib/functions.php
Работу с CSRF лучше вынести в класс со статическими методами (паттерн Utility Class http://en.wikipedia.org/wiki/Utility_pattern )
> <?php } ?>
надо использовать операторы с двоеточием вместо скобок в шаблоне ради читаемости https://php.net/manual/ru/control-structures.alternative-syntax.php
> https://github.com/sgscode/students/blob/master/templates/list.php#L34
> as $key => $value
дай переменным понятные названия и прочитай статью: http://learn.javascript.ru/write-unmain-code#будьте-абстрактны-при-выборе-имени
> https://github.com/sgscode/students/blob/master/templates/list.php#L35
> 10):
Здесь у тебя спрятано число записей на странице. Хороший же будет сюрприз когда кто-то поменяет число записей в php файле, а тут забудет и текущая страница перестанет выделяться!
Число записей должно храниться только в одном месте в коде.
> https://github.com/sgscode/students/blob/master/templates/list.php#L38
Сылки тоже надо пропускать через h() не ради безопасности а ради правильного HTML кода, так как в & ссылках должен писаться как &
> https://github.com/sgscode/students/tree/master/templates/bootstrap
это надо вынести из папки шаблонов в папку css или static
Для полей ввода чисел лучше исплоьзовать специальный тип input, а не text. Тогда например на мобильных устройствах будет выезжать клавиатура с цифрами: http://htmlbook.ru/html5/forms
> https://github.com/sgscode/students/blob/master/templates/form.php#L54
тут checked лучше поставить внутри if
Так вообще, пока выглядит неплохо.
> Хранить все сообщения в такой каше?
Это не каша а стандартный денормализованный способ по умолчанию
>>455096
Диванный оптимизатор? Прежде чем придумывать свои странные форматы надо как минимум подумать, а нужно ли это и сделать тесты. Иначе навоображать себе можно что угодно, а потом мучаться с этой велосипедной схемой хранения данных. Вставка как минимум не очень удобная получается.
> то что ты предлагаешь - каша.
Это стандартный способ.
>>455129
ответил >>455454\t
>>455141
Если нет необходимости принимать данные из массива то отдельные сеттеры конечно лучше.
>>455165
да, константа помогает повысить читабельность.
>>455168
слышал что выравнивают присваивания переменным, когда там идут выражения, а тут и без выравнивания все хорошо читается. Требования выравнивать в PSR нет, и я не думаю, что тут обязательно так делать.
>>455188
> Как правильно переименовывать файл?
Можно 23_picture_jpg, можно даже 23.bin. Под Windows с русскими буквами (и тем более с иероглифами) будут проблемы. Кстати, проверь чтобы твой файлообменник работал с иероглифами. если надо, вот пример такого файла: http://rghost.ru/6PvRNs6lV
>>455202
Ты только чуть ошибся тут:
> При нормальном покрывающем индексе
varchar в индекс засовывать нецелесообразно, а text вообще невозможно
А насчет ненормализации/денормализации — это надо проверять тестами. а если тестов (или необходимости оптимизировать) нет то и не придумывать свои велосипеды.
> Хранить все сообщения в такой каше?
Это не каша а стандартный денормализованный способ по умолчанию
>>455096
Диванный оптимизатор? Прежде чем придумывать свои странные форматы надо как минимум подумать, а нужно ли это и сделать тесты. Иначе навоображать себе можно что угодно, а потом мучаться с этой велосипедной схемой хранения данных. Вставка как минимум не очень удобная получается.
> то что ты предлагаешь - каша.
Это стандартный способ.
>>455129
ответил >>455454\t
>>455141
Если нет необходимости принимать данные из массива то отдельные сеттеры конечно лучше.
>>455165
да, константа помогает повысить читабельность.
>>455168
слышал что выравнивают присваивания переменным, когда там идут выражения, а тут и без выравнивания все хорошо читается. Требования выравнивать в PSR нет, и я не думаю, что тут обязательно так делать.
>>455188
> Как правильно переименовывать файл?
Можно 23_picture_jpg, можно даже 23.bin. Под Windows с русскими буквами (и тем более с иероглифами) будут проблемы. Кстати, проверь чтобы твой файлообменник работал с иероглифами. если надо, вот пример такого файла: http://rghost.ru/6PvRNs6lV
>>455202
Ты только чуть ошибся тут:
> При нормальном покрывающем индексе
varchar в индекс засовывать нецелесообразно, а text вообще невозможно
А насчет ненормализации/денормализации — это надо проверять тестами. а если тестов (или необходимости оптимизировать) нет то и не придумывать свои велосипеды.
Оп, спасибо что проверил! Завтра буду исправлять.
Может они как раз хотят человека с опытом рабты на битриксе или аналогичной CMS чтобы не тратить время на освоение.
>>455258
Я сам не знаю какие виды имеются в виду, в гугле вроде пишут про прямую и косвенную.
>>455262
Начинающим все же не стоит быть такими привередливыми, на битриксе писать не хочу, php мне не нравится и тд. Программистов нанимают для решения задач с минимальными затратами времени, а не написания безупречного кода на их любимом языке (у нас в треде кстати наоборот).
Ну и если ты хочешь на что-то другое перейти, стоит фреймворки учить наверно, с ними тоже можно найти работу (если у тебя в городе ничего кроме студий нет, то фриланс/удаленка).
>>455263
нет, там небольшие замечания я написал выше. Но ты не жди меня в таких случаях, решай следующую задачу.
>>455264
Битрикс выгоден студиям так как он платный и фирма разработчик платит им долю от продаж, в низкобюджетном секторе это неплохая прибавка. Но конечно ничего сложного на нем без боли не сделаешь.
>>455265
Ну да. Если затраты у компаний из реального сектора выросли, то им наверно не до заказов сайтов. Пока что хорошо только тем кто на запад работает, но им я бы тоже не советовал расслабляться. Не так давно жители Крыма лишились доступа к американским сервисам, включая одеск, кто знает может и остальным разработчикам придется заняться импортозамещением долларовых заказов на рублевые.
Может они как раз хотят человека с опытом рабты на битриксе или аналогичной CMS чтобы не тратить время на освоение.
>>455258
Я сам не знаю какие виды имеются в виду, в гугле вроде пишут про прямую и косвенную.
>>455262
Начинающим все же не стоит быть такими привередливыми, на битриксе писать не хочу, php мне не нравится и тд. Программистов нанимают для решения задач с минимальными затратами времени, а не написания безупречного кода на их любимом языке (у нас в треде кстати наоборот).
Ну и если ты хочешь на что-то другое перейти, стоит фреймворки учить наверно, с ними тоже можно найти работу (если у тебя в городе ничего кроме студий нет, то фриланс/удаленка).
>>455263
нет, там небольшие замечания я написал выше. Но ты не жди меня в таких случаях, решай следующую задачу.
>>455264
Битрикс выгоден студиям так как он платный и фирма разработчик платит им долю от продаж, в низкобюджетном секторе это неплохая прибавка. Но конечно ничего сложного на нем без боли не сделаешь.
>>455265
Ну да. Если затраты у компаний из реального сектора выросли, то им наверно не до заказов сайтов. Пока что хорошо только тем кто на запад работает, но им я бы тоже не советовал расслабляться. Не так давно жители Крыма лишились доступа к американским сервисам, включая одеск, кто знает может и остальным разработчикам придется заняться импортозамещением долларовых заказов на рублевые.
>>455280
> и как ты вкатился в него ?
Поработал в компании-разработчике высоконагруженных сайтов. Собственно это самый лучший вариант, только чтобы попасть в такую компанию надо уже иметь какие-то начальные знания. Тебе было бы полезно подучить:
Особенности оптимизации запросов в БД (индексы, EXPLAIN, немного про тюнинг памяти, объемов разных буферов и SHOW ENGINE INNODB STATUS)
http://ruhighload.com/post/%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0+%D1%81+%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D0%B0%D0%BC%D0%B8+%D0%B2+MySQL
http://habrahabr.ru/post/211022/
http://habrahabr.ru/post/31129/
Вот это годная статья: http://habrahabr.ru/company/mailru/blog/206494/
Денормализация данных в Бд ради оптимизации. Горизонтальное и вертикальное масштабирование,
Нужно любить делать тесты, например для проверки как быстрее хранить или искать данные в таблице. Любить пользоваться бенчмарками наподобие ab, siege.
Кеширование и key value кеширующие хранилища: memcahce, redis
http://lib.custis.ru/%D0%9A%D1%8D%D1%88%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B2_%D0%B2%D0%B5%D0%B1-%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F%D1%85_-_%D1%87%D1%82%D0%BE,_%D0%B3%D0%B4%D0%B5,_%D0%BA%D0%BE%D0%B3%D0%B4%D0%B0 (там есть PDF и наверно где-то есть видео но я его не видел)
http://habrahabr.ru/post/42607/
офиц. сайт redis
Командная строка linux (bash, утилиты), простые скрипты,Ю написание cli скриптов на php
Алгоритмы, структуры данных и сложность вроде O(N), O(1). Какова сложность in_array, array_key_exists?
Архитектура нагруженных сервисов, вот набор статей для начала:
http://www.insight-it.ru/highload/
http://ruhighload.com/post/%D0%90%D1%80%D1%85%D0%B8%D1%82%D0%B5%D0%BA%D1%82%D1%83%D1%80%D0%B0+%D0%B2%D1%8B%D1%81%D0%BE%D0%BA%D0%B8%D1%85+%D0%BD%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BE%D0%BA
Знание Си/Си++/программирования сокетов будет плюсом. но не обязательно. Понимать что такое сокеты и accept/socket_create надо бы, хотя бы на примере PHP и уметь написать клиент к какому-нибудь протоколу.
Знание Node.JS и вебсокетов может быть плюсом.
Понимать HTTP протокол и его особенности, кеширование в HTTP.
Понимать принцип map-reduce.
ООП
Какой-нибудь ООП фреймворк будет плюсом.
Знание event loop библиотек вроде Ratchet и умение писать асинхронные демоны будет плюсом.
https://ru.wikipedia.org/wiki/%D0%A2%D0%B5%D0%BE%D1%80%D0%B5%D0%BC%D0%B0_CAP
>>455280
> и как ты вкатился в него ?
Поработал в компании-разработчике высоконагруженных сайтов. Собственно это самый лучший вариант, только чтобы попасть в такую компанию надо уже иметь какие-то начальные знания. Тебе было бы полезно подучить:
Особенности оптимизации запросов в БД (индексы, EXPLAIN, немного про тюнинг памяти, объемов разных буферов и SHOW ENGINE INNODB STATUS)
http://ruhighload.com/post/%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0+%D1%81+%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D0%B0%D0%BC%D0%B8+%D0%B2+MySQL
http://habrahabr.ru/post/211022/
http://habrahabr.ru/post/31129/
Вот это годная статья: http://habrahabr.ru/company/mailru/blog/206494/
Денормализация данных в Бд ради оптимизации. Горизонтальное и вертикальное масштабирование,
Нужно любить делать тесты, например для проверки как быстрее хранить или искать данные в таблице. Любить пользоваться бенчмарками наподобие ab, siege.
Кеширование и key value кеширующие хранилища: memcahce, redis
http://lib.custis.ru/%D0%9A%D1%8D%D1%88%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B2_%D0%B2%D0%B5%D0%B1-%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F%D1%85_-_%D1%87%D1%82%D0%BE,_%D0%B3%D0%B4%D0%B5,_%D0%BA%D0%BE%D0%B3%D0%B4%D0%B0 (там есть PDF и наверно где-то есть видео но я его не видел)
http://habrahabr.ru/post/42607/
офиц. сайт redis
Командная строка linux (bash, утилиты), простые скрипты,Ю написание cli скриптов на php
Алгоритмы, структуры данных и сложность вроде O(N), O(1). Какова сложность in_array, array_key_exists?
Архитектура нагруженных сервисов, вот набор статей для начала:
http://www.insight-it.ru/highload/
http://ruhighload.com/post/%D0%90%D1%80%D1%85%D0%B8%D1%82%D0%B5%D0%BA%D1%82%D1%83%D1%80%D0%B0+%D0%B2%D1%8B%D1%81%D0%BE%D0%BA%D0%B8%D1%85+%D0%BD%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BE%D0%BA
Знание Си/Си++/программирования сокетов будет плюсом. но не обязательно. Понимать что такое сокеты и accept/socket_create надо бы, хотя бы на примере PHP и уметь написать клиент к какому-нибудь протоколу.
Знание Node.JS и вебсокетов может быть плюсом.
Понимать HTTP протокол и его особенности, кеширование в HTTP.
Понимать принцип map-reduce.
ООП
Какой-нибудь ООП фреймворк будет плюсом.
Знание event loop библиотек вроде Ratchet и умение писать асинхронные демоны будет плюсом.
https://ru.wikipedia.org/wiki/%D0%A2%D0%B5%D0%BE%D1%80%D0%B5%D0%BC%D0%B0_CAP
а, еще надо бы знать Теорему CAP.
> все вакансии содержат обязательный пункт - работа с нагруженными системами и на такие вакансии ессно меня не берут.
Под этим на самом деле может быть лишь требование знать memcahce и уметь написать простейший if для кеширования, если речь конечно не о настоящих hghload сервисах типа баду, топфес и подобных.
>>455281
JS выполняется в браузере а не на сервере.
>>455283
> elseif (($anonSum < $compSum) && ($compSum > $anonSum)) {
А зачем ты условие 2 раза написал, причем второй раз то же самое, но справа налево? Ты думаешь в if обязательно использовать ровно 2 условия? Их может быть любое число.
Нет проверки на ничью.
> Поясните за вторую задачу W4.2, как там рулетку запилить?
генерируешь номер поста, берешь последнюю цифрцу. Если она равна 1, пишешь что-нибудь, если 2 то что-нибудь другое и так далее.
>>455293
Продолжать изучать технологии, чтобы быть лучше других кандидатов.
>>455323
В офисе проще чем на фрилансе скорее всего.
Наверно как минимум надо уметь сделать сайт, может быть знать какую-то CMS или фреймворк. То есть тебе надо освоить HTML/CSS, познакомиться с базами данных, может JS, с созданием страничек, работой с формами, MVC, ООП, может каким-нибудь фреймворком. Ну и правильно советуют, изучи сайты вакансий, brainstorage.me, geekjob, hh.ru
> Created by PhpStorm.
Советую отключить в настройках, ибо комментарий бесполезен и служит только для рекламы. Если ты используешь ситсему вроде git в ней и так хранится кто и когда создал файл.
> array_reverse($screen)
Там достаточно было знак минус перед синусом или косинусом поставить.
В остальном верно.
а, еще надо бы знать Теорему CAP.
> все вакансии содержат обязательный пункт - работа с нагруженными системами и на такие вакансии ессно меня не берут.
Под этим на самом деле может быть лишь требование знать memcahce и уметь написать простейший if для кеширования, если речь конечно не о настоящих hghload сервисах типа баду, топфес и подобных.
>>455281
JS выполняется в браузере а не на сервере.
>>455283
> elseif (($anonSum < $compSum) && ($compSum > $anonSum)) {
А зачем ты условие 2 раза написал, причем второй раз то же самое, но справа налево? Ты думаешь в if обязательно использовать ровно 2 условия? Их может быть любое число.
Нет проверки на ничью.
> Поясните за вторую задачу W4.2, как там рулетку запилить?
генерируешь номер поста, берешь последнюю цифрцу. Если она равна 1, пишешь что-нибудь, если 2 то что-нибудь другое и так далее.
>>455293
Продолжать изучать технологии, чтобы быть лучше других кандидатов.
>>455323
В офисе проще чем на фрилансе скорее всего.
Наверно как минимум надо уметь сделать сайт, может быть знать какую-то CMS или фреймворк. То есть тебе надо освоить HTML/CSS, познакомиться с базами данных, может JS, с созданием страничек, работой с формами, MVC, ООП, может каким-нибудь фреймворком. Ну и правильно советуют, изучи сайты вакансий, brainstorage.me, geekjob, hh.ru
> Created by PhpStorm.
Советую отключить в настройках, ибо комментарий бесполезен и служит только для рекламы. Если ты используешь ситсему вроде git в ней и так хранится кто и когда создал файл.
> array_reverse($screen)
Там достаточно было знак минус перед синусом или косинусом поставить.
В остальном верно.
> еЁ
е входит в диапазон а-я, ее писать отдельно не надо. Только ё.
> [,!?:]
А точка?
> [Жж]ы|[Шш]ы
Можно ж и ш вместе поставить в скобки
> PHP Notice: Use of undefined constant regexp - assumed 'regexp' in /home/kFPkN7/prog.php on line 31
Забыл кавычки или знак доллара
Видит ошибки там где их нет: http://ideone.com/uDs3q9
Задачу про номера телефонов надо проверить на большом числе телефонов, чтобы убедиться что твой код правильный. Но руками подставлять номера — долго и скучно. Пусть работает робот, а не человек!
Для этого давай добавим в программу тесты, чтобы сразу было видно, верно все работает или нет. Сделай 2 списка номеров (правильные и нет), добавь их в программу и напиши цикл, который их по очереди прогоняет через регулярку и проверяет что они определяются как надо (если нет — надо вывести какой именно номер не распознается правильно).
Вот список номеров:
Правильные: array('84951234567', '+74951234567', '8-495-1-234-567', ' 8 (8122) 56-56-56', '8-911-1234567', '8 (911) 12 345 67', '8-911 12 345 67', '8 (911) - 123 - 45 - 67', '+ 7 999 123 4567', '8 ( 999 ) 1234567', '8 999 123 4567');
Неправильные: array('02', '84951234567 позвать люсю', '849512345', '849512345678',
'8 (409) 123-123-123', '7900123467', '5005005001', '8888-8888-88',
'84951a234567', '8495123456a',
'+1 234 5678901', // неверный код страны
'+8 234 5678901', // либо 8 либо +7
'7 234 5678901' // нет +
);
>>455408
> стоит ли учить Reflection,
А что там учить? Прочти мануал и пойми что это и скорее всего хватит.
> Curl
лучше бы знать
> XML
Хорошо бы знать
> PEAR
Сейчас больше composer исопльзуют
> паттерны проектирования
Не имея опыта ты вряд ли их поймешь.
> или лучше сосредоточиться на более важных вещах базах данных, ООП, фреймворки
Это да, более важно
>>455426
Посмотри инспектором на вкладке Elements в разделе Computed. Должно быть 300. Я впрочем и без инспектора вижу что толще чем требуется, и ты тоже бы должен видеть.
>>455431
Погугли что такое lzo для начала, а потом можешь погуглить про то как это сделать на php
>>455436
Скорее нет чем да. Андроид явно левее чем надо, монитор левее, попробуй в фотошопе или просто линейкой (если она у тебя есть; у меня нету) найти середину и провести линии.
Задачу про номера телефонов надо проверить на большом числе телефонов, чтобы убедиться что твой код правильный. Но руками подставлять номера — долго и скучно. Пусть работает робот, а не человек!
Для этого давай добавим в программу тесты, чтобы сразу было видно, верно все работает или нет. Сделай 2 списка номеров (правильные и нет), добавь их в программу и напиши цикл, который их по очереди прогоняет через регулярку и проверяет что они определяются как надо (если нет — надо вывести какой именно номер не распознается правильно).
Вот список номеров:
Правильные: array('84951234567', '+74951234567', '8-495-1-234-567', ' 8 (8122) 56-56-56', '8-911-1234567', '8 (911) 12 345 67', '8-911 12 345 67', '8 (911) - 123 - 45 - 67', '+ 7 999 123 4567', '8 ( 999 ) 1234567', '8 999 123 4567');
Неправильные: array('02', '84951234567 позвать люсю', '849512345', '849512345678',
'8 (409) 123-123-123', '7900123467', '5005005001', '8888-8888-88',
'84951a234567', '8495123456a',
'+1 234 5678901', // неверный код страны
'+8 234 5678901', // либо 8 либо +7
'7 234 5678901' // нет +
);
>>455408
> стоит ли учить Reflection,
А что там учить? Прочти мануал и пойми что это и скорее всего хватит.
> Curl
лучше бы знать
> XML
Хорошо бы знать
> PEAR
Сейчас больше composer исопльзуют
> паттерны проектирования
Не имея опыта ты вряд ли их поймешь.
> или лучше сосредоточиться на более важных вещах базах данных, ООП, фреймворки
Это да, более важно
>>455426
Посмотри инспектором на вкладке Elements в разделе Computed. Должно быть 300. Я впрочем и без инспектора вижу что толще чем требуется, и ты тоже бы должен видеть.
>>455431
Погугли что такое lzo для начала, а потом можешь погуглить про то как это сделать на php
>>455436
Скорее нет чем да. Андроид явно левее чем надо, монитор левее, попробуй в фотошопе или просто линейкой (если она у тебя есть; у меня нету) найти середину и провести линии.
А, анон, мы с тобой забыли еще кое-что. Тестировал ли ты сайт в ИЕ? Если у тебя есть Windows то как минимум одна версия IE установлена и если ты хочешь то можешь поставить остальные в виртуальных машинах (у меня стоят).
Хороший верстальщик разумеется должен делать верстку которая не развалится в этом браузере.
Вот тебе урок в помощь: https://gist.github.com/codedokode/855e3970124687b26a1c
На практике обычно требуется поддержка IE8 и выше, но если тебе захочется заморочиться с IE7 я возражать не буду.
Ну и по пооводу аккуратности верстки. вот смотри, даже в вакансиях пишут:
http://brainstorage.me/jobs/28133
> Аккуратность. Это очень важно. Очень огорчает, когда дизайнер специально остался на ночь исправляя во всех макетах отступы или высоту строки таблиц, отмеряя все пиксель-в-пиксель по сеточке в 8px с педантичной точностью. А технолог просто взял и сделал это на глаз. Вот это никуда не годится...
и еще есть сервис http://www.browserstack.com/screenshots/ для получения скриншотов в разных браузерах, но он коммерческий и я не знаю когда и за что он попросит деньги. Первый раз вроде не просит.
Вот я попробовал твой сайт в ИЕ проверить через него: http://www.browserstack.com/screenshots/837e1e6d7c051a2b2feb1a4a3f5861b8521a91a3
>Посмотри инспектором на вкладке Elements в разделе Computed. Должно быть 300.
Тут вообще 100 стоит.
Спасибо, анончик, добра тебе ^_^
http://www.google.ru/search?sourceid=chrome&ie=UTF-8&q=%D1%82%D0%B5%D1%85%D0%BD%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B5+%D0%B7%D0%B0%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5+site%3Afl.ru+pdf
http://habrahabr.ru/post/253943/
http://habrahabr.ru/post/254141/
fl.ru выдает 403, но ведь у гугла есть схороненная копия, например: http://webcache.googleusercontent.com/search?q=cache:90YDptMbVXYJ:https://st.fl.ru/users/NikitaB/upload/f_030510c4ec31ada1.pdf+%D1%82%D0%B5%D1%85%D0%BD%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B5+%D0%B7%D0%B0%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5+%D0%BF%D0%B0%D1%80%D0%BE%D0%BB%D1%8C+site:fl.ru+pdf&cd=4&hl=ru&ct=clnk&gl=ru
Спасибо большое анон, буду изучать
Как правильно оформить её?
У таблицы есть заголовок, в котором указаны имена столбцов. Как я понимаю помещать эти имена в первые строчки нельзя, так как они могут не соответствовать формату столбца.
Тогда хорошим ли тоном будет называть поля таблицы в mysql русскими словами и как получить эти названия без дополнительного запроса в базу? Который DESCRIBE table;
Не вписывать же мне вручную в html заголовок таблицы?
>Надеюсь, ты извлек из задачи какое-то понимание ООП и умение строить модели предметной области
Определенно извлек. Спасибо тебе большое, ОП!
>Если ты захочешь еще помучать ООП, то у меня есть дополнительная задача написать свой аналог DOM, в которой объектов и классов будет больше, а их связи сложнее. ну или ты можешь решать задачки из оп-поста, про студентов, файлообменнник, они больше не на ООП, а на практические навыки создания сайтов, форм, вывода данных, работы с базой.
Давай я сначала попробую написать задачу про кошек-мышек, потом, с новыми знаниями, переделаю задачу с превьюшками, а потом посмотрим нужна ли мне дополнительная задача.
Далее я хочу глубже изучить html\css и js. У тебя вроде были задачи по ним?
Ну и наконец, я хочу сделать задачу по файлообменнику. И причем сделать его так, чтобы загруженные картинки/аудиозаписи/видеозаписи можно было посмотреть на их странице, чтобы была регистрация где можно было посмотреть какие файлы загрузил пользователь, чтобы был поиск и комментарии.
Может покажется что я многого хочу, но я правда хочу все знать!
Ну и еще хочется спросить у тебя, нравиться ли тебе учиться меня? В смысле нету каких-нибудь раздражающих моментов? Может мне что-нибудь подучить надо где-то? В общем говори все что хочется сказать.
Спасибо.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [L]
Если ходить по ссылкам типа localhost/мvc/abrakadabra перенаправляет нормально. Но на втором и больше уровнях вложенности типа localhost/мvc/abrakadabra/qwerty перенаправляет на индекс в котором не подключаются картинки и css. Норм нагуглить проблему не могу, кто советует абсолютные пути использовать, кто дописывать правила где перечисляются все подтипы файлов которые нужно подключать. Оба способа мне бредом кажутся.
Как совладать с этим безумием? Структура папок пикрел.
>Как правильно оформить её?
С помощью HTML тегов table.
>Тогда хорошим ли тоном будет называть поля таблицы в mysql русскими словами
Определённо плохим
>и как получить эти названия без дополнительного запроса в базу?
Создай массив с именами и выводи в цикле.
Рассматривай таблицу в базе, её обработку на клиенте и вывод таблицы как отдельные сущности и работай с ними, а ты пытаешься перенести таблицу из базы в таком же виде в браузер, таблица это просто хранилище
Основы в некоторой степени я освоил, просто думаю что дальше лучше делать, укреплять свои знания в основах, что бы научится хорошо и правильно писать код или же переходить на подобное тому что я написал.
Ну я собственно сначала делаю селект всего из таблицы. Получаю массив двумерный. Далее делаю describe table, что бы получить заголовки.
Потом начинаю строить <table> с помощью этих двух массивов. Сначала в th идут заголовки. А потом двумя циклами идет построение <tr> <td>
И получается няшная табличка в браузере. Все правильно делаю?
> Далее делаю describe table, что бы получить заголовки.
Дались тебе эти заголовки, просто создай массив с именами столбцов и используй его для красивых имен.
Иформация в талице об именах столбцов меняется очень редко, если вобще меняется,
зачем ее каждый раз выбирать. Задай массив с ключами имён столбцов и значениями на русском и используй
Попытался решить получилось пока вот так:
function fmap(a, gen) {
return function () {
return a(gen(arguments[0],arguments[1]));
}
}
Ну вот сделал index.html с выводом зарегистрированных абитуриентов, добавить кнопки: регистрация, правка данных и главная, добавить. Прикрепить коннект к дб, а где ООП использовать?
В уроке вроде написано. ООП всезде с используется, в отображении данных, в работе с базой данных (Data Mapper)
начни с дб. вместо обычного процедурного винегрета пиши свой класс-обертку вроде class DB {} с методами доступа, удаления и т.д. Должно работать как-то так:
$db = new DB();
$db -> getStudent('1'); //выбрать студента с ид =1
$db -> addStudent('Вася', 'Петров', 'Кт-213'); //добавить студента с таким-то именем в такую-то группу
Еще лучше без привязки к студентам, а просто $db -> add ($таблица, array $поля_для_вставки, array $значения_для_вставки)
Спасибо, полезный ответ.
>лучше без привязки к студентам, а просто $db -> add ($таблица, array $поля_для_вставки, array $значения_для_вставки)
именно так и надо делать. Ты получишь универсальный класс для вставки чего угодно куда угодно - студентов в группы, статей в блоги, товаров в ассортимент магазина, писюнов в чужих мамок, даже аллаха в небо.
Методы типа addStudent должны принадлежать другому классу.
Мухосранск 550к, позвонили по резюме (сам студент 2 курс), сказали нужен человек пишущий модули для сайтов. Ну думаю не помешает попробовать, как раз практика в cms-ках будет. Короче, мужик дал тз, я единственный кто сделал из толпы приходивших, думаю, ну збс будет. А хуй там. Первый заказ - исправить добавление инфы из 25-и полей, сверстать саму форму добавления + сделать выборку городов/етс через ajax. Короче, сделал всё красиво, всё збс, при том, что пришлось править кучу говно кода который писал САМ этот мужик (начальник компании, у него образование ПОГРОМИСТА). Это был пиздец. Нужно было еще запилить вывод некоторой инфы из заполнения этого документа в личный кабинет и сформировать лицевой счет уникальный. Сложность заключалась как раз в том, что пришлось переписывать кучу им написанного говна, когда как он пару раз говорил ДА ТАМ УЖЕ ВСЁ ГОТОВО ОСТАЛОСЬ ПОДПРАВИТЬ. Уже когда я всё закончил (за 1.5 дня), тут щас будет моя большая ошибка: только тогда поговорили об оплате, сошлись на 2к. Теперь бинго -- мужик каждый день ищет, видимо, к чему придраться. Вчера сказал "заметил кучу косяков, потом скажу какие щас на встрече" и это уже продолжается сутки. Короче, я так понял он либо даун, либо решил меня кинуть (у меня пароль к бд и ftp доступ). Но тогда странно что он не поменял пароли и не съебал.
Короче, я вернул все файлы назад (которые были до моей правки) и написал, что я всё вернул, и если он хочет продолжать работать (я почти уверен, что работать с таким говном за еду согласится только студент типа меня, а у нас студенты далеко не все чето могут), то пока не получу 100% оплату - возвращать ничего не буду и сотрудничать мы прекращаем.
Всё правильно сделал или нет? Алсо, первый опыт общения с ЗАКАЗЧИКОМ.
Правильно. А сотрудничать я бы с ним дальше по-любому не стал - хоть заплатит, хоть нет.
лол, ответил "раз я не отвечаю, значит у меня нет времени, и если будешь диктовать мне условия то дальше нам не по пути.. готов ли ты работать сейчас с меньшей отдачей ради большей в будущем?"
При том, что был уговор - есть тз, выполняю задание - получаю оплату. Короче, идет нахуй. Пиздец.
как не попадать на таких, братки? первый заказчик и сразу такая хуйня.
Бери 50% предоплаты.
>456026\t
два раза напомнил. какой смысл, думаешь, он сам этого не помнит? лол. щас пишет, что у меня там была какая-то мелкая ошибка (не в то поле записывалось значение). ОХУЕТЬ. На фоне всего что я сделал, он пишет "за невнимательность и работу в 5 минут надо подумать сколько платить". При бюджете в обоссаные 2к. Короче заменил все файлы которые правил старыми и вежливо послал нахуй. Вконце написал "жду в понедельник в офисе и надеюсь на большее уважение к работодателю". При том что работаю я не официально, у нас есть только тз и оплата. ЛОЛ.
>если будешь диктовать мне условия то дальше нам не по пути
>большее уважение к работодателю
Таких сразу надо нахуй слать, сириусли. Аж пригорело. Можешь ему в ответ написать про уважение к работнику, а то как-то не за что его уважать.
да я написал про его отношение, и сделал акцент на говнокод, в котором он будет разбираться месяц в лучшем случае. Тоже пригорело, да. Типа если мне 19 лет а ему 30+, значит я должен его уважать и терпеть все "хотелки" за 2к рублей, лол блять. Короче впизду, даже как-то плохо на душе стало. Хотел подработать на каких-то реальных задачах связанных с пыхой, но теперь буду учить какой-нить фреймворк как и хотел (начну с codeigniter) и потихоньку качать скилл, как и было до нахождения этой РАБОТЫ. Эх.
Лучше yii и перекатывайся в рельсы потом. Или, если не хочешь перекатываться, laravel.
Не учи Codeigniter. Там код из времен PHP4 и php5.2 которое на новых версиях php сыплет кучей варнингов. Кроме ООП там еще куча глобальных функций, ну и архитектура дурацкая, какие-то $this->load->something везде, антипаттерн на антипаттерне. Не веришь - посмотри исходники.
Лучше брать Yii2 и Symfony 2.
CodeIgniter неплохой фреймворк для небольших проектов. Всё что надо там есть: mvc, роутинг, ar, система конфигов, небольшой набор нужных хелперов и библиотек. Начинать с него - норм, так как фреймворк ничего лишнего не навязывает.
Насчёт антипаттернов, yii1/2 - образец быдлоархитектуры, всюду сервис локаторы, статический контекст, хрупкие абстракции на наследовании и глобальное состояние. Симфони = вместо написания кода - написание конфигов.
>>456036
Сейчас действительно в моде микрофреймворки, но лучше возьми что-то посовременнее, типа Slim или Silex.
http://srs.myrusakov.ru/freephp
>>456018
>>456029
Советую и поясняю для других анонов про выстраивание отношений с заказчиком.
Прежде всего, есть вещи, которые делать не стоит в любом случае, так как это неконструктивно и не дает вам выгоды:
- говорить кому-то что он быдлокодер/пишет плохой код/в проекте плохой код и надо все переписать
- разговаривать на повышенных тонах/угрожать/выяснять отношения/ставить условия
- заниматься вредительством/установкой бекдоров (это может быть наказуемо по УК)
Подробнее.
Почему никогда не стоит жаловаться на быдлокод? Потому что это не дает никакой выгоды. Человек от того, что вы его назовете быдлокодером, к вам относиться лучше не станет. Менеджер/владелец проекта, которому вы расскажете про то какой там плохой код и почему его надо переписать, тоже вас не поймет так как этот код уже приносит деньги и от того что вы его перепишете он денег приносить больше не станет (подробнее у Джоэла Споэльски, он работал в майкрсофте и вообще очень умный: http://habrahabr.ru/post/219651/ )
Я вообще плохо отношусь к чужому коду. Большинство программистов неквалифицированны, пишут ужасный код, не знают многих вещей, неучи одним словом. Но что я выиграю если скажу им это?
Вас как профессионала нанимают чтобы решить задачу. Вам не нравится код? Прекрасно, не беритесь за эту задачу. А если взялись, то не жалуйтесь, это ваша работа.
Если бы не надо было работать с плохим кодом, незачем было бы вас нанимать - проще было бы позвать студентов-хаскеллистов за тарелку борща. В общем, перед тем как браться за задачу, посмотрите код и решайте, хотите вы с ним возиться или нет.
Для меня предложение вместо решения задачи «тут надо все переписать сначала» признак непрофессионализма.
Теперь обсудим принципы оплаты. Бывают разные подходы:
- фиксированная сумма. Она выгодна прежде всего заказчику, так как страхует его от лишних расходов. С другой стороны, исполнитель в невыгодном положении: он либо вынужден работать за бесплатно если не успел сделать все вовремя, либо не доделывает работу или делает ее некачественно в надежде что заказчик не заметит (я сам так не поступал).
Эта схема опасна для исполнителя тем, что он может неточно оценить свои затраты времени и в итоге получить меньшую часовую ставку чем он рассчитывал. По ней можно делать только маленькие заказы.
Есть еще разновидность такой же схемы, но с поэтапной оплатой.
- повременная оплата. Заказчик оплачивает затраченное на разработку время по заранее согласованной часовой ставке. Эта схема позволяет исполнителю сделать все тщательно и не спешить, не боясь остаться без денег. Обычно при такой схеме заказчик настаивает на использовании какой-то программы для контроля затраченного времени (кстати, мне повезло работать без этого).
Также, бывает вариант удаленной работы за фиксированную сумму в месяц, который тоже можно отнести к этой категории.
Теперь по поводу правок и доработок. Я придерживаюсь такого принципа: если я где-то сделал ошибку или что-то пропустил (при работе по фиксированной стоимости), то я ее исправляю бесплатно, если нужны доработки, то предлагаю их сделать после выполнения задачи за отдельные деньги.
Теперь попробую прокомментировать:
> при том, что пришлось править кучу говно кода который писал САМ этот мужик
> Сложность заключалась как раз в том, что пришлось переписывать кучу им написанного говна
Это твоя работа, не нравится — не берись.
> Вчера сказал "заметил кучу косяков, потом скажу какие щас на встрече" и это уже продолжается сутки
Это уже другой вопрос. Ты можешь пока убрать свой код и ничего не делать. Может там действительно есть ошибки. Сутки на мой взгляд немного если человек занят.
Ситуация, как я понимаю, такая:
— у тебя есть потраченное время и код, но нет денег
— у него деньги и возможно потраченное время (а может эта задача не срочная и он ничего не теряет). Если он тебя кинет, ты скорее всего напишешь про него на всех местных форумах и ему трудно будет найти другого программиста.
Тут ты явно не в выигрыше. Если он не спешит, он вообще может просто дать эту задачу кому-то еще. С другой стороны, может ему все же нужен этот код и других свободных программистов у вас в городе немного.
> и если он хочет продолжать работать (я почти уверен, что работать с таким говном за еду согласится только студент типа меня, а у нас студенты далеко не все чето могут), то пока не получу 100% оплату - возвращать ничего не буду и сотрудничать мы прекращаем.
Лучше было прекратить работу, но условий пока не ставить. Ведь может быть там действительно есть ошибки, платить за неработающий код вряд ли хочется.
И я советую не переводить общение в негативное русло. Тебе это ничего не дает, тем более что ты тут в проигрышной ситуации. Не надо ставить условия, надо просто сказать: если в моей работе есть какие-то ошибки, давайте мне список, я с удовольствием их исправлю. А на предложение доработок говорить: «да, конечно, я рад буду это сделать, давайте подробнее обсудим это после того, как я доделаю задачу. Сейчас я не готов на это отвлекаться/это удобнее сделать потом.»
Сотрудничество с исполнителем-истеричкой, который ведет разговор в стиле «если ты хочешь продолжать со мной работать...» нормальный заказчик продолжать не станет.
В общем, если ты хочешь отказать в чем-то заказчику, не надо делать это в негативном ключе. Делай конструктивные предложения, которые позволяют двигаться вперед, а не портят отношения.
Пока, как я понял из твоего рассказа, никаких лишних доработок ты не делал, может ему действительно пока некогда было проверить твою работу и потому он ее пока не принял. Сутки это немного.
Кстати, можно выкладывать код для демонстрации на свой сервер, а не на его, если ты не доверяешь заказчику, если у тебя есть сервер/хостинг и ты можешь там развернуть копию проекта.
Моя интуиция подсказывает, что «кидать» разработчика, который хорошо сделал свою работу и недорого за это взял, довольно глупо, так как работает это только один раз, тем более что после этого будет куча негативных отзывов. Ты также можешь погулить ники/контакты заказчика в интернете, нет ли про него плохих отзывов (и это конечно стоило сделать до того как брать заказ).
В общем предлагаю, если ты наговорил ему претензий про код, признать что ты был неправ, и дождаться замечаний. Опять же, если там будет то, о чем заранее не договаривались, спокойно объясни что это отдельная доработка.
> Всё правильно сделал или нет
Думаю, ты наделал кучу ошибок в общении.
> и если будешь диктовать мне условия то дальше нам не по пути
Тут он прав
> готов ли ты работать сейчас с меньшей отдачей ради большей в будущем?"
Ответь что сначала предпочел бы закрыть задачу, а потом обсуждать это. Это слова которые ничего в принципе не значат так как не содержат конкретных сумм.
> что у меня там была какая-то мелкая ошибка (не в то поле записывалось значение)
Справедливая претензия. Если ты заплатишь исполнителю до исправления ошибок, он может их и не исправить.
>>456019
Гуглить отзывы, рейтинг на фрилансе смотреть, может быть безопасная сделка.
>>456018
>>456029
Советую и поясняю для других анонов про выстраивание отношений с заказчиком.
Прежде всего, есть вещи, которые делать не стоит в любом случае, так как это неконструктивно и не дает вам выгоды:
- говорить кому-то что он быдлокодер/пишет плохой код/в проекте плохой код и надо все переписать
- разговаривать на повышенных тонах/угрожать/выяснять отношения/ставить условия
- заниматься вредительством/установкой бекдоров (это может быть наказуемо по УК)
Подробнее.
Почему никогда не стоит жаловаться на быдлокод? Потому что это не дает никакой выгоды. Человек от того, что вы его назовете быдлокодером, к вам относиться лучше не станет. Менеджер/владелец проекта, которому вы расскажете про то какой там плохой код и почему его надо переписать, тоже вас не поймет так как этот код уже приносит деньги и от того что вы его перепишете он денег приносить больше не станет (подробнее у Джоэла Споэльски, он работал в майкрсофте и вообще очень умный: http://habrahabr.ru/post/219651/ )
Я вообще плохо отношусь к чужому коду. Большинство программистов неквалифицированны, пишут ужасный код, не знают многих вещей, неучи одним словом. Но что я выиграю если скажу им это?
Вас как профессионала нанимают чтобы решить задачу. Вам не нравится код? Прекрасно, не беритесь за эту задачу. А если взялись, то не жалуйтесь, это ваша работа.
Если бы не надо было работать с плохим кодом, незачем было бы вас нанимать - проще было бы позвать студентов-хаскеллистов за тарелку борща. В общем, перед тем как браться за задачу, посмотрите код и решайте, хотите вы с ним возиться или нет.
Для меня предложение вместо решения задачи «тут надо все переписать сначала» признак непрофессионализма.
Теперь обсудим принципы оплаты. Бывают разные подходы:
- фиксированная сумма. Она выгодна прежде всего заказчику, так как страхует его от лишних расходов. С другой стороны, исполнитель в невыгодном положении: он либо вынужден работать за бесплатно если не успел сделать все вовремя, либо не доделывает работу или делает ее некачественно в надежде что заказчик не заметит (я сам так не поступал).
Эта схема опасна для исполнителя тем, что он может неточно оценить свои затраты времени и в итоге получить меньшую часовую ставку чем он рассчитывал. По ней можно делать только маленькие заказы.
Есть еще разновидность такой же схемы, но с поэтапной оплатой.
- повременная оплата. Заказчик оплачивает затраченное на разработку время по заранее согласованной часовой ставке. Эта схема позволяет исполнителю сделать все тщательно и не спешить, не боясь остаться без денег. Обычно при такой схеме заказчик настаивает на использовании какой-то программы для контроля затраченного времени (кстати, мне повезло работать без этого).
Также, бывает вариант удаленной работы за фиксированную сумму в месяц, который тоже можно отнести к этой категории.
Теперь по поводу правок и доработок. Я придерживаюсь такого принципа: если я где-то сделал ошибку или что-то пропустил (при работе по фиксированной стоимости), то я ее исправляю бесплатно, если нужны доработки, то предлагаю их сделать после выполнения задачи за отдельные деньги.
Теперь попробую прокомментировать:
> при том, что пришлось править кучу говно кода который писал САМ этот мужик
> Сложность заключалась как раз в том, что пришлось переписывать кучу им написанного говна
Это твоя работа, не нравится — не берись.
> Вчера сказал "заметил кучу косяков, потом скажу какие щас на встрече" и это уже продолжается сутки
Это уже другой вопрос. Ты можешь пока убрать свой код и ничего не делать. Может там действительно есть ошибки. Сутки на мой взгляд немного если человек занят.
Ситуация, как я понимаю, такая:
— у тебя есть потраченное время и код, но нет денег
— у него деньги и возможно потраченное время (а может эта задача не срочная и он ничего не теряет). Если он тебя кинет, ты скорее всего напишешь про него на всех местных форумах и ему трудно будет найти другого программиста.
Тут ты явно не в выигрыше. Если он не спешит, он вообще может просто дать эту задачу кому-то еще. С другой стороны, может ему все же нужен этот код и других свободных программистов у вас в городе немного.
> и если он хочет продолжать работать (я почти уверен, что работать с таким говном за еду согласится только студент типа меня, а у нас студенты далеко не все чето могут), то пока не получу 100% оплату - возвращать ничего не буду и сотрудничать мы прекращаем.
Лучше было прекратить работу, но условий пока не ставить. Ведь может быть там действительно есть ошибки, платить за неработающий код вряд ли хочется.
И я советую не переводить общение в негативное русло. Тебе это ничего не дает, тем более что ты тут в проигрышной ситуации. Не надо ставить условия, надо просто сказать: если в моей работе есть какие-то ошибки, давайте мне список, я с удовольствием их исправлю. А на предложение доработок говорить: «да, конечно, я рад буду это сделать, давайте подробнее обсудим это после того, как я доделаю задачу. Сейчас я не готов на это отвлекаться/это удобнее сделать потом.»
Сотрудничество с исполнителем-истеричкой, который ведет разговор в стиле «если ты хочешь продолжать со мной работать...» нормальный заказчик продолжать не станет.
В общем, если ты хочешь отказать в чем-то заказчику, не надо делать это в негативном ключе. Делай конструктивные предложения, которые позволяют двигаться вперед, а не портят отношения.
Пока, как я понял из твоего рассказа, никаких лишних доработок ты не делал, может ему действительно пока некогда было проверить твою работу и потому он ее пока не принял. Сутки это немного.
Кстати, можно выкладывать код для демонстрации на свой сервер, а не на его, если ты не доверяешь заказчику, если у тебя есть сервер/хостинг и ты можешь там развернуть копию проекта.
Моя интуиция подсказывает, что «кидать» разработчика, который хорошо сделал свою работу и недорого за это взял, довольно глупо, так как работает это только один раз, тем более что после этого будет куча негативных отзывов. Ты также можешь погулить ники/контакты заказчика в интернете, нет ли про него плохих отзывов (и это конечно стоило сделать до того как брать заказ).
В общем предлагаю, если ты наговорил ему претензий про код, признать что ты был неправ, и дождаться замечаний. Опять же, если там будет то, о чем заранее не договаривались, спокойно объясни что это отдельная доработка.
> Всё правильно сделал или нет
Думаю, ты наделал кучу ошибок в общении.
> и если будешь диктовать мне условия то дальше нам не по пути
Тут он прав
> готов ли ты работать сейчас с меньшей отдачей ради большей в будущем?"
Ответь что сначала предпочел бы закрыть задачу, а потом обсуждать это. Это слова которые ничего в принципе не значат так как не содержат конкретных сумм.
> что у меня там была какая-то мелкая ошибка (не в то поле записывалось значение)
Справедливая претензия. Если ты заплатишь исполнителю до исправления ошибок, он может их и не исправить.
>>456019
Гуглить отзывы, рейтинг на фрилансе смотреть, может быть безопасная сделка.
А так, я тебя конечно понимаю, я сам сталкивался с экономившими на всем и торговавшимися за копейки заказчиками. Но если взялся за работу, то должен сделать. Условия обговаривать надо до, а не во время или после. А потом пусть они ищут желающих с ними сотрудничать.
>>456032
> Можешь ему в ответ написать про уважение к работнику, а то как-то не за что его уважать.
Это не конструктивное предложение. Твоя цель деньги за работу получить или выяснить кто кого уважает?
>>456036
> и сделал акцент на говнокод, в котором он будет разбираться месяц в лучшем случае.
Это непрофессионально. Вообще вести разговор в стиле «если ты не согласен на мои условия то» непрофессионально.
> Типа если мне 19 лет а ему 30+, значит я должен его уважать и терпеть все "хотелки" за 2к рублей
Ты сам на эту сумму согласился, чем ты недоволен? Даже если ты согласился за бесплатно сделать работу, это не повод менять условия на полпути. Мне это напоминает фильм, по моему «трасса 60», где человек сначала говорил что согласен работать за еду, а потом начал предъявлять претензии.
Насчет уважения, конечно, исполнитель и заказчик должны разговаривать друг с другом с уважением, как иначе? Зачем сотрудничать с тем кто тебя не уважает?
Codeigniter застрял в прошлом и компания-разработчик, как я помню, давно сама его забросила. так что неясно то ли ты неудачно троллишь то ли не понимаешь что к чему.
> всюду сервис локаторы
$this->load
> статический контекст,
get_instance
> хрупкие абстракции на наследовании
Я подозреваю ты просто плохо знаешь ООП
> глобальное состояние.
get_instance
> Сейчас действительно в моде микрофреймворки,
микрофреймворки только для микросайтов
Это плохая идея так как ты скатываешься в массив-ориентированое программирование. У тебя в программе будет огромное число массивов разных видов и ты сам забудешь какие в каком поля. ООП не для этого придуман, чтобы таскать туда-сюда массивы. Надо использовать паттерны вроде ActiveRecord или DataMapper описанные в уроке (придумал их конечно не я, а Фаулер): https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md
В случае использования этих паттернов работа с одной таблицей инкапсулирована в отдельном классе, в твоем случае нет и вообще это мало на ООП похоже.
http://ideone.com/yNRQ1M
newb-кун
Печально, что у самого композера 464 issues и всего два разработчика.
Тут загвоздка в том что разные проекты могут использовать разные версии библиотек (зафиксированные в .lock файлах). Потому папку vendor делают именно в проекте.
phpunit кстати можно скачать в виде phar файла.
Также есть команда global которая может быть поможет https://getcomposer.org/doc/03-cli.md#global
>> Можешь ему в ответ написать про уважение к работнику, а то как-то не за что его уважать.
>Это не конструктивное предложение. Твоя цель деньги за работу получить или выяснить кто кого уважает?
Его цель уже никакая из этих. А конструктивно ли вести такие разговоры с исполнителем? У тебя же классическое "клиент всегда прав" - стратегия опущенцев в сфере IT. Здесь клиент, как правило, нихуя не шарит и ему нужно дать решение. А если он при этом начинает делать вид, что его не наебешь, и создавать на ровном месте проблемы - это уже однозначно к врачу.
http://ideone.com/bmNjaJ
Все правильно, молодец.
$this->id = "262"
но если делаю
empty($this->id)
выводит true
Почему оно empty, хотя оно совсем не empty?
Мануал читал, не помогло.
а что значит .BR ?
http://rutracker.org/forum/viewtopic.php?t=4858506
http://www.xiper.net/examples/html-and-css-tricks/css/twitching-site.html
Верстка уебищно скачет на ширину скролла по причине margin:auto для центрирования блока с контентом. И что же вы думали, существует человеческое решение проблемы? Нет, "добавьте скролл через overflow-y: scroll в body и скакать не будет". Ну да, тока при этом полоска скролла будет торчать везде и когда она не нужна тоже. Или центрируйте блок по-другому. Таблицами не модно, заморочился с флексбоксами. Стоп, ИЕ <11 не поддерживает. Давай, чисти-чисти вилкой.
Может кто-нибудь объяснит зачем на js вот такая еботня вообще нужна? Надеюсь эти задачи писались с целью поразмять мозги, а не научить кого-либо яваскрипту с помощью этого пиздеца.
>ваша функция должна возвращать функцию
Покайтесь блять.
Сажа отклеилась
Нет, циклы — это уровень архитектора. Обычным ребятам-программистам они не нужны.
Не знаю, не вводил. Вангую, вечным потенциальным клиентом станешь.
>>456481
Будешь получать интересные рекламные предложения наверно.
>>456459
Баг где-то, бывает
>>456414
Ты ошибаешься. Достаточно набрать php iis в гугле чтобы найти
http://php.net/manual/ru/install.windows.iis7.php
http://habrahabr.ru/post/30154/
FastCGI с CGI общего имеет только название, это совсем другая вещь.
Ну и конечно не очень понятно что такого хорошего в IIS и Windows чтобы их исплоьзовать для сервера.
>>456405
Плохо ищешь так как 2 ссылки выше идут первыми по запросу php iis
>>456481
Будешь получать интересные рекламные предложения наверно.
>>456459
Баг где-то, бывает
>>456414
Ты ошибаешься. Достаточно набрать php iis в гугле чтобы найти
http://php.net/manual/ru/install.windows.iis7.php
http://habrahabr.ru/post/30154/
FastCGI с CGI общего имеет только название, это совсем другая вещь.
Ну и конечно не очень понятно что такого хорошего в IIS и Windows чтобы их исплоьзовать для сервера.
>>456405
Плохо ищешь так как 2 ссылки выше идут первыми по запросу php iis
> вообще нужна? Надеюсь эти задачи писались с целью поразмять мозги, а не научить кого-либо яваскрипту
Эти задачи проверяют, понял ли ты как писать код на яваскрипте и знаешь ли ты его. Если ты знаешь JS то решение не займет у тебя много времени, если не знаешь то разумется ты их не решишь. Решение задач помогает увидеть, какие темы человек знает плохо, и исправить пробелы в знаниях.
На мой взгляд, это прекрасный набор задач, на голову выше чем примитивные задачки с других сайтов и учебников которые дают гораздо меньше знаний.
Тут ты конечно мог бы спросить, зачем знать яваскрипт? Это язык, который выполняется на страницах в браузере, который очень активно сейчас используется, на нем даже приложения пишут, он запускается на сервере (node.js), ну и практически от любого верстальщика требуют его знание.
>>ваша функция должна возвращать функцию
>Покайтесь блять.
Что, так сложно? А другие аноны справляются.
>>456336
Ололо, вот так новость. Я еще 5 лет назад знал что CSS плохо подходит для верстки сложных интерфейсов и лейаутов, и делался для оформления текстов из нескольких абзацев с заголовками, вот ты меня удивил.
> Верстка уебищно скачет на ширину скролла по причине margin:auto для центрирования блока с контентом
В моем браузере контент на этой странице прижат влево и никуда не скачет. На мой взгляд проблемы как таковой нет, я пользуюсь интернетом каждый день и не замечал этой проблемы (хотя от заказчиков слышал такие претензии и испралял через overflow, раз заказчик просит почему бы и не сделать). Я читаю Хабр, Роем, Geektimes, Reddit, News.Ycombinator и мне наличие/остстусвие скролла никак не мешает пользоваться этими сайтами.
Если тебе интересно, что меня раздражает, то меня раздражает загрузка страниц дольше чем одна секунда (мануал php например после редизайна медленно грузится из-за мегабайта шрифтов) и неплавный скроллинг/анимации, если там меньше 60 fps.Вообще, любые лаги и задержки раздражают.
Неужели нельзя просто сделать черный текст на белом фоне как на этом прекрасном сайте? https://news.ycombinator.com/
Нет, неграмотные дебилы обязательно хотят нагородить новомодных технологий и SVG анимаций от которых все еле ползает, а контент еще надо найти среди оформления. И конечно надо подложить на фон видео, что за сайт без видео в шапке.
> И что же вы думали, существует человеческое решение проблемы?
А как по твоему она должна решаться?
В принципе на маках и мобильных устройствах линейка прокрутки накладывается сверху и там этой проблемы нет (и скорее всего эта мода перейдет на остальные платформы со временем), но мне например больше нравятся старомодные линейки прокрутки, я бы их еще раза в полтора шире сделал. Линейку прокрутки делают сейчас скрывающейся так как ей никто все равно не пользуется, у всех устройств есть либо мышь с колесом либо тач интерфейс.
> Таблицами не модно,
У тебя цель решить задачу или использовать то о чем ты прочел вчера на хабре?
> Или центрируйте блок по-другому. Таблицами не модно, заморочился с флексбоксами.
Я не понимаю как тебе флексбоксы помогут изменить факт что полоска прокрутки занимает часть ширины страницы. По моему ты решаешь несуществующую пробелму и исплоьзуешь технологии не потому что она лучше подходит, а потому что вчера про нее написали на хабре?
> Стоп, ИЕ <11 не поддерживает.
Значит это экспериментальная технология которая не должна пока использовать на практике.
Если от тебя не требует этого заказчик, я советую забить на эту проблему. Если требует то поставить overflow. Ну и у CSS конечно есть проблемы, но не те о которых ты пишешь (реальная проблема: вертикальное центрирование, прижать блок неизвестной высоты к низу окна и тд., в CSS с автоматическим определением высоты действительно все плохо).
> вообще нужна? Надеюсь эти задачи писались с целью поразмять мозги, а не научить кого-либо яваскрипту
Эти задачи проверяют, понял ли ты как писать код на яваскрипте и знаешь ли ты его. Если ты знаешь JS то решение не займет у тебя много времени, если не знаешь то разумется ты их не решишь. Решение задач помогает увидеть, какие темы человек знает плохо, и исправить пробелы в знаниях.
На мой взгляд, это прекрасный набор задач, на голову выше чем примитивные задачки с других сайтов и учебников которые дают гораздо меньше знаний.
Тут ты конечно мог бы спросить, зачем знать яваскрипт? Это язык, который выполняется на страницах в браузере, который очень активно сейчас используется, на нем даже приложения пишут, он запускается на сервере (node.js), ну и практически от любого верстальщика требуют его знание.
>>ваша функция должна возвращать функцию
>Покайтесь блять.
Что, так сложно? А другие аноны справляются.
>>456336
Ололо, вот так новость. Я еще 5 лет назад знал что CSS плохо подходит для верстки сложных интерфейсов и лейаутов, и делался для оформления текстов из нескольких абзацев с заголовками, вот ты меня удивил.
> Верстка уебищно скачет на ширину скролла по причине margin:auto для центрирования блока с контентом
В моем браузере контент на этой странице прижат влево и никуда не скачет. На мой взгляд проблемы как таковой нет, я пользуюсь интернетом каждый день и не замечал этой проблемы (хотя от заказчиков слышал такие претензии и испралял через overflow, раз заказчик просит почему бы и не сделать). Я читаю Хабр, Роем, Geektimes, Reddit, News.Ycombinator и мне наличие/остстусвие скролла никак не мешает пользоваться этими сайтами.
Если тебе интересно, что меня раздражает, то меня раздражает загрузка страниц дольше чем одна секунда (мануал php например после редизайна медленно грузится из-за мегабайта шрифтов) и неплавный скроллинг/анимации, если там меньше 60 fps.Вообще, любые лаги и задержки раздражают.
Неужели нельзя просто сделать черный текст на белом фоне как на этом прекрасном сайте? https://news.ycombinator.com/
Нет, неграмотные дебилы обязательно хотят нагородить новомодных технологий и SVG анимаций от которых все еле ползает, а контент еще надо найти среди оформления. И конечно надо подложить на фон видео, что за сайт без видео в шапке.
> И что же вы думали, существует человеческое решение проблемы?
А как по твоему она должна решаться?
В принципе на маках и мобильных устройствах линейка прокрутки накладывается сверху и там этой проблемы нет (и скорее всего эта мода перейдет на остальные платформы со временем), но мне например больше нравятся старомодные линейки прокрутки, я бы их еще раза в полтора шире сделал. Линейку прокрутки делают сейчас скрывающейся так как ей никто все равно не пользуется, у всех устройств есть либо мышь с колесом либо тач интерфейс.
> Таблицами не модно,
У тебя цель решить задачу или использовать то о чем ты прочел вчера на хабре?
> Или центрируйте блок по-другому. Таблицами не модно, заморочился с флексбоксами.
Я не понимаю как тебе флексбоксы помогут изменить факт что полоска прокрутки занимает часть ширины страницы. По моему ты решаешь несуществующую пробелму и исплоьзуешь технологии не потому что она лучше подходит, а потому что вчера про нее написали на хабре?
> Стоп, ИЕ <11 не поддерживает.
Значит это экспериментальная технология которая не должна пока использовать на практике.
Если от тебя не требует этого заказчик, я советую забить на эту проблему. Если требует то поставить overflow. Ну и у CSS конечно есть проблемы, но не те о которых ты пишешь (реальная проблема: вертикальное центрирование, прижать блок неизвестной высоты к низу окна и тд., в CSS с автоматическим определением высоты действительно все плохо).
В чем смысл таких книг с рецептами? Если ты знаешь php ты сам легко это напишешь, если не знаешь то не поймешь.
>>456216
Как работает empty?
1) проверяет если ли у объекта свойство id (вызвается __isset)
2) проверяет пустое ли у него знаечние (вызывается __get)
Иди внимательно мануал перечитывай: http://php.net/manual/ru/language.oop5.overloading.php
Ну и я не понимаю чем $this->properties['id'] лучше чем this->id. Ты массиво ориентированным программированием видимо увлекаешься.
Код ужасный конечно, все в кучу смешано, и куки, и массивы, и какие-то объекты.
>>456230
__isset не хватает
>>456216
Плохо читал, почитай про __isset
>>456203
Все хорошо, только exit не нужен.
>>456163
Решай дальше.
>>456162
В виде объекта хранящего список находящихся на нем животных например. мы же в мире ООП.
>>456155
> . Здесь клиент, как правило, нихуя не шарит и ему нужно дать решение.
Это не повод вести себя непрофессионально
> А если он при этом начинает делать вид, что его не наебешь, и создавать на ровном месте проблемы
Не работай с ним или найми менеджера который умеет общаться с людьми.
>>456138
> $wordFrom1 = $word1[mt_rand(1,$array1Count)];
тут наверно с array_rand короче получится.
также ошибка, ты думаешь в массиве индексы начинаются с 1 а они начинаются с 0. У тебя первое слово (с индексом 0) никогда не выпадет.
Тут идут ошибки из-за этого же : http://ideone.com/qgt2jw
В остальном хорошо.
Код ужасный конечно, все в кучу смешано, и куки, и массивы, и какие-то объекты.
>>456230
__isset не хватает
>>456216
Плохо читал, почитай про __isset
>>456203
Все хорошо, только exit не нужен.
>>456163
Решай дальше.
>>456162
В виде объекта хранящего список находящихся на нем животных например. мы же в мире ООП.
>>456155
> . Здесь клиент, как правило, нихуя не шарит и ему нужно дать решение.
Это не повод вести себя непрофессионально
> А если он при этом начинает делать вид, что его не наебешь, и создавать на ровном месте проблемы
Не работай с ним или найми менеджера который умеет общаться с людьми.
>>456138
> $wordFrom1 = $word1[mt_rand(1,$array1Count)];
тут наверно с array_rand короче получится.
также ошибка, ты думаешь в массиве индексы начинаются с 1 а они начинаются с 0. У тебя первое слово (с индексом 0) никогда не выпадет.
Тут идут ошибки из-за этого же : http://ideone.com/qgt2jw
В остальном хорошо.
Профайлер покаызвает что paint занимает 100% времени.
Методом исключения удалось определить что проблема в SVG иконках — стоит их отключить как все оживает. Ну и возможно отчасти в гигантских PNG картинках которые еще и масштабируются.
Вот такие вот «специалисты» которые больше интересуются модными технологиями, а не качеством получившейся страницы.
>>455905
Вообще, для скачивания файлов лшучше использовать более высокоуровневые библиоетки, вроде Guzzle, а не писать лапшекод на курле. Имей это в виду.
Вот задания:
— напиши скрипт, проверяющий изменился ли файл http://archive.ubuntu.com/ubuntu/dists/utopic-updates/main/installer-i386/current/images/netboot/mini.iso без скачивания его целиком (хинт: используй HEAD и last-Modified)
— напиши скрипт, загружающий файл на rghost.ru и выводящий ссылку
Там есть псевдопеременная arguments и методы apply/call:
http://learn.javascript.ru/arguments-pseudoarray
http://javascript.ru/arguments
http://javascript.ru/Function/apply
http://learn.javascript.ru/this#метод-apply
>>455606
> перенаправляет на индекс в котором не подключаются картинки и css
Почитай про то как работают относительные URL. Они резолвятся относительно URL в браузере а не того где расположен твой файл.
>>455603
> Давай я сначала попробую написать задачу про кошек-мышек, потом, с новыми знаниями, переделаю задачу с превьюшками, а потом посмотрим нужна ли мне дополнительная задача.
Как хочешь, но я бы советовал после браться за задачи вроде списка студентов или файлообменника, в последнем тебе как раз превьюшки понадобятся. Ну то есть за задачи не просто по изучению PHP, а по использованию PHP для написания сайтов и приложений.
Ну а кошки мышки у тебя времени много не должны занять. Насчет алгоритма выбора хода, сразу дам совет, как это можно сделать:
— составляем список возможных ходов включая стоять на месте
— оцениваем каждый ход в баллах
— выбираем с наибольшим числом баллов
Критерии оценки могут быть разными, для кошки близость к мышке, для мышки наоборот. Плюс, мышка должна избегать краев доски и особенно углов так как там ее легче поймать.
> Далее я хочу глубже изучить html\css и js. У тебя вроде были задачи по ним?
Да. в шапке треда
> но я правда хочу все знать!
Это хорошая идея. там еще много тем для изучения.
> Ну и еще хочется спросить у тебя, нравиться ли тебе учиться меня? В смысле нету каких-нибудь раздражающих моментов?
Все нормально. Чем больше ты хочешь изучить и чем больше задачек решить, тем лучше. Тем более что у тебя неплохо получается.
Там есть псевдопеременная arguments и методы apply/call:
http://learn.javascript.ru/arguments-pseudoarray
http://javascript.ru/arguments
http://javascript.ru/Function/apply
http://learn.javascript.ru/this#метод-apply
>>455606
> перенаправляет на индекс в котором не подключаются картинки и css
Почитай про то как работают относительные URL. Они резолвятся относительно URL в браузере а не того где расположен твой файл.
>>455603
> Давай я сначала попробую написать задачу про кошек-мышек, потом, с новыми знаниями, переделаю задачу с превьюшками, а потом посмотрим нужна ли мне дополнительная задача.
Как хочешь, но я бы советовал после браться за задачи вроде списка студентов или файлообменника, в последнем тебе как раз превьюшки понадобятся. Ну то есть за задачи не просто по изучению PHP, а по использованию PHP для написания сайтов и приложений.
Ну а кошки мышки у тебя времени много не должны занять. Насчет алгоритма выбора хода, сразу дам совет, как это можно сделать:
— составляем список возможных ходов включая стоять на месте
— оцениваем каждый ход в баллах
— выбираем с наибольшим числом баллов
Критерии оценки могут быть разными, для кошки близость к мышке, для мышки наоборот. Плюс, мышка должна избегать краев доски и особенно углов так как там ее легче поймать.
> Далее я хочу глубже изучить html\css и js. У тебя вроде были задачи по ним?
Да. в шапке треда
> но я правда хочу все знать!
Это хорошая идея. там еще много тем для изучения.
> Ну и еще хочется спросить у тебя, нравиться ли тебе учиться меня? В смысле нету каких-нибудь раздражающих моментов?
Все нормально. Чем больше ты хочешь изучить и чем больше задачек решить, тем лучше. Тем более что у тебя неплохо получается.
Есть brainstorage.me, geekjob, hh.ru, сначала глянь их.
>>455513
там может стоять что угодно, но если у браузера есть только шрифт с весом 400 то он поставит то, что есть.
И что насчет проверки верстки в ИЕ? Я тут описал несколько способов: >>455511
>>455943
При уменьшении масштаба в браузере надо чтобы картинки портфолио не становились больше 4 в ряд так как некрасиво получается.
У второй картинки в портфолио белая полоса слева.
А так, вообще, по сравнению с первыми вариантами — земля и небо.
Я позже еще гляну как будет время (хорошо если ты напомнишь об этом), а пока советую изучать JS, он тоже нужен при верстке, или делать еще какие-то задачки.
А ведь по сути null отсутствие значение и ему самое место там, где значения может просто не быть.
Как его правильно использовать и какие подводные камни, например, в сравнениях?
NULL значит «нет данных» или «неизвестно». Это не то же самое, что 0 или пустая строка.
Все математические или логические операции учитывают это:
SELECT 5 + NULL -> NULL (результат сложения с неизвестным тоже неизвестен)
SELECT 5 + 0 -> 5
NULL × 0 -> NULL (не знаю почему так)
1 AND NULL -> NULL
1 OR NULL -> 1 (при OR достаточно чтобы одна из стороны была непустой)
Соответственно сравнение с NULL через = не работает, надо использовать IS NULL:
SELECT NULL = NULL -> NULL (неизвестно равно ли неизвестное число неизвестному)
NULL IS NULL -> 1
Если для колонки указано NOT NULL и нет значения по умолчанию, обычно это значит что она обязательна к заполнению (в строгом режиме MySQL не позволит пропустить эту колонку).
> и обычно где запись может быть без поля (например, user_id) - ставил 0 по умолчанию
Ты не используешь внешние ключи и зря, так как ты не видишь своей же ошибки. Они бы не дали тебе вставить туда 0. Почитай http://denis.in.ua/foreign-keys-in-mysql.htm
Надо использовать в таких случаях NULL
Ну и также, если хочешь получше разобраться в MySQL могу посоветовать задачи на SQL из оп поста.
>Под Windows с русскими буквами (и тем более с иероглифами) будут проблемы.
>Кстати, проверь чтобы твой файлообменник работал с иероглифами. если надо, вот пример такого файла: http://rghost.ru/6PvRNs6lV
Русские имена у меня сохраняются, благодаря переводу из одной кодировки в другую iconv("UTF-8", "CP1251", $fileName);
Но в какой кодировке будет сохранет вот такое имя: "[MP3] 化物語 音楽集 - Bakemonogatari Music Collection - (ED・特典CD).torrent"
Браузер фообще выводит что имя файла имеет попадает в массив $_FILES['file']['name'] вот такое:
[MP3] 化物語 音楽集 - Bakemonogatari Music Collection - (ED・特典CD).torrent[MP3]
По википедии кодировка Windows-1251 восьмибитная, и там нет иероглифов. В какой кодировке всё это дело сохранять на windows?
Надо видимо переименовывать. Сама по себе Windows поддерживает utf, но PHP сделан так, что под Windows использует функции работающие в Win-1251.
> Браузер фообще выводит что имя файла имеет попадает в массив $_FILES['file']['name'] вот такое:
Это ты забыл метатег поставить чтобы сказать браузеру что данные в utf-8
Аноны, подскажите чому этот код в браузере и phpstorm возвращает знаки вопроса. Как запилить что бы нормальные русские буквы были?
На ideone походу вообще нет русской локали, так что на вывод там обращать внимания не стоит.
Подскажите, куда можно скинуть свой сайт, что-бы его код можно было посмотреть?
А как его юзать?
Я там зарегестрировался, дошел до пикрилейтеда ололодиванон. А дальше как? Или я не там?
Читай книжку про гитхаб либо используй декстопное приложение для винды, там просто перетаскиваешь папку с проектом в окно программы, коммитишь и репозиторий сам создастся.
Собственно, мне нужно кидать не весь сайт, а элементы кода.
Написано же все на картинке. Команды нужно вводить в posix совместимый терминал – консоль в mac os/linux. В шиндошсе не знаю как.
Да, мне дало уверенности в том что нужно делать с помощью координат. Спасибо.
>>456495
>В виде объекта хранящего список находящихся на нем животных например. мы же в мире ООП.
А как тогда животным ориентироваться в пространстве? Меня именно это интересует, если честно. Анон выше подсказал использовать координаты, что собственно логично, но будет ли так правильно?
Извиняюсь если вопрос глупый - я просто никогда не делал задачи связанные с пространством.
https://github.com/sgscode/students
Анон, я вроде исправил все баги, проверь как будет время. Особенно по классу Students поясни, возможно я неправильно понял в чем там ошибка.
Нет, я точно помню, что вчера было много постов, а сегодня их только два осталось.
Тиреч вайпнул пару досок.
> https://github.com/sgscode/students/blob/master/students.sql#L40
> DEFAULT CHARSET=latin1
Кодировку в таблице поменял? Русские имена вставляются и сохраняются правильно?
Повторю проблему, может кто поможет:
Выдает вот такую ошибку при попытке проверки эмейла на совпадение в БД.
Warning: mysql_real_escape_string() expects parameter 2 to be resource, string given in E:\OpenServer\domains\localhost\php\Register\input1.php on line 35
Warning: mysql_query() expects parameter 2 to be resource, string given in E:\OpenServer\domains\localhost\php\Register\input1.php on line 35
Warning: mysql_num_rows() expects parameter 1 to be resource, null given in E:\OpenServer\domains\localhost\php\Register\input1.php on line 36
Тогда я скопировал содержимое файлов в ideone, счас залил на гит: https://github.com/Si0n/registr
Приветик
Братишки, я почему то немогу PDO в debian включит, подскажите, как делать.
Выполнил эту команду:
ALTER TABLE students CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;
теперь русский корректно отображается.
В гит залей новый дамп тогда
>>456817
Надо установить что-то. Попробуй сделать
apt-cache search pdo | grep php | sort
И посмотри что из этого ты не установил. pdo-mysql скорее всего.
>>456815
Вот старый ответ
>>457109
$link = $page->makeDBcnct( );
Перед этой строчкой с помощью var_dump определи что хранится в $link и почему.
Ну и отдельно замечу что код ужасный, mysql давно устарел, переменные нельзя вставлять в запрос, HTML нельзя смешивать с логикой на php в одном файле, ты явно учился по какому-то устаревшему учебнику.Почитай например http://phptherightway.ru/ чтобы ознакомиться с современным состоянием дел.
Там есть раздел про работу с БД: http://phptherightway.ru/#Базы_данных
Также, если ты пытался использовать ООП, то у тебя получилось довольно неправильно. Чтобы это понять, достаточно сравнить название класса (page) и код в нем. Если класс представляет собой информацию о какой-то странице (?) то почему в нем код работы с базой данных? Почему у тебя прямо в PHP код засунут кусок HTML? Каждый класс должен заниматься своим делом. Это не ООП, ты просто используешь в своем коде классы не понимая как это надо делать правильно (у нас есть уроки и задачки которые могли бы помочь разобраться, кстати).
Ну и названия неудачные например getData ничего не значит. Почти любая функция получает какие-то данные, назвать метод getData это то же самое что назвать метод someMethod.
>>457109
Также когда ты делаешь запрос надо обрабатывать ошибки (иначе ты можешь их не увидеть). Почитай официальный мануал по функции mysql_query:
http://php.net/manual/ru/function.mysql-query.php
там в первом же примере кода есть if который проверяет что вернула функция и обрабатывает ошибки: http://php.net/manual/ru/function.mysql-query.php#refsect1-function.mysql-query-examples
Соответственно ты должен ставить такой if после каждого действия с mysql.
Разумеется это все устарело, и mysql и ифы. Лучше исплоьзовать PDO, который умеет сам обрабатывать ошибки и выбрасывать исключения.
В гит залей новый дамп тогда
>>456817
Надо установить что-то. Попробуй сделать
apt-cache search pdo | grep php | sort
И посмотри что из этого ты не установил. pdo-mysql скорее всего.
>>456815
Вот старый ответ
>>457109
$link = $page->makeDBcnct( );
Перед этой строчкой с помощью var_dump определи что хранится в $link и почему.
Ну и отдельно замечу что код ужасный, mysql давно устарел, переменные нельзя вставлять в запрос, HTML нельзя смешивать с логикой на php в одном файле, ты явно учился по какому-то устаревшему учебнику.Почитай например http://phptherightway.ru/ чтобы ознакомиться с современным состоянием дел.
Там есть раздел про работу с БД: http://phptherightway.ru/#Базы_данных
Также, если ты пытался использовать ООП, то у тебя получилось довольно неправильно. Чтобы это понять, достаточно сравнить название класса (page) и код в нем. Если класс представляет собой информацию о какой-то странице (?) то почему в нем код работы с базой данных? Почему у тебя прямо в PHP код засунут кусок HTML? Каждый класс должен заниматься своим делом. Это не ООП, ты просто используешь в своем коде классы не понимая как это надо делать правильно (у нас есть уроки и задачки которые могли бы помочь разобраться, кстати).
Ну и названия неудачные например getData ничего не значит. Почти любая функция получает какие-то данные, назвать метод getData это то же самое что назвать метод someMethod.
>>457109
Также когда ты делаешь запрос надо обрабатывать ошибки (иначе ты можешь их не увидеть). Почитай официальный мануал по функции mysql_query:
http://php.net/manual/ru/function.mysql-query.php
там в первом же примере кода есть if который проверяет что вернула функция и обрабатывает ошибки: http://php.net/manual/ru/function.mysql-query.php#refsect1-function.mysql-query-examples
Соответственно ты должен ставить такой if после каждого действия с mysql.
Разумеется это все устарело, и mysql и ифы. Лучше исплоьзовать PDO, который умеет сам обрабатывать ошибки и выбрасывать исключения.
Она работает. как юзать, написано в мануале. Увидеть сами куки нетрудно в заголовках на вкладке Network в инспекторе в браузере (Ctrl + Shift + I).
>Надо установить что-то. Попробуй сделать
apt-cache search pdo | grep php | sort
И посмотри что из этого ты не установил. pdo-mysql скорее всего.
Такое вернуло вроде на месте всё
может что-то в php.ini забыл?
root@debian:~# apt-cache search pdo | grep php | sort
php5-mysql - MySQL module for php5
php5-mysqlnd - MySQL module for php5 (Native Driver)
php5-odbc - ODBC module for php5
php5-pgsql - PostgreSQL module for php5
php5-sqlite - SQLite module for php5
php5-sybase - Sybase / MS SQL Server module for php5
php-db - PHP PEAR Database Abstraction Layer
php-mdb2 - merge of the PEAR DB and Metabase php database abstraction layers
У мне yii2 такое говорит
Database Exception – yii\db\Exception
could not find driver
↵
Caused by: PDOException
could not find driver
in /var/www/testhub/vendor/yiisoft/yii2/db/Connection.php at line 579
>Надо установить что-то. Попробуй сделать
apt-cache search pdo | grep php | sort
И посмотри что из этого ты не установил. pdo-mysql скорее всего.
Такое вернуло вроде на месте всё
может что-то в php.ini забыл?
root@debian:~# apt-cache search pdo | grep php | sort
php5-mysql - MySQL module for php5
php5-mysqlnd - MySQL module for php5 (Native Driver)
php5-odbc - ODBC module for php5
php5-pgsql - PostgreSQL module for php5
php5-sqlite - SQLite module for php5
php5-sybase - Sybase / MS SQL Server module for php5
php-db - PHP PEAR Database Abstraction Layer
php-mdb2 - merge of the PEAR DB and Metabase php database abstraction layers
У мне yii2 такое говорит
Database Exception – yii\db\Exception
could not find driver
↵
Caused by: PDOException
could not find driver
in /var/www/testhub/vendor/yiisoft/yii2/db/Connection.php at line 579
Установить указанный модуль (apt-get) и включить в php.ini. Если ты php смог на дебиан установить то значит и модуль можешь установить, верно?
А! Вспомнил! По моему в дебиане там не один большой php.ini, а разбитый на кучу мелких. Вот тут вроде что-то написано https://wiki.debian.org/PHP/
Вот еще ссылка в помощь http://php.net/manual/ru/install.unix.debian.php
http://codepad.org/x7rojgwW
там специально дан неправильный код, который уходит в минуса. Надо его исправить или написать свой.
Надо смотреть чему равен остаток долга и обрабатывать ситуацию, когда она маленький, а не выплачивать сразу же 5000 вот в этом месте: ... + $servicePayment - $monthlyPayment;
Попробуй переписать код внутри цикла примерно так:
- прибавляем проценты и комиссию к остатку долга
- если остаток маленький, выплачиваем сколько осталось и уходим
- иначе платим 5000
«Платим» здесь значит уменьшаем долг и увеличиваем общую сумму выплаченного.
Если тебе трудно написать сразу, давай писать по частям:
- напиши код, который каждый месяц только увеличивает долг (и выводит его на экран)
- допиши к нему код, который каждый месяц пишет, большой сейчас долг (школьник не может его выплатить разом) или маленький (меньше 5000 и его можно выплатить за один раз)
- допиши код, который каждый месяц пишет, сколько надо заплатить в этом месяце (с учетом того что больше 5000 школьник заплатить не может)
- наконец, допиши код, который платит эту сумму, уменьшая долг и считает сколько всего выплачено
ну хорошо я что-то подшаманил у меня теперь получается что я еще банку должен 260
>>456695
> setlocale(LC_ALL, "russian");
Я сомневаюсь что это сработает. Локали глючные, непортабельные и ненадежные. Лучший способ написать свой код для вывода месяца или найти библиотеку.
>>456699
Если ты готов осилить гит (он все равно понадобится) то https://pages.github.com/
Книга по гиту http://git-scm.com/book/ru/v1
Если никак то можешь конечно выложить архивчиком или найти бесплатный хостинг. Но лучше бы на гитхаб.
Помощь по командной строке: https://gist.github.com/codedokode/10539568
>>456702
Придется изучить гит чтобы пользоваться гитхабом. Но все другие аноны его освоили. Вот посмотри на сайт другого анона например:
https://github.com/MindiMakridi/MindiMakridi.github.io
>>456710
Новичкам лучше начать с консольки чтобы понять гит.
>>456727
В шиндоусе в git bash который будет после установки гита
>>456695
> setlocale(LC_ALL, "russian");
Я сомневаюсь что это сработает. Локали глючные, непортабельные и ненадежные. Лучший способ написать свой код для вывода месяца или найти библиотеку.
>>456699
Если ты готов осилить гит (он все равно понадобится) то https://pages.github.com/
Книга по гиту http://git-scm.com/book/ru/v1
Если никак то можешь конечно выложить архивчиком или найти бесплатный хостинг. Но лучше бы на гитхаб.
Помощь по командной строке: https://gist.github.com/codedokode/10539568
>>456702
Придется изучить гит чтобы пользоваться гитхабом. Но все другие аноны его освоили. Вот посмотри на сайт другого анона например:
https://github.com/MindiMakridi/MindiMakridi.github.io
>>456710
Новичкам лучше начать с консольки чтобы понять гит.
>>456727
В шиндоусе в git bash который будет после установки гита
это первоначальный
<?php
error_reporting(-1);
$creditBalance = 40000; / Долг анона перед банком /
$percent = 1.03; / Банк начисляет 3% в месяц от суммы /
$servicePayment = 1000; / А также 1000 рублей в месяц комиссии за обслуживание счета /
$monthlyPayment = 5000; / Анон платит 5000 р в месяц, это все, что ему дает мама на завтраки /
$paymentTotal = 0; / Сколько всего отдал банку анон /
/ Посчитаем расходы 20 раз на 20 месяцев вперед /
for ($month = 1; $month <= 20; $month ++) {
\t
\t$creditBalance = ( $creditBalance $percent ) + $servicePayment - $monthlyPayment;
\t$paymentTotal = $paymentTotal + $monthlyPayment;
\techo "{$month} месяц спустя: долг = {$creditBalance} руб, выплачено всего {$paymentTotal} руб. \n";
/ Если баланс отрицательный — хватит считать */
if ($creditBalance < 0) {
echo "С меня хватит!\n";
break;
}
}
>>456746
Можно использовать координаты. Ориентироваться просто: клеточка справа это клеточка у которой икс на 1 больше чем у тебя, и т.д.
Можешь на листочке бумаги координаты нарисовать :)
>>456776
А почему нет? Такие у них традиции.
>>456778
> использовать mt_rand для выбора слов, не сработало
Покажи код, этот метод как раз работает. ну еще можно взять функцию array_rand.
-----
>>Я сомневаюсь что это сработает. Локали глючные, непортабельные и ненадежные. Лучший способ написать свой код для вывода месяца или найти библиотеку.
> Но все же почему так, человек курсы которого я смотрю их использует и у него все ок. А у меня вот знаки вопроса сплошные?
Может быть у него используется 8-битная кодировка вроде win-1251 (а у тебя utf-8 и буквы ломаются). Ну и судя по названию «russsain» это локаль под Windows, под linux локали называются обычно ru_RU.utf8 или как-то так и они могут быть не установлены на сервере. То есть используя локали ты рискуешь что твое приложение не везде заработает и рискуешь потратить кучу времени на поиск проблемы.
------
>Есть один скрипт на jQuery. Суть в том, что он проигрывает анимацию когда пользователь скроллит вниз до определённого места.
> Всё работает в хроме, но в файрфоксе анимация не проигрывается. В чём дело? Как решить эту проблему?
Для начала открой инспектор (Ctrl + SHift + I) и проверь выполняется ли функция внутри.
---------
> При попытке применить к иероглифам iconv("UTF-8", "CP1251", $fileName);
> Вызывается ошибка. Если сохранять как есть сохраняются кракозябры.
В кодировке cp1251 всего 256 символов и там нет иероглифов. Нельзя их сохранить никак в этой кодировке.Вот вики: https://ru.wikipedia.org/wiki/Windows-1251
----------
> >Надо видимо переименовывать.
> Ну ведь в именах каталогов виндовс можно же написать иероглифы.
> Вопрос как их туда записать средствами php/
Надо переименовывать значит. Например вырезать/заменять все символы кроме разрешенного списка. Я боюсь средствами php иероглифы под WIndows не сохранить.
> Ну ведь в именах каталогов виндовс можно же написать иероглифы.
Windows поддерживает utf, но php использует 8-битное WinAPI которое не пропускает иероглифы. На линуксе/маке проблемы нет, но переименовывать наверно в любом случае хорошая идея.
> Вопрос как их туда записать средствами php/
Скорее всего никак
>>456746
Можно использовать координаты. Ориентироваться просто: клеточка справа это клеточка у которой икс на 1 больше чем у тебя, и т.д.
Можешь на листочке бумаги координаты нарисовать :)
>>456776
А почему нет? Такие у них традиции.
>>456778
> использовать mt_rand для выбора слов, не сработало
Покажи код, этот метод как раз работает. ну еще можно взять функцию array_rand.
-----
>>Я сомневаюсь что это сработает. Локали глючные, непортабельные и ненадежные. Лучший способ написать свой код для вывода месяца или найти библиотеку.
> Но все же почему так, человек курсы которого я смотрю их использует и у него все ок. А у меня вот знаки вопроса сплошные?
Может быть у него используется 8-битная кодировка вроде win-1251 (а у тебя utf-8 и буквы ломаются). Ну и судя по названию «russsain» это локаль под Windows, под linux локали называются обычно ru_RU.utf8 или как-то так и они могут быть не установлены на сервере. То есть используя локали ты рискуешь что твое приложение не везде заработает и рискуешь потратить кучу времени на поиск проблемы.
------
>Есть один скрипт на jQuery. Суть в том, что он проигрывает анимацию когда пользователь скроллит вниз до определённого места.
> Всё работает в хроме, но в файрфоксе анимация не проигрывается. В чём дело? Как решить эту проблему?
Для начала открой инспектор (Ctrl + SHift + I) и проверь выполняется ли функция внутри.
---------
> При попытке применить к иероглифам iconv("UTF-8", "CP1251", $fileName);
> Вызывается ошибка. Если сохранять как есть сохраняются кракозябры.
В кодировке cp1251 всего 256 символов и там нет иероглифов. Нельзя их сохранить никак в этой кодировке.Вот вики: https://ru.wikipedia.org/wiki/Windows-1251
----------
> >Надо видимо переименовывать.
> Ну ведь в именах каталогов виндовс можно же написать иероглифы.
> Вопрос как их туда записать средствами php/
Надо переименовывать значит. Например вырезать/заменять все символы кроме разрешенного списка. Я боюсь средствами php иероглифы под WIndows не сохранить.
> Ну ведь в именах каталогов виндовс можно же написать иероглифы.
Windows поддерживает utf, но php использует 8-битное WinAPI которое не пропускает иероглифы. На линуксе/маке проблемы нет, но переименовывать наверно в любом случае хорошая идея.
> Вопрос как их туда записать средствами php/
Скорее всего никак
<?php
error_reporting(-1);
$creditBalance = 40000; / Долг анона перед банком /
$percent = 1.03; / Банк начисляет 3% в месяц от суммы /
$servicePayment = 1000; / А также 1000 рублей в месяц комиссии за обслуживание счета /
$monthlyPayment = 5000; / Анон платит 5000 р в месяц, это все, что ему дает мама на завтраки /
$paymentTotal = 0; / Сколько всего отдал банку анон /
/ Посчитаем расходы 20 раз на 20 месяцев вперед /
for ($month = 1; $month <= 20; $month ++) {
\t
\t$creditBalance = ( $creditBalance $percent ) + $servicePayment - $monthlyPayment;
\t$paymentTotal = $paymentTotal + $monthlyPayment;
\techo "{$month} месяц спустя: долг = {$creditBalance} руб, выплачено всего {$paymentTotal} руб. \n";
/ Если баланс отрицательный — хватит считать */
if ($creditBalance < $monthlyPayment) {
$monthlyPayment==$creditBalance;
echo "С меня хватит!\n";
break;
}
}
> Как сделать так, чтобы при загрузке файла из формы и сохранении его с помощью move_uploaded_file получалось нормальное имя на кириллице, если оно у него на этой самой кириллице?
В Windows функции работы с файлами принимают и выдают имена в кодировке windows-1251. преобразовать можно с помощью iconv. Обрати внимание, что делать это надо только под win, под линуксом и маком они работают с utf-8.
> И как кстати реализовать такую загрузку файлов, чтобы случайно не перезаписать старый, если имена совпадут? Как, короче, сделать уникальное имя?
Приписывать уникальный id
> Ладно, фиг с ним, мне все равно надо переименовывать файлы эти. Но теперь такой неожиданный для меня вопрос: я загружаю файлы в той же форме, где добавляю новую запись в SQL, но как связать запись с этим файлом? Понятно, что можно присвоить файлу имя содержащее тот же айдишник, но его-то как получить, если в базу он пишется через auto_increment?
База может вернуть последний сгенерированный id, смотри например
http://php.net/manual/ru/pdo.lastinsertid.php
http://php.net/manual/ru/mysqli.insert-id.php
--------
> Если таки удается заставить себя допиливать свой проектик, то прям настроение такое хорошее, когда что-то сделаешь, пусть даже мелочь. Ощущение, что не зря ебланил весь день, как обычно бывает. Прям доставляет.
--------
> Оп, у тебя в учебнике не сказано что такое foreach.
В таком случае стоит набрать в гугле php foreach и открыть официальный мануал который гораздо подробнее и даже в чем-то полезнее советов ОПа:
http://php.net/manual/ru/control-structures.foreach.php
Но ты прав, там хорошего объяснения в учебнике пока нет.
> Как сделать так, чтобы при загрузке файла из формы и сохранении его с помощью move_uploaded_file получалось нормальное имя на кириллице, если оно у него на этой самой кириллице?
В Windows функции работы с файлами принимают и выдают имена в кодировке windows-1251. преобразовать можно с помощью iconv. Обрати внимание, что делать это надо только под win, под линуксом и маком они работают с utf-8.
> И как кстати реализовать такую загрузку файлов, чтобы случайно не перезаписать старый, если имена совпадут? Как, короче, сделать уникальное имя?
Приписывать уникальный id
> Ладно, фиг с ним, мне все равно надо переименовывать файлы эти. Но теперь такой неожиданный для меня вопрос: я загружаю файлы в той же форме, где добавляю новую запись в SQL, но как связать запись с этим файлом? Понятно, что можно присвоить файлу имя содержащее тот же айдишник, но его-то как получить, если в базу он пишется через auto_increment?
База может вернуть последний сгенерированный id, смотри например
http://php.net/manual/ru/pdo.lastinsertid.php
http://php.net/manual/ru/mysqli.insert-id.php
--------
> Если таки удается заставить себя допиливать свой проектик, то прям настроение такое хорошее, когда что-то сделаешь, пусть даже мелочь. Ощущение, что не зря ебланил весь день, как обычно бывает. Прям доставляет.
--------
> Оп, у тебя в учебнике не сказано что такое foreach.
В таком случае стоит набрать в гугле php foreach и открыть официальный мануал который гораздо подробнее и даже в чем-то полезнее советов ОПа:
http://php.net/manual/ru/control-structures.foreach.php
Но ты прав, там хорошего объяснения в учебнике пока нет.
Объясни что ты поменял и почему? Я вижу что вроде поменялось только эта строчка:
> $monthlyPayment==$creditBalance;
Что она должна по твоей задумке делать? Вообще, она ничего не делает так как == сравнивает числа и возвращает специальные значения true или false, которые ты никуда не сохраняешь.
Такое ощущение что ты наугад строчки пишешь. так быть не должно, надо понимать что ты делаешь, даже если понять сложно., надо попытаться
То есть по моему ты вообще ничего не поменял.
Я советую тебе удалить этот код и написать свой с нуля.
Вот тут >>456911 я описал 2 варианта решения. Второй, который по шагам делается, по моему, более прост.
Также там есть задача про вклад в банк, чуть ниже можешь решить ее сначала если хочешь, она проще.
Вован, оклемался, что ли?
Ты, главное, не нервничай, тебе нельзя. Всё будет хорошо, легаси говна на твой век хватит. Иди лучше лапшичку погрызи. Воду не отключили, надеюсь?
Поддерживаю этого мудака, Ларавел — это сейчас весело, модно, молодёжно. И невероятно удобно, минимум ебли под капотом.
Нужно выдавать токен в cookies пользователя и поставить долгий срок жизни. Сессия завершена, если пользователь удалил токен.
Не стоит, это старье
>>457170
Phalcon на Си и очень специфический, не для начинающих. Для начинающих я советую Yii2 как простой фреймворк и Symfony 2 как сложный.
>>457182
>>457216
Ничего веселого все на статических методах, и все на велосипедах. Не особо подойдет для начинающего так как не учит правильнымм подходам.
>>457217
> Как-то можно узнать, что сессия завершена, и если завершена, что-то далее сделать?
Сессия это временное хранилище данных. Она также удаляется например если 20-30 минут к ней не обращаться. Обнаружить что она завершена очень легко — массив SESSION стал пустой.
>>457223
Неправильный совет. Не надо это делать так как сессия на сервере все равно будет удалена через 20-30 минут неактивности.
Но ты конечно можешь поставить отдельную, не связанную с сессией куку. Например при авторизации можно сделать отдельную авторизационную куку (а можно зайти еще дальше и вообще не использовать сессии для авторизации).
Ладно, я думал, что вопрос про сессию поможет мне придумать решение, но что-то тухло всё. Я, в общем, хочу хранить в базе длительность последней сессии для каждого пользователя, есть идеи, есть икеи? Почему я спросил о завершении сессии, подумал, мол, она завершается с закрытием браузера, а значит, это то, что мне нужно — можно сравнить два времени, логина и конца логина, разницей и будет длительность сессии, но мне кажется, что вариант через завершение сессии неправильный, это неудобно. Вторым вариантом думал написать аяксопроверяльщик на клиенте, который раз в какое-то количество секунд говорит серверу, что всё хорошо и он еще жив, а тот заносит это время в базу, обновляя поле снова и снова, пока пользователь еще на сайте, но это тоже странно звучит.
Есть советы? Спасибо же.
Решил всё же разбираться с PDO, создал новый класс для работы с DB, в таком виде можно оставить? (да, там смешано php с html)
http://ideone.com/oCbjIG либо нужно то, что выдаст mysql на запрос сохранить отдельно и потом уже передать в отдельный обработчик который выведет на экран?
Да, там тоже есть велосипедизм и своеобразные решения, но как я понимаю, Юи в России популярен (скорее всего из-за русского разработчика и русской документации) и есть высокая вероятность с ним столкнуться.
А в Юи 2 они наконец-то начали поддерживать композер, еще какие-то улучшения сделали.
>>457255
> Я, в общем, хочу хранить в базе длительность последней сессии для каждого пользователя, есть идеи
Тебе это точно нужно? Это технически непросто и содержит кучу заморочек.
В современных браузерах удобно использовать например вебсокет так как он не передает никаких запросов, а на сервере можно зафиксировать разрыв соединения.
Если тебе надо учиытвать кто онлайн, то проще фиксировать дату последней активности и просто считать что допустим если пользователь неактивен 3 минуты то он ушел с сайта. Вконтакте вроде раньше примерно так работал, там еще была интересная фишка что если не заходить на свою страницу он считал что ты офлайн.То есть проверялось только время захода на свою страницу и этого всем хватало.
>в общем, хочу хранить в базе длительность последней сессии для каждого пользователя
Можно учитывать время от логина до последней активности, примерно будет верно.
> Почему я спросил о завершении сессии, подумал, мол, она завершается с закрытием браузера,
Неверно. Когда пользователь закрывает браузер на сервере ничего не происходит. Ты представляешь как вообще взаимодействуют браузер и сервер, как работает HTTP? Если нет то тебе надо сначала это изучить а потом браться за такую работу.
Сессии в PHP в linux обычно удаляются скриптом-сборщиком мусора который запускается по расписанию и удаляет старые файлы сессий. При этом никакой твой код разумеется не вызвыается.
> Вторым вариантом думал написать аяксопроверяльщик на клиенте, который раз в какое-то количество секунд говорит серверу, что всё хорошо и он еще жив,
Лучше вебсокет тогда
> а тот заносит это время в базу, обновляя поле снова и снова,
И при 100 пользователях твоя база ляжет.
> Есть советы?
1) подумать, а так ли это надо и нельзя ли решить задачу другим способом (я уверен что можно, зачем тебе длительность сессии, ты будешь сидеть и лично считать кто сколько на сайте просидел?)
2) нельзя ли использовать стороннеее решение, какую-нибудь аналитику наподобие яндекс-метрики которая вообще может все действия на сайте записывать, а не только длительность сессии
3) сохранять время последней активности
Да, там тоже есть велосипедизм и своеобразные решения, но как я понимаю, Юи в России популярен (скорее всего из-за русского разработчика и русской документации) и есть высокая вероятность с ним столкнуться.
А в Юи 2 они наконец-то начали поддерживать композер, еще какие-то улучшения сделали.
>>457255
> Я, в общем, хочу хранить в базе длительность последней сессии для каждого пользователя, есть идеи
Тебе это точно нужно? Это технически непросто и содержит кучу заморочек.
В современных браузерах удобно использовать например вебсокет так как он не передает никаких запросов, а на сервере можно зафиксировать разрыв соединения.
Если тебе надо учиытвать кто онлайн, то проще фиксировать дату последней активности и просто считать что допустим если пользователь неактивен 3 минуты то он ушел с сайта. Вконтакте вроде раньше примерно так работал, там еще была интересная фишка что если не заходить на свою страницу он считал что ты офлайн.То есть проверялось только время захода на свою страницу и этого всем хватало.
>в общем, хочу хранить в базе длительность последней сессии для каждого пользователя
Можно учитывать время от логина до последней активности, примерно будет верно.
> Почему я спросил о завершении сессии, подумал, мол, она завершается с закрытием браузера,
Неверно. Когда пользователь закрывает браузер на сервере ничего не происходит. Ты представляешь как вообще взаимодействуют браузер и сервер, как работает HTTP? Если нет то тебе надо сначала это изучить а потом браться за такую работу.
Сессии в PHP в linux обычно удаляются скриптом-сборщиком мусора который запускается по расписанию и удаляет старые файлы сессий. При этом никакой твой код разумеется не вызвыается.
> Вторым вариантом думал написать аяксопроверяльщик на клиенте, который раз в какое-то количество секунд говорит серверу, что всё хорошо и он еще жив,
Лучше вебсокет тогда
> а тот заносит это время в базу, обновляя поле снова и снова,
И при 100 пользователях твоя база ляжет.
> Есть советы?
1) подумать, а так ли это надо и нельзя ли решить задачу другим способом (я уверен что можно, зачем тебе длительность сессии, ты будешь сидеть и лично считать кто сколько на сайте просидел?)
2) нельзя ли использовать стороннеее решение, какую-нибудь аналитику наподобие яндекс-метрики которая вообще может все действия на сайте записывать, а не только длительность сессии
3) сохранять время последней активности
> в таком виде можно оставить?
Если ты делаешь для себя, то делай как хочешь, если ты решаешь нашу задачу то разумеется такой код недопустим. Ведь цель задачи научиться правильно разносить код по разным файлам и классам, а не смешивать в кучу.
Если ты решаешь задачу, пожалуйста прочитай подробные комментарии и пояснения под ней. Они там не просто так написаны.
> да, там смешано php с html
А в комментариях к задаче что написано про смешивание php и html?
> либо нужно то, что выдаст mysql на запрос сохранить отдельно и потом уже передать в отдельный обработчик который выведет на экран?
Ты читал комментарии к задаче, описания паттерна DataMapper? Было бы хорошо если бы ты его реализовал или хотя бы ActiveRecord.
А код может выглядеть примерно так:
// получаем студентов из базы в виде массива объектов Student
$students = $studentMapper->getAll( );
// выводим список
require 'templates/list.phtml';
Смотри, как кратко и аккуратно получается.
Еще я тебе советую в классе работы с БД не создавать PDO, а передавать его снаружи. Это сделает код более правильным и гибким.
А в твоем коде, как ты сделаешь чтобы несколько разных классов могли работать с базой? В каждом создавать свой PDO?
И разумеется класс работы с БД ни при каких условиях не должен ничего пытаться выводить.
А, и если это ты вчера выкладывал ссылку https://github.com/sgscode/students то я пока не успел проверить, чуть попозже проверю, я не забыл про тебя.
Аноны, ты еще с нами? Я тут проверил твой сайт и заметил пару мелочей:
http://www.browserstack.com/screenshots/f16cd9baeeb87aebd6e22ff74c92c5c0e6a49c70 — тут на скриншоте из айпада у тебя почему-то портфолио идет в 2 столбика, хотя есть место для третьего.
Причина в том что у тебя на .protfolio стоит большой паддинг (по 140px). Лучше было бы сделать его не таким большим.
Также, на скриншоте из Win 7 IE10 и IE9 картинки в портфолио обведены синей рамкой. В некоторых браузерах (включая ИЕ) по умолчанию стоит стиль вроде a img { border: ... } и побеждается он обнулением border на img.
В ИЕ8 кроме прочего, иконки телефона и адреса искажены (а также логотип уехал вправо из-за какого-то бага ИЕ). Чтобы избежать такого, надо указывать background-repeat: no-repeat и оставлять промежутки вокруг картинок, а не лепить их тесно.
Далее, ты подключаешь большое число шрифтов: http://fonts.googleapis.com/css?family=Lato:100,300,400,700,900,100italic,300italic,400italic,700italic,900italic&subset=latin,latin-ext
Там шрифты весят по 40 Кб каждый, вроде немного, но когда их 10 размеров, уже прилично выходит.
Я думаю, часть из них не используется (italic на многих размерах) и ее можно не подключать. С другой стороны, если каике-то тексты на сайте редактируются через админку с редактором HTML то конечно там может появиться курсив.
> font-family: "Lato", serif, "sans-serif", cursive, fantasy, monotype;
Это ты перестарался. достаточно указать один стандартный шрифт в конце, так как их должен поддерживать любой браузер, на то они и стандартные. Если у тебя шрифт с засечками, пиши serif, если без то sans-serif
В остальном, больше у меня замечаний нет. В итоге получилась довольно неплохая и прочная верстка. Я еще у себя протестировал ее добавлением/уменьшением объема текста и пунктов меню (у меня есть скрипт для этого) и ничего не развалилось. Надеюсь ты в итоге извлек для себя что-то полезное из этой задачи.
Если ты сомневаешься, что стоит изучать дальше, то тут есть 2 варианта:
— изучать яваскрипт, у нас есть задания на него. С яваскриптом ты сможешь как минимум заниматься полноценно версткой
— изучать написание приложений на php, задание про студентов и про фалообменник
Аноны, ты еще с нами? Я тут проверил твой сайт и заметил пару мелочей:
http://www.browserstack.com/screenshots/f16cd9baeeb87aebd6e22ff74c92c5c0e6a49c70 — тут на скриншоте из айпада у тебя почему-то портфолио идет в 2 столбика, хотя есть место для третьего.
Причина в том что у тебя на .protfolio стоит большой паддинг (по 140px). Лучше было бы сделать его не таким большим.
Также, на скриншоте из Win 7 IE10 и IE9 картинки в портфолио обведены синей рамкой. В некоторых браузерах (включая ИЕ) по умолчанию стоит стиль вроде a img { border: ... } и побеждается он обнулением border на img.
В ИЕ8 кроме прочего, иконки телефона и адреса искажены (а также логотип уехал вправо из-за какого-то бага ИЕ). Чтобы избежать такого, надо указывать background-repeat: no-repeat и оставлять промежутки вокруг картинок, а не лепить их тесно.
Далее, ты подключаешь большое число шрифтов: http://fonts.googleapis.com/css?family=Lato:100,300,400,700,900,100italic,300italic,400italic,700italic,900italic&subset=latin,latin-ext
Там шрифты весят по 40 Кб каждый, вроде немного, но когда их 10 размеров, уже прилично выходит.
Я думаю, часть из них не используется (italic на многих размерах) и ее можно не подключать. С другой стороны, если каике-то тексты на сайте редактируются через админку с редактором HTML то конечно там может появиться курсив.
> font-family: "Lato", serif, "sans-serif", cursive, fantasy, monotype;
Это ты перестарался. достаточно указать один стандартный шрифт в конце, так как их должен поддерживать любой браузер, на то они и стандартные. Если у тебя шрифт с засечками, пиши serif, если без то sans-serif
В остальном, больше у меня замечаний нет. В итоге получилась довольно неплохая и прочная верстка. Я еще у себя протестировал ее добавлением/уменьшением объема текста и пунктов меню (у меня есть скрипт для этого) и ничего не развалилось. Надеюсь ты в итоге извлек для себя что-то полезное из этой задачи.
Если ты сомневаешься, что стоит изучать дальше, то тут есть 2 варианта:
— изучать яваскрипт, у нас есть задания на него. С яваскриптом ты сможешь как минимум заниматься полноценно версткой
— изучать написание приложений на php, задание про студентов и про фалообменник
> Как-то не круто это.
Круто и гибко, и внешние ключи работают. Это стандартный способ.
> а что serialize тут не подойдет?
Нет конечно. Лучше использовать json в таких случаях из-за того что он не привязан к языку, плюс serialize это не формат обмена данными и нет никаких гарантий что он не поменяется например при обновлении php.
>Список JSON можно и в MySQL хранить с таким же успехом.
Ну да, только заебешься вручную лопатить их, без функций самой БД. Например, я бы посмотрел как ты удалишь один конкретный id из всех записей. Привет n+1.
А у PostgresSQL есть особая магия которая то же сделает без обхода таблицы, доставания и сохранения записей обратно?
Надо хранить в отдельной таблице и не изобретать велоипеды.
> без обхода таблицы, доставания и сохранения записей обратно?
Вопрос был не в том сколько запросов, а как это реализовано, используются ли индексы и тд.
А просто работа с JSON вроде как и для MySQL есть: http://blog.ulf-wendel.de/2013/mysql-5-7-sql-functions-for-json-udf/
>Вопрос был не в том сколько запросов, а как это реализовано, используются ли индексы и тд.
Я подозревал, но даже если с массивами там не очень(в чем я сильно сомневаюсь), то в остальном гораздо лудшэ это всё, jsonb вот недавно завезли.
Оказалось в эту поебень не встроили одного - умения нормально работать и не разваливаться при подключении хоть чего-то внешнего.
Как наши погромизды с ней пердолятся - ума не приложу.
ЗЫ: Гуры ООП говорят что это в контроллере делать не тру (как и работу с данными), но вообще забей хуй. Когда тебя начнут волновать такие вопросы - ты уже придёшь от наколеночного MVC к фреймворкам, под которые всё равно всё придётся переписывать.
Я хочу именно в наколеночное MVC, потом во фреймворки. И пихать эту проверку в контроллер мне вообще не нравится. А куда еще я не знаю.
DELETE FROM 'table' WHERE 'field' = 1234.
Алсо, меньше обсирайся, для временного хранения данных придумана монга, которая как раз и высирает на выходе чистый жысон.
>нельзя
Тащемта, можно. Если ты конечно не налажал с игнорированием прав, специфично виндовыми приблудами, или расширениями которых на боевых серваках нет.
некробсдшник посрался о постгресе, который интересен разве что таким же некрофилам.
Вместо разбития урла на части попробуй сделать как тут:
http://www.yiiframework.com/doc-2.0/yii-web-urlmanager.html
Можешь вообще весь этот код выдрать из YII и вставить его себе в проект, видоизменив. Я со временем понял, что такой подход гораздо лучше, чем неявное определение роутинга по именам классов контроллеров, именам файлов, и так далее. Причины:
1) Безопасность - снижается вероятность принимать что-то неправильное через урл, ведущее к ошибке.
2) Не надо в папке контроллеров городить хуету, заточенную под урл. Вместо этого называешь и группируешь произвольно, не городя костыли.
3) Всегда можно соотнести список роутинга и список используемого кода, и почистить лишний код.
Олсо вот пункты кошерного фреймворка:
1) Не грузить 2 мегабайта кода через интерпретатор, когда нужно выполнить простую задачу (строчку из БД получить и отдать в JSON)
2) Хороший фильтр, конфигурируемый под разные нужды. Пускай там будет оверкилл по паранойе - лучше потратить тысячу-другую тактов процессора раз в 10 секунд, чем получить дырявую хуйню.
3) Хорошая абстракция вокруг БД. За тысячи sql-запросов в коде продакшна надо пиздюлей давать.
4) Запилить нормальный шаблонизатор (XSLT, на крайний случай smarty).
5) Заранее продумать back-end, как отдельную сущность. С генератором CRUD по схеме, постраничным выводом, фильтрами, файл аплоадом.
А лучше выучить любой кошерный фреймворк, выучить его reference от корки до корки, и самому туда впиливать, что хочешь, и выпиливать то, что не нужно.
ах да, надо еще запилить garbage collection для БД и файлов. и мьютексы. костылями и то, и то очень заебывает делать.
>Ничего веселого все на статических методах, и все на велосипедах. Не особо подойдет для начинающего так как не учит правильнымм подходам.
Че-то взлольнул с тебя.
Статические методы. Лоооол. Да не используй их.
$obj = App::make('kokoko')->ban();
$obj = Kokoko::ban();
В чем проблема?
Ой, все, катись к хуям, комментатор. Лишь бы чего-нибудь спиздануть.
Спасибо, я просто забью на длительность сессии в итоге, надо академического говна почитать на эту тему.
Пасиб.
Ну а насчет ООП и MVC — способ есть. Основы ООП изучаются в последней главе учебника из ОП поста (а также в книгах которые упомянуты в ОП посте) и там же есть полезные задачи.
MVC упомянут например в задаче про список студентов, в комментариях, и несложно нагуглить что это.
Да я знаю, передо мной лежит задача с допилом вектора до ума, с его антикризисными штуками и замечаниями опа, но чет я уже неделю ебланю.
Сходил на https://packagist.org/search/?tags=crud
Вижу одно говно для фреймворков, как-то лень в их код лезть и вынимать.
Пока из полезного нашел только это:
https://github.com/j4mie/idiorm/
Впрочем дописать 4 функции круда не составит труда
http://ideone.com/IsLm1o
Блин, извиняюсь, немного не то там надписи идиотские чтобы видно лучше было как цикл работает
Вот: http://ideone.com/V8uIDm
>>457792
Открыл оба файла - 0 отличий, как по мне так все норм там.
Оп бы сказал тебе, что можно в функцию и вот эти параметры передавать отдельно:
$creditSum = 39999;
$payout = 5000;
а то вдруг изменятся, а типа не вшивать их внутрь, но как по мне, так если они не меняются в этой задаче, то и норм. Прост главное что бы ты понимал, что если бы каждый из них был бы действительно переменной, то и нужно выносить из функции
>break;
пробовал убирать? что меняется? У тебя собственно зачем он там? У тебя ведь цикл и так идет до того момента, как долг станет равен 0, стало быть как только дело дойдет до твоего
if ($creditSum < 5000)
то следующей итерации уже не будет, и функция вернет значение.
В общем, на тостере мне посоветовали это делать в базовом контроллере от которого все остальные наследуются. У меня вышло как-то так, все работает, хотя и не покидает ощущение что сие - говнокод.
public function __construct () {
\tif (Session::exists("userId")) {
\t\t\t$this -> view = new View();
\t\t} else {
\t\t\tRedirect::target("login.php");
\t\t}
\t}
Анон, я нашел время проверить твой код.
Вообще, сделано хорошо и аккуратно, приятно смотреть. Вот небольшой список замечаний к коду.
В файле ./listpage.php:
> catch (Exception $e) {
> echo $e->getMessage( );
> die( );
> }
Здесь ты ловишь исключение и самостоятельно его выводишь. Это плохая идея, так как об исключении узн
ает пользователь сайта (и ничего не поймет), а ты не узнаешь, так как оно не пишется в логи. Не надо
ловить и выводить исключения через echo, PHP сам по умолчанию ловит все непойманные исключения, зап
исывает их в лог (который ты можешь позже прочесть) и, если включен display_errors в php.ini, выводи
т информацию об исключении на экран (а если выключен то выводится белая страница, что конечно не оче
нь красиво).
Если ты хочешь выводить красивую страницу-заглушку для пользователя при возникновении исключения, удобнее всего задействовать обработчик непойманных исключений, который задается функцией set_exception
_handler (мануал: http://php.net/manual/ru/function.set-exception-handler.php ). Не забудь выдавать
HTTP-код вроде 500, это положено по стандарту HTTP и это подскажет поисковикам не индексировать стра
ницу ошибки.
Урок про исключения: https://gist.github.com/codedokode/65d43ca5ac95c762bc1a
Ты используешь функции mb_xxx в своем коде, а указал ли ты для них используемую кодировку с помощью
mb_internal_encoding(...)? Без этого эти функции могут неправильно обрабатывать строки.
(это были сообщения от робота, дальше от человека)
> https://github.com/sgscode/students/blob/master/lib/PageNavigator.php#L8
Из-за того, что ты поместил названия колонок внутрь объекта, его нельзя будет использовать с другой таблицей.
> https://github.com/sgscode/students/blob/master/lib/StudentMapper.php#L90
здесь ты выбираешь только часть полей. Этим ты ухудшаешь свой код, так как часть функций у тебя возвращает полностью заполненный объект Student, а часть частитчно заполненный. Как можно писать надежный код, когда непонятно заполнено ли поле в объекте или нет?
Надо либо выбирать все нужные поля, либо возвращать массив вместо объектов. Лучше наверно выбирать все поля.
> https://github.com/sgscode/students/blob/master/lib/Student.php#L63
Валидацию лучше делать снаружи студента. А то так мы например не можем проверить email на уникальность. Ну и не задача студента самого себя проверять. хотя, тут маленькое приложение, наверно и так сойдет.
> https://github.com/sgscode/students/blob/master/lib/bootstrap.php#L16
> $loggedIn = $mapper->isCodeExist($cookieCode);
Если кука пустая, то не надо лезть в базу.
> https://github.com/sgscode/students/blob/master/formpage.php#L46
> while ($mapper->isCodeExist($code)) {
В таких случаях лучше использовать for c ограничением числа попыток, а то в случае какой-то ошибки у тебя может получиться вечный цикл.
> https://github.com/sgscode/students/blob/master/templates/form.php#L62
> style="color: #a94442"
Это надо делать с помощью CSS классов, а не копировать один и тот же стиль
Мелкий баг: если в поиск ввести «Iva» то слово подсвечивается в результатах, а если «iva» то нет. Это исправлять наверно не стоит, а так тут можно было бы использовать например составление регулярки из запроса с игнорированием регистра.
Если ничего не найдено, лучше вместо пустой таблицы выводить «По запросу «...» ничего не найдено. Показать всех студентов.»
Перед результатами поиска стоит выводить надпись «Результаты поиска по запросу «...». Показать всех студентов», чтобы было видно что включен поиск и можно было отменить этот режим.
Если есть всего одна страница, не надо выводить пагинатор.
Дальше ты можешь делать задачу про файлообменник или яваскрипт изучать, если ты с ним особо не знаком.
Анон, я нашел время проверить твой код.
Вообще, сделано хорошо и аккуратно, приятно смотреть. Вот небольшой список замечаний к коду.
В файле ./listpage.php:
> catch (Exception $e) {
> echo $e->getMessage( );
> die( );
> }
Здесь ты ловишь исключение и самостоятельно его выводишь. Это плохая идея, так как об исключении узн
ает пользователь сайта (и ничего не поймет), а ты не узнаешь, так как оно не пишется в логи. Не надо
ловить и выводить исключения через echo, PHP сам по умолчанию ловит все непойманные исключения, зап
исывает их в лог (который ты можешь позже прочесть) и, если включен display_errors в php.ini, выводи
т информацию об исключении на экран (а если выключен то выводится белая страница, что конечно не оче
нь красиво).
Если ты хочешь выводить красивую страницу-заглушку для пользователя при возникновении исключения, удобнее всего задействовать обработчик непойманных исключений, который задается функцией set_exception
_handler (мануал: http://php.net/manual/ru/function.set-exception-handler.php ). Не забудь выдавать
HTTP-код вроде 500, это положено по стандарту HTTP и это подскажет поисковикам не индексировать стра
ницу ошибки.
Урок про исключения: https://gist.github.com/codedokode/65d43ca5ac95c762bc1a
Ты используешь функции mb_xxx в своем коде, а указал ли ты для них используемую кодировку с помощью
mb_internal_encoding(...)? Без этого эти функции могут неправильно обрабатывать строки.
(это были сообщения от робота, дальше от человека)
> https://github.com/sgscode/students/blob/master/lib/PageNavigator.php#L8
Из-за того, что ты поместил названия колонок внутрь объекта, его нельзя будет использовать с другой таблицей.
> https://github.com/sgscode/students/blob/master/lib/StudentMapper.php#L90
здесь ты выбираешь только часть полей. Этим ты ухудшаешь свой код, так как часть функций у тебя возвращает полностью заполненный объект Student, а часть частитчно заполненный. Как можно писать надежный код, когда непонятно заполнено ли поле в объекте или нет?
Надо либо выбирать все нужные поля, либо возвращать массив вместо объектов. Лучше наверно выбирать все поля.
> https://github.com/sgscode/students/blob/master/lib/Student.php#L63
Валидацию лучше делать снаружи студента. А то так мы например не можем проверить email на уникальность. Ну и не задача студента самого себя проверять. хотя, тут маленькое приложение, наверно и так сойдет.
> https://github.com/sgscode/students/blob/master/lib/bootstrap.php#L16
> $loggedIn = $mapper->isCodeExist($cookieCode);
Если кука пустая, то не надо лезть в базу.
> https://github.com/sgscode/students/blob/master/formpage.php#L46
> while ($mapper->isCodeExist($code)) {
В таких случаях лучше использовать for c ограничением числа попыток, а то в случае какой-то ошибки у тебя может получиться вечный цикл.
> https://github.com/sgscode/students/blob/master/templates/form.php#L62
> style="color: #a94442"
Это надо делать с помощью CSS классов, а не копировать один и тот же стиль
Мелкий баг: если в поиск ввести «Iva» то слово подсвечивается в результатах, а если «iva» то нет. Это исправлять наверно не стоит, а так тут можно было бы использовать например составление регулярки из запроса с игнорированием регистра.
Если ничего не найдено, лучше вместо пустой таблицы выводить «По запросу «...» ничего не найдено. Показать всех студентов.»
Перед результатами поиска стоит выводить надпись «Результаты поиска по запросу «...». Показать всех студентов», чтобы было видно что включен поиск и можно было отменить этот режим.
Если есть всего одна страница, не надо выводить пагинатор.
Дальше ты можешь делать задачу про файлообменник или яваскрипт изучать, если ты с ним особо не знаком.
Бредовый ответ. Никуда переходить не надо. Хранить связь многие ко многим можно и в MySQL, и в любой другой реляционной БД.
>>457341
Комментарии у тебя раскособочило, надо было перед строчкой, а не справа писать. Обычно код шире 80-100 символов не пишут.
> $time = $time + $pathTimeBy["time"]; // Обновляем время. Идем вперед плюсуем время
> $time = $time - $pathTimeBy["time"]; // Обновляем время. Идем обратно минусуем время
Вот это неудачная идея, так как эти команды достаточно далеко друг от друга и как-то неудачно выйдя из цикла или поставив if, можно одну из них не выполнить. Можно еще что-то прибавить к time и забыть вычесть.
Лучше сделать по-другому: просто завести новую переменную и не трогать $time:
$newTime = $time + ...;
В остальном, решено хорошо.
Я советую тебе также для расширения кругозора почитать вот эту статью про алгоритмы поиска пути: https://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%BF%D1%83%D1%82%D0%B8
Тот алгоритм, который я предложил, рекурсивный, он наверно хорошо подходит для изучения рекурсии, но довольно неэффективен, особенно на большом массиве точек.
Да любые вопросы, начиная от вопросов по мануалу заканчивая задачками на любые темы. Ты не угадаешь. Так что перечитай мануал и порешай какие-нибудь задачки.
Вот наши задачки с собеседований разной сложности: https://github.com/codedokode/pasta/blob/master/interview-tasks.md
>>457478
> И вот дальше, получается что, в каждом контроллере надо проверять залогинен ли пользователь?
Иногда делают так: в контроллере задают права доступа:
class NewsController extends Controller
{
protected $access = self::ACCESS_PUBLIC;
а базовый контроллер перед вызовом действия проверяет права. Так например делает юи:
http://www.yiiframework.com/doc-2.0/yii-filters-accesscontrol.html
http://rmcreative.ru/blog/post/yii2--kontrol-dostupa
> Если да грузим то что надо если нет то что - перенаправляем или грузим в ту же вьюшку форму для залогинивания?
лучше перенаправлять. И добавлять адрес исходной страницы в URL разумеется чтобы потом вернуться.
>>457501
Может ты не осилил просто что-то? Чтобы пользоваться симфони надо читать доки (много), так просто ты не разберешься.
Да любые вопросы, начиная от вопросов по мануалу заканчивая задачками на любые темы. Ты не угадаешь. Так что перечитай мануал и порешай какие-нибудь задачки.
Вот наши задачки с собеседований разной сложности: https://github.com/codedokode/pasta/blob/master/interview-tasks.md
>>457478
> И вот дальше, получается что, в каждом контроллере надо проверять залогинен ли пользователь?
Иногда делают так: в контроллере задают права доступа:
class NewsController extends Controller
{
protected $access = self::ACCESS_PUBLIC;
а базовый контроллер перед вызовом действия проверяет права. Так например делает юи:
http://www.yiiframework.com/doc-2.0/yii-filters-accesscontrol.html
http://rmcreative.ru/blog/post/yii2--kontrol-dostupa
> Если да грузим то что надо если нет то что - перенаправляем или грузим в ту же вьюшку форму для залогинивания?
лучше перенаправлять. И добавлять адрес исходной страницы в URL разумеется чтобы потом вернуться.
>>457501
Может ты не осилил просто что-то? Чтобы пользоваться симфони надо читать доки (много), так просто ты не разберешься.
Почему ты решил что у анона авторизация сделана сессией?
>>457509
Проверку доступа в контроллере как раз делать тру, так как он отвечает за взаимодействие с пользователем.
>>457512
Посмотри как сделано в том же Юи.
>>457513
Для временного хранения данных удобнее использовать неперсистентное хранилище. Также, я не думаю что анону нужно временное хранение подписок на каналы.
>>457515
Та часть что бизнес-логика — да, в модели. А та часть что проверяет доступ и редиректит, в контроллере.
>>457553
Я не знаю такой книги. Может книга по какому-нибудь фреймворку вроде Yii/Symfony 2?
>>457598
Если ты линуксоид то мучай vi или emacs. А так, Sublime Text есть под линукс вроде тоже.
>>457608
> Можешь вообще весь этот код выдрать из YII и вставить его себе в проект, видоизменив
Это плохая идея так как непонятно как потом импортировать изменения. Умнее будет подключить Юи тогда через композер и подключать нужный класс из него.
Также, есть например Symfony Router который можно использовать отдельно как библиотеку. Я бы выбрал этот вариант.
> Вместо этого называешь и группируешь произвольно, не городя костыли.
Одинаковые вещи лучше называть одинаково во избежание путаницы
> 2 мегабайта кода через интерпретатор,
> тысячу-другую тактов процессора
Ассемблер-тред в другом месте. Не надо сюда это тащить.
> За тысячи sql-запросов в коде
Спорно. Плохо это когда они беспорядочно раскиданы, а не собраны в одном месте.
> нормальный шаблонизатор (XSLT, на крайний случай smarty).
ты устарел. Алсо, я работал с XSLT, он очень громоздкий и неудобный (хотя я знаю что раньше его много где исплоьзовали, и в яндексе и в других компаниях, но это было в прошлой эпохе)
Почему ты решил что у анона авторизация сделана сессией?
>>457509
Проверку доступа в контроллере как раз делать тру, так как он отвечает за взаимодействие с пользователем.
>>457512
Посмотри как сделано в том же Юи.
>>457513
Для временного хранения данных удобнее использовать неперсистентное хранилище. Также, я не думаю что анону нужно временное хранение подписок на каналы.
>>457515
Та часть что бизнес-логика — да, в модели. А та часть что проверяет доступ и редиректит, в контроллере.
>>457553
Я не знаю такой книги. Может книга по какому-нибудь фреймворку вроде Yii/Symfony 2?
>>457598
Если ты линуксоид то мучай vi или emacs. А так, Sublime Text есть под линукс вроде тоже.
>>457608
> Можешь вообще весь этот код выдрать из YII и вставить его себе в проект, видоизменив
Это плохая идея так как непонятно как потом импортировать изменения. Умнее будет подключить Юи тогда через композер и подключать нужный класс из него.
Также, есть например Symfony Router который можно использовать отдельно как библиотеку. Я бы выбрал этот вариант.
> Вместо этого называешь и группируешь произвольно, не городя костыли.
Одинаковые вещи лучше называть одинаково во избежание путаницы
> 2 мегабайта кода через интерпретатор,
> тысячу-другую тактов процессора
Ассемблер-тред в другом месте. Не надо сюда это тащить.
> За тысячи sql-запросов в коде
Спорно. Плохо это когда они беспорядочно раскиданы, а не собраны в одном месте.
> нормальный шаблонизатор (XSLT, на крайний случай smarty).
ты устарел. Алсо, я работал с XSLT, он очень громоздкий и неудобный (хотя я знаю что раньше его много где исплоьзовали, и в яндексе и в других компаниях, но это было в прошлой эпохе)
У тебя оба примера на статических методах. Зачем например нужен make('kokoko') когда есть new Kokoko()? ты любишь усложнять вещи?
>>457616
Рад что тебе понравилось. Решай задачки и приноси решения в тред.
>>457632
Главная особенность класса со статическими методами это то что нельзя создать 2 независимых экземпляра.
То есть ты теряешь преимущества ООП, и код получается более спутанный. А ведь ООП дает тебе возможность сделать программу как набор независимых модулей, а исплоьзуя статические методы ты от этого отказываешься и все связываешь намертво. Это не твой бро ООП.
Ну и тестировать неудобно, хотя это уже второстепенно, но как правило код который неудобно тестировать, невысокого качества и имеет и другие недостатки.
Вот у меня тут это упомянуто: https://gist.github.com/codedokode/e1d31a31b37d5f635057
Не уверен.
>>457792
> $totalPayment = 0 + $openPayment;
0+ забыл убрать?
> $creditSum = $creditSum - $payout;
>\t \t$totalPayment = $totalPayment + $payout;
эти строчки скопированы 2 раза. Попробуй избавиться от повторений.
> \t$creditSum = 39999;
> $payout = 5000;
Это лучше вынести из функции наружу а то у тебя функция позволяет посчитать кредит только на эту сумму и нельзя передать другую.
В остальном, считает верно.
>>457795
> пробовал убирать? что меняется? У тебя собственно зачем он там?
Я думаю он нужен так как иначе выполнится код после if
>>457826
Статические методы на статических. что же вы ООП не любите?
> if (Session::exists("userId")) {
для проверки авторизации логично сделать функцию с таким названием, а не копипастить строчку с работой с сессиией.
Не уверен.
>>457792
> $totalPayment = 0 + $openPayment;
0+ забыл убрать?
> $creditSum = $creditSum - $payout;
>\t \t$totalPayment = $totalPayment + $payout;
эти строчки скопированы 2 раза. Попробуй избавиться от повторений.
> \t$creditSum = 39999;
> $payout = 5000;
Это лучше вынести из функции наружу а то у тебя функция позволяет посчитать кредит только на эту сумму и нельзя передать другую.
В остальном, считает верно.
>>457795
> пробовал убирать? что меняется? У тебя собственно зачем он там?
Я думаю он нужен так как иначе выполнится код после if
>>457826
Статические методы на статических. что же вы ООП не любите?
> if (Session::exists("userId")) {
для проверки авторизации логично сделать функцию с таким названием, а не копипастить строчку с работой с сессиией.
1000 строк sql-кода в модели это нихуя не няшно. Надо хотя бы простые запросы в active records заворачивать. Запросы через 5 таблиц с джойнами, гроупами и конкатенциями в SQL - допустим, можно смириться, хотя эти методы будут самым больным узлом говнокода в проекте, но хоть остальное будет более-менее читаемо. А если еще и SQL намешан с кодом, который должен быть в контроллере - это вообще пиздец, такой проект себе долго будет программиста на замену искать.
Зачем например нужен make('kokoko') когда есть new Kokoko()? ты любишь усложнять вещи?
Читай что такое инверсия зависимостей. И узнаешь что new Kokoko() не всегда хорошо
>Главная особенность класса со статическими методами это то что нельзя создать 2 независимых экземпляра.
Васянь. Это относится синглетону. А тут статика это фасад.
Читай про то что написал выше
Нет, ты читай. Инверсия зависимостей, если она правильно реализована, никак не мешает создавать объекты через new.
А «фасады» приводят к тому что весь код пишется на них и получается процедурная лапша. если ты из секты свидетелей лавареля то в этом треде тебя успех не ждет.
>Открыл оба файла - 0 отличий
Ну да точно. Просто идеон как-то странно сохраняет иногда, после кнопки save выполняет старый код, без изменений.
>пробовал убирать? что меняется? У тебя собственно зачем он там?
Это чтобы в минус баланс не уходил, нам нужно выплачивать сразу весь остаток, а не 5000, для этого и нужен выход из цикла и условие.
>>457909
>0+ забыл убрать?
Просто не привык, что переменную до объявления вообще не надо задавать (до этого был опыт на C# и java).
Для меня до сих пор загадка, где в PHP типы переменных (сейчас читаю про регулярные выражения).
>эти строчки скопированы 2 раза. Попробуй избавиться от повторений.
Я понимаю что криво, но не могу придумать, как по другому сделать.
>Статические методы на статических. что же вы ООП не любите?
Как-то напрягает повсеместное создание экземпляров класса, даже если синглтоном делать все равно на одно действие больше. А так, ну вот есть класс Session со статическими методами достать, положить, проверить. Экземпляры не нужны, вызывается как обычная функция, но все собрано в одном классе. По-моему клево.
>Главная особенность класса со статическими методами это то что нельзя создать 2 независимых экземпляра.
Так а если заранее решить что не нужно вообще ни одного экземпляра.
я просто не совсем понял, как плейсхолдеры в таком виде защитят от sql-инъекций, с виду просто переприсваивается запрос разным переменным и всё.
Лучше использовать именованные плейсхолдеры чтобы не запутаться.
>>458022
Плейсхолдеры защищают от инъекции таким образом что вставляемые через них значения корректно экранируются и заключаются в кавычки и запрос не поменять.
Чтобы понять как плейсхолдеры защищают от инъекций тебе сначала надо понять что такое SQL инъекция и как она работает.
это полный пиздец. нормального orm не завезли? знаки вопроса эти, ой не могу
Выглядеть должно как-то так:
$user->name = $request->post('name');
$user->age = $request->post('age');
$db->insert('users', $user);
А еще лучше, чтобы последняя строка была
$user->save();
Ну и функция конечно неудачная. Ну сам посмотри, 8 аргументов. Ты же сам не запомнишь в каком порядке что передавать, а другой человек тем более. Такого быть не должно.
У тебя же есть ООП. Сделай функцию нормально:
addStudent(Student $student)
{
...
}
Смотри, насколько проще получается.
И в 3-й советую тебе почитать мой урок про дата мапперы.
Не разобрался а лезешь с советами? не надо так.
Есть стандартные паттерны (ActiveRecord, DataMapper уес.). Не надо изобретать свои кривые поделки и пытаться подсунуть их начинающим которые в этой теме плохо разбираются. Странные велосипеды нам не нужны.
Ну и сам посмотри на свой код
> $db->insert('users', $user);
У тебя тут как минимум один аргумент лишний. Если $user это объект определенного класса то зачем передавать имя таблицы? ты что пользователя собрался в разные таблицы сохранять?
И при чем тут $request->post если мы обсуждаем не реализацию класса Request в юи-подобных фреймворках а классы для работы с БД.
Твой пост ничему не учит а лишь запутывает. В нем нет никакой информации и есть какой-то странный велосипедный код. Не надо такие посты писать.
Я codelobster раньше юзал, счас phpstorm на рутрекере стянул. Второй больше ресурсов ест.
Phpstorm платный, для студентов скидка. Если сильно печет можно и крякнуть. Еще есть netbeans, но он ультра уебищный чисто внешне.
notepad++ нормально настраивается, там куча плагинов на все случаи жзни.
попробовал вместо mysql_connect заюзать mysqli_connect - то же самое
Пока весь цивилизованный мир пользуется Vagrant'ом, рузские пхп-ВОВАНЫ денвер ставят. Забавно.
Чем плох денвер? Чем его заменить? Была мысль его установить, но захотелось настроить все самому, чтобы не было лишнего мусора, все официальное, никаких конфигов от васяна.
Использовать ORM штуки пока рано, я только учусь, нужно основы познать.
Все тот же ньюфаг.
> Чем плох денвер?
ВОВАНоподелие, которое поставит тебе пхп 5.3 и ссаный апач.
> Чем его заменить?
Vagrant. Ну или Cloud IDE типа https://c9.io (рекомендую) или https://koding.com
Да хотя бы OpenServer. Ну и у PHP так-то встроенный веб-сервер есть.
Идите вон если сказать по делу нечего.
>>458177
Тебе возможно надо просто рзрешить расширения pdo или mysqli в php.ini. Погугли немного сам на тему «как установитьь расширение X под Y»
http://php.net/manual/ru/install.windows.extensions.php
Вот например
>>458179
да, 5.3 совсем старый. Лучше конечно самому ставить Апач/PHP/mysql у меня и мануалы имеются:
https://gist.github.com/codedokode/7054af4a03865c4cc863
https://gist.github.com/codedokode/10774100
https://gist.github.com/codedokode/10539568
> Vagrant. Ну или Cloud IDE
Ты пишешь полную чушь. ВО-первых php прекрасно работает под Windows/linux/mac. Во вторых если тебе нужен линукс всегда можно поднять виртуалку в виртуалбокс. А теперь объясни зачем здесь вагрант?
Ну а «клауд иде» это вообще край.
Человек спрашивает как ему кстановить расширение под php ты еиу предлагаешь перейти на браузерную недоиде в которой все равно это расширение надо включать точно так же через правку php.ini. ну не дебил ли а ?
Идите вон если сказать по делу нечего.
>>458177
Тебе возможно надо просто рзрешить расширения pdo или mysqli в php.ini. Погугли немного сам на тему «как установитьь расширение X под Y»
http://php.net/manual/ru/install.windows.extensions.php
Вот например
>>458179
да, 5.3 совсем старый. Лучше конечно самому ставить Апач/PHP/mysql у меня и мануалы имеются:
https://gist.github.com/codedokode/7054af4a03865c4cc863
https://gist.github.com/codedokode/10774100
https://gist.github.com/codedokode/10539568
> Vagrant. Ну или Cloud IDE
Ты пишешь полную чушь. ВО-первых php прекрасно работает под Windows/linux/mac. Во вторых если тебе нужен линукс всегда можно поднять виртуалку в виртуалбокс. А теперь объясни зачем здесь вагрант?
Ну а «клауд иде» это вообще край.
Человек спрашивает как ему кстановить расширение под php ты еиу предлагаешь перейти на браузерную недоиде в которой все равно это расширение надо включать точно так же через правку php.ini. ну не дебил ли а ?
phpstorm (есть бесплатная версия)
netbeans
Sublime text (не полноценная Иде, а просто блокнот с подсветкой)
>>458048
phpstorm вроде как-то можно бесплатно юзать по какой-то программе раннего тестирования или как-то так
>>458150
Расширение mysql давно устарело. Это значит ты учишься по какому-то древнему учебнику так как устарело оно уже лет 5 назад если не больше.
Изучай mysqli или pdo, информации в гугле и на хабре полно.
>>458167
Тебе надо установить или разрешить расширение mysqli и может еще что-то. Гугли.
>>458171
Прежде чем браться за ОРМ надо изучить SQL и низкоуровневые DBAl. Зачем ты даешь заведомо неправильные советы и пытаешься запутать людей? Здесь еды нету, уходи.
>>458176
дебил? что php без вагранта медленнее работает что ли? зачем он вообще нужен? Зачем ты даешь заведомо неправильные советы и пытаешься запутать людей? Здесь еды нету, уходи.
Анон спрашивал как ему работать с БД, а не как установить еще одну бесполезную программу.
>>458177
Самому ставить и настраивать полезнее всего. Правильно мыслишь.
> Использовать ORM штуки пока рано,
тут ты тоже прав
phpstorm (есть бесплатная версия)
netbeans
Sublime text (не полноценная Иде, а просто блокнот с подсветкой)
>>458048
phpstorm вроде как-то можно бесплатно юзать по какой-то программе раннего тестирования или как-то так
>>458150
Расширение mysql давно устарело. Это значит ты учишься по какому-то древнему учебнику так как устарело оно уже лет 5 назад если не больше.
Изучай mysqli или pdo, информации в гугле и на хабре полно.
>>458167
Тебе надо установить или разрешить расширение mysqli и может еще что-то. Гугли.
>>458171
Прежде чем браться за ОРМ надо изучить SQL и низкоуровневые DBAl. Зачем ты даешь заведомо неправильные советы и пытаешься запутать людей? Здесь еды нету, уходи.
>>458176
дебил? что php без вагранта медленнее работает что ли? зачем он вообще нужен? Зачем ты даешь заведомо неправильные советы и пытаешься запутать людей? Здесь еды нету, уходи.
Анон спрашивал как ему работать с БД, а не как установить еще одну бесполезную программу.
>>458177
Самому ставить и настраивать полезнее всего. Правильно мыслишь.
> Использовать ORM штуки пока рано,
тут ты тоже прав
начинающему лучше самому себе все поставить. как минимум быстрее работать будет и не будет зависеть от состояния интернета и кучи удаленных серверов.
> Там есть виртуальные бд или что? Или как там данные хранить?
Не знаю, если тебе интересно лучше всего наверно на сайт зайти и почитать faq
Короче, есть железка с белым айпи, к которой я хочу приконнектиться, чтобы пинговать серые айпишники. Как это реализовать в клауд9?
В общем есть код окторый я написал до этого: http://ideone.com/jKnvgR
Писав его я старался как можно больше нахитрить, что бы избежать копипасты и прочей фигни, ну типа вместо 4х однотипных функций у меня есть функция public function countDepStuff($stuff)
В которой можно посчитать зарплату, кофе, и отчеты передавая туда лишь название того, что мы собственно считаем.
Далее у меня есть хитрый способ заплнять департаменты:
\tpublic function addWorkers($amount, $class, $rank, $leader) {
И вот комментарий ОП-а на эту тему аж в позапрошлом треде: >>453544
К которому я так и не могу подойти.
>Это лучше вынести из департамента. А то у тебя нельзя просто создать объект работника и добавить в департамент. Лучше сделать функцию вида
>addEmployee(Employee $employee)
Я просто не могу догнать как это реализовать можно или нужно? В каком месте мне нужно создавать работников тогда? Нельзя же в классе Employee сделать функцию, которая бы создавала объекты своих наследников? Я реально на этом на неделю завис уже.
Вот переделал код слегка, и исправил замечания, кроме создания employee, которое я так и не понимаю как реализовать. Пока все нормально?
Я уже подумываю Netbeans поставить, и установить какую-нибудь бд вручную, а то в пхпшторме все непрозрачно как-то.
1) Для классов-утилит (вроде Math в яваскрипте). Ну например если у тебя есть метод вроде «обрезать строку до N символов» или метод перевода миль в километры, то можно сделать его статическим методом в классе Util.
http://en.wikipedia.org/wiki/Utility_pattern
2) для методов, которые не привязаны к конкретному объекту, например «получить название профессии по ее коду»
$jobTitle = Worker::getJobTitle(Worker::JOB_MANAGER);
3) для реализации паттернов вроде Singleton (который сам по себе не очень удачен)
То есть, как видишь, эти методы нужны довольно редко.
В случае который анон приводил выше, гораздо лучше и удобнее использовать объекты. Он например приводил пример работы с сессией:
Session::set('x', 1);
Использовать тут объект гораздо гибче:
$session->set('x', 1)
Так как мы можем тогда иметь несколько разных сессий, например сессии с разным типом хранения данных или временем, а также можем передавать классы-заглушки при тестировании, например.
Ну и соответственно, большинство классов в твоем приложении тогда должны создаваться как-то так:
// Класс работающий с постами
$postService = new PostService($orm, $imageManager, $fileManager);
То есть с явной передачей зависимостей в конструктор, а не прописыванием их в виде статических вызовов. Это описано тут: https://gist.github.com/codedokode/e1d31a31b37d5f635057
Это позволяет разбить код на относительно независимые друг от друга модули.
Злоупотребление статическими методами делает код спутанным.
В принципе, их можно было бы использовать в контроллерах (так как контроллер все равно имеет доступ к любому классу), но если в фреймворке есть статические методы, люди начинают их писать не только в контроллерах, но и в моделях, сервисах, везде.
1) Для классов-утилит (вроде Math в яваскрипте). Ну например если у тебя есть метод вроде «обрезать строку до N символов» или метод перевода миль в километры, то можно сделать его статическим методом в классе Util.
http://en.wikipedia.org/wiki/Utility_pattern
2) для методов, которые не привязаны к конкретному объекту, например «получить название профессии по ее коду»
$jobTitle = Worker::getJobTitle(Worker::JOB_MANAGER);
3) для реализации паттернов вроде Singleton (который сам по себе не очень удачен)
То есть, как видишь, эти методы нужны довольно редко.
В случае который анон приводил выше, гораздо лучше и удобнее использовать объекты. Он например приводил пример работы с сессией:
Session::set('x', 1);
Использовать тут объект гораздо гибче:
$session->set('x', 1)
Так как мы можем тогда иметь несколько разных сессий, например сессии с разным типом хранения данных или временем, а также можем передавать классы-заглушки при тестировании, например.
Ну и соответственно, большинство классов в твоем приложении тогда должны создаваться как-то так:
// Класс работающий с постами
$postService = new PostService($orm, $imageManager, $fileManager);
То есть с явной передачей зависимостей в конструктор, а не прописыванием их в виде статических вызовов. Это описано тут: https://gist.github.com/codedokode/e1d31a31b37d5f635057
Это позволяет разбить код на относительно независимые друг от друга модули.
Злоупотребление статическими методами делает код спутанным.
В принципе, их можно было бы использовать в контроллерах (так как контроллер все равно имеет доступ к любому классу), но если в фреймворке есть статические методы, люди начинают их писать не только в контроллерах, но и в моделях, сервисах, везде.
Если «серые» IP адреса это адреса локальных сетей за NAT то очевидно никак. Потому они и серые что не маршрутизуются глобально и к ним нельзя отправлять пакеты извне.
>>458264
Заходим в гугл с правильно составленным запросом: http://www.google.ru/search?sourceid=chrome&ie=UTF-8&q=php+pdo+sqlite
На первой странице мануала находим слова DSN и переходим по ссылке http://php.net/manual/ru/ref.pdo-sqlite.connection.php
Смотрим примеры DSN там.
Ты делаешь неправильно. JDBC — это специальный драйвер-посредник для универсального доступа к любой БД (но чтобы им пользоваться ты должен его установить и запустить, это отдельная программа, почитай вики: https://ru.wikipedia.org/wiki/Java_Database_Connectivity ). Тебе JDBC не нужен так как PDO умеет работать с sqlite напрямую.
>>458267
PhpStorm тут вообще не при чем. Если ты написал неправильный код как тебе поможет смена редактора? Ну сам-то подумай.
Ну и напомню еще определение статического метода: это метод, который не использует поля и обычные методы объекта (то есть не использует $this).
Соответственно если твой метод не требует наличия объекта то делай его статическим. Это довольно редко встречается.
Сессию определенно лучше сделать объектом, так как это отдельная сущность и никто не запрещает иметь несколько сессий (например, сессия текущего пользователя и сессия какого-нибудь другого пользователя которую мы зачем-то загрузили в память).
> Писав его я старался как можно больше нахитрить, что бы избежать копипасты
Это хорошо, но ты помни что на первом месте должна быть понятность кода. Код пишется для людей и надо писать его так, чтобы его можно было максимально легко прочесть, понять и например исправить.
> функция public function countDepStuff($stuff)
Вот это можно было не оптимизировать, если бы ты сделал 4 функции, то ничего страшного. Ну твой вариант в общем тоже годится, но не стоит тут переусердстовавть вот с такими обращениями:
> $worker->$stuff;
Они плохи тем, что если ты захочешь найти поиском все места где например идет обращение к полю $worker->salary то с доступом через переменную их найти сложнее.
Также, если нам надо будет прописать более сложные правила расчета общей зарплаты (не просто сложить, а например еще на то-нибудь домножить), то код функции countStuff будет усложняться.
Ну и в коде появляются «магические» строки вроде такой:
> $dep->countDepStuff("salary")
> "salary"
Глядя на этот код во первых непонятно откуда взялось salary, во вторых какие еще варианты мы можем передать (чтобы это понять надо разобрать функцию countStufff и все другие функции которые она вызывает).
То есть в общем, тут наверно эту оптимизацию делать не стоило. На этой маленькой программе конечно разницы особой нет, но в больших приложениях каждое такое усложнение делает код более запутанным.
Теперь перейдем к замечаниям:
Вот смотри, простой тест твоего класса Работник:
http://ideone.com/ADaj6h
Мы повышаем работнику ранг, но зарплата не повышается. Почему?
Вот представь что я твой коллега и хочу использовать твой класс. Я пишу код, а он не работает. Мне придется тратить время на анализ кода, отладку, выяснять что сделано не так. Разве это хорошо?
Твоя ошибка в том что ты сделал поле salary для хранения зарплаты, но оно не обновляется само при изменении ранга. Лучше сделать получение зарплаты через метод вроде getSalary() а само поле убрать чтобы никто не пытался к нему обращаться.
Также, ты бы мог закрыть поле rank от прямого доступа и сделать изменение ранга только через метод setRank (там же можно кстати сделать проверку что ранг должен быть от 1 до 3).
В ООП каждый класс это как независимый модуль. Ну например объект-работник это модуль, который содержит информацию о работнике и умеет рассчитывать некоторые вещи (зарплату, потребление кофе и тд). Я не создавал департамент или компанию, а создал только один объект-работника. Но и в этом случае все должно работать.
> Писав его я старался как можно больше нахитрить, что бы избежать копипасты
Это хорошо, но ты помни что на первом месте должна быть понятность кода. Код пишется для людей и надо писать его так, чтобы его можно было максимально легко прочесть, понять и например исправить.
> функция public function countDepStuff($stuff)
Вот это можно было не оптимизировать, если бы ты сделал 4 функции, то ничего страшного. Ну твой вариант в общем тоже годится, но не стоит тут переусердстовавть вот с такими обращениями:
> $worker->$stuff;
Они плохи тем, что если ты захочешь найти поиском все места где например идет обращение к полю $worker->salary то с доступом через переменную их найти сложнее.
Также, если нам надо будет прописать более сложные правила расчета общей зарплаты (не просто сложить, а например еще на то-нибудь домножить), то код функции countStuff будет усложняться.
Ну и в коде появляются «магические» строки вроде такой:
> $dep->countDepStuff("salary")
> "salary"
Глядя на этот код во первых непонятно откуда взялось salary, во вторых какие еще варианты мы можем передать (чтобы это понять надо разобрать функцию countStufff и все другие функции которые она вызывает).
То есть в общем, тут наверно эту оптимизацию делать не стоило. На этой маленькой программе конечно разницы особой нет, но в больших приложениях каждое такое усложнение делает код более запутанным.
Теперь перейдем к замечаниям:
Вот смотри, простой тест твоего класса Работник:
http://ideone.com/ADaj6h
Мы повышаем работнику ранг, но зарплата не повышается. Почему?
Вот представь что я твой коллега и хочу использовать твой класс. Я пишу код, а он не работает. Мне придется тратить время на анализ кода, отладку, выяснять что сделано не так. Разве это хорошо?
Твоя ошибка в том что ты сделал поле salary для хранения зарплаты, но оно не обновляется само при изменении ранга. Лучше сделать получение зарплаты через метод вроде getSalary() а само поле убрать чтобы никто не пытался к нему обращаться.
Также, ты бы мог закрыть поле rank от прямого доступа и сделать изменение ранга только через метод setRank (там же можно кстати сделать проверку что ранг должен быть от 1 до 3).
В ООП каждый класс это как независимый модуль. Ну например объект-работник это модуль, который содержит информацию о работнике и умеет рассчитывать некоторые вещи (зарплату, потребление кофе и тд). Я не создавал департамент или компанию, а создал только один объект-работника. Но и в этом случае все должно работать.
Теперь поясню про департаменты, тоже в виде кода. Допустим у меня есть организация, департамент и 3 работника: http://ideone.com/pyk7cq
Как их устроить на работу в этот департамент?
> Далее у меня есть хитрый способ заплнять департаменты:
это как раз плохой способ. Я не могу добавить в департамент кого хочу. Неудобно.
Если ты хочешь упростить создание работников то сделай отдельную функцию за пределами департамента.
> В каком месте мне нужно создавать работников тогда?
через new либо отдельной функцией или классом (EmployeeFactory — объекты, которые производят другие объекты, называют фабриками).
> Нельзя же в классе Employee сделать функцию, которая бы создавала объекты своих наследников?
Разумеется нельзя.
> Я реально на этом на неделю завис уже.
Задавай уточняющие вопросы, я поясню.
Нужна ли книга "Пхп и Мускул" Кевина Янка?
>>458304
Спасибо большое, вроде бы все стало яснее, особенно вот это
>через new либо отдельной функцией или классом (EmployeeFactory — объекты, которые производят другие объекты, называют фабриками).
Пока что фабрика мне кажется неплохим решением, приду домой через час и постараюсь исправить этот ньюанс, и то что ты выше писал про поле salary
Ок, фабрика вполне подойдет. Ты даже можешь сделать метод создания статическим если хочешь.
И еще. ты читал в мануале что такое private/protected/public? С их помощью ты можешь ограничивать доступ к полям и методам снаружи. Я советую тебе их использовать в этой задаче и закрыть свойства от доступа снаружи, это сделает код надежнее.
Также, если я тебе не давал дополнительное антикризисное задание к этой задаче, то его надо будет тоже решить, опять же чтобы ты лучше понимал ООП.
залил страницу , интерпретатор постоянно ругается на строку mysql_connect
Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO
Синтаксис функции и данные проверил, всё правильно.
С чем может быть связано?
Давал, только я почитал, и примерно понял, что там нужно сначала исправить такие вещи как добавление и убавление работников, а так же манипуляцию с ранками, что бы было легко РАСШИРЯТЬ код. И так как изначально я писал код только под эту задачу, то у меня тупик вышел естественно с этим, и я сначала пытаюсь исправлять недочеты которые ты указал.
Перевести не пробовал или в мануал заглянуть? Расширение mysql устарело и скоро будет удалено из php. Используй более новый учебник а не написанный 10 лет назад.
Например переходи на PDO: http://habrahabr.ru/post/137664/
>>458316
> что там нужно сначала исправить такие вещи как добавление и убавление работников, а так же манипуляцию с ранками, что бы было легко РАСШИРЯТЬ код.
Верно. Те 2 примера кода что я тебе дал, как раз показывают что тут пока не все идеально.
> и я сначала пытаюсь исправлять недочеты которые ты указал.
Эти исправления помогут тебе и при решении дополнительного задания.
Ты внимательно прочел лог? Смотри что там написано:
> request: "GET /uploads/images/d93469a4458daecae04d4f8dd606930f2b337fea.jpg
Это не запрос на загрузку картинки, а на ее скачивание с сервера. Следовательно эта запись не имеет отношения к проблеме (плюс, как я понимаю, там еще и время другое).
Тот лог, что ты привел, это лог нгинкса. Если загрузка файла на сервер идет через php то там наверняка есть лог ошибок php (или же если там используется какой-нибудь странный фрйемворк то он может перехватывать ошибки и направлять их в свой лог). Найди эти логи и изучи.
Также имей в виду что для решения проблемы скорее всего понадобится знание php.
Заведи переменную, запиши в нее ноль, каждый раз когда видишь высокого одноклассника, увеличивай эту переменную на 1.
class Controller_profile
{
private $input = false;
public function construct() {
$input = Input::getPost();
}
}
Где
class Input {
public static function getAll () {
return $_POST;
}
}
Атрибут action=" в таком случае, получается, можно оставлять пустым?
>Верно. Те 2 примера кода что я тебе дал, как раз показывают что тут пока не все идеально.
Да я и так по сути все понимал, просто прочитал недавно статью на хабре, о том что переписывать рабочий код с 0 - плохо, и нужно учиться над ним работать, а не делать поновой те же велосипеды. Хотя возможно для учебных задач и можно так делать, ибо когда у тебя код как запутанный клубок и если правишь в одном месте и ломается другое, то действительно небольшой обьем можно было и переписать. В общем не знаю что сказать еще, спасибо что возишься со мной.
Во-первых, читал ли ты мой урок про работу с формами? Прочти.
https://github.com/codedokode/pasta/blob/master/forms.md
Во-вторых, в MVC ты обычно просто выделяешь действие (экшен) в контроллере для работы с формой. То есть у тебя есть например контроллер News и в нем метод listAction для просмотра списка новостей и editAction для редактирования и создания новости. Он и форму выводит и принимает отправленные ей данные.
> А тут - не пойму, по идее надо в контроллер, но где там ловить?
Лучше использовать общепринятые обозначения, так как я например не понимаю, что значит «ловить». Если ты спрашиваешь, что прописывать к качестве action у формы то обычно используют тот же URL что и для отображения формы. И конечно запрос отправленный при заполнении формы должен обрабатывать контроллер, а как же иначе.
> Атрибут action=" в таком случае, получается, можно оставлять пустым?
Да, либо, что лучше, вписывать туда URL явно.
> Вот раньше в процедурных деревнх я заводил файл operations.php, все формы направлял туда, там ловил имя нажатого субмита,
это в общем плохая идея, так как файл получается огромный. Ты с таким же успехом можешь вообще все приложение в index.php засунуть, только удобно ли будет с ним работать?
Еще один совет. Не изобретай велосипеды. Или хотя бы прежде чем изобретать, посмотри как это принято делать, а потом изобретай свое. Никому из программистов не нравится разбирать потом написанный таким «изобретателем» код. Если есть общепринятые стандарты и подходы, надо использовать их.
В твоем случае я советую изучить фреймворк вроде Yii 2 и Symfony 2 и смотреть как реализовано MVC там, а не придумывать какие-то свои вещи.
Вот что у тебя плохо:
> class Controller_profile
Зачем ты изобретаешь свой стандарт именования классов? Есть стандарт PSR-1, которого придерживается большинство фреймворков:
http://www.php-fig.org/psr/psr-1/ru/
> Классам НЕОБХОДИМО давать имена в стиле StudlyCaps.
Далее, надо писать не ControllerProfile, а ProfileController иначе это переводится не контроллер профиля, а профиль контроллера.
Далее,
> Input::getPost( );
Не используй тут статический метод, данные запроса это отдельная сущность для которой стоит создать отдельный объект.
Далее, сами данные запроса принято называть Request а не Input. Более того, готовится стандарт PSR-7 который описывает как должен выглядеть класс хранящий эти данные:
https://github.com/php-fig/fig-standards/blob/master/proposed/http-message.md#321-psrhttpmessageserverrequestinterface
Пока этот стандарт не вступил в силу, фреймворки придумывали свои классы. Вот как класс Request в Юи 2: http://www.yiiframework.com/doc-2.0/yii-web-request.html
Вот русский мануал:
https://github.com/yiisoft/yii2/blob/master/docs/guide-ru/runtime-requests.md
Вот русский мануал по работе с формами в Юи: https://github.com/yiisoft/yii2/blob/master/docs/guide-ru/start-forms.md
Вот как выглядит класс Request в Симфони 2:
http://symfony-gu.ru/documentation/ru/html/book/http_fundamentals.html
http://api.symfony.com/2.0/Symfony/Component/HttpFoundation/Request.html (англ)
Почитай сначала как это сделано в фреймворках, а потом изобретай свои варианты этого класса.
Если у тебя есть еще вопросы, я буду рад ответить.
Во-первых, читал ли ты мой урок про работу с формами? Прочти.
https://github.com/codedokode/pasta/blob/master/forms.md
Во-вторых, в MVC ты обычно просто выделяешь действие (экшен) в контроллере для работы с формой. То есть у тебя есть например контроллер News и в нем метод listAction для просмотра списка новостей и editAction для редактирования и создания новости. Он и форму выводит и принимает отправленные ей данные.
> А тут - не пойму, по идее надо в контроллер, но где там ловить?
Лучше использовать общепринятые обозначения, так как я например не понимаю, что значит «ловить». Если ты спрашиваешь, что прописывать к качестве action у формы то обычно используют тот же URL что и для отображения формы. И конечно запрос отправленный при заполнении формы должен обрабатывать контроллер, а как же иначе.
> Атрибут action=" в таком случае, получается, можно оставлять пустым?
Да, либо, что лучше, вписывать туда URL явно.
> Вот раньше в процедурных деревнх я заводил файл operations.php, все формы направлял туда, там ловил имя нажатого субмита,
это в общем плохая идея, так как файл получается огромный. Ты с таким же успехом можешь вообще все приложение в index.php засунуть, только удобно ли будет с ним работать?
Еще один совет. Не изобретай велосипеды. Или хотя бы прежде чем изобретать, посмотри как это принято делать, а потом изобретай свое. Никому из программистов не нравится разбирать потом написанный таким «изобретателем» код. Если есть общепринятые стандарты и подходы, надо использовать их.
В твоем случае я советую изучить фреймворк вроде Yii 2 и Symfony 2 и смотреть как реализовано MVC там, а не придумывать какие-то свои вещи.
Вот что у тебя плохо:
> class Controller_profile
Зачем ты изобретаешь свой стандарт именования классов? Есть стандарт PSR-1, которого придерживается большинство фреймворков:
http://www.php-fig.org/psr/psr-1/ru/
> Классам НЕОБХОДИМО давать имена в стиле StudlyCaps.
Далее, надо писать не ControllerProfile, а ProfileController иначе это переводится не контроллер профиля, а профиль контроллера.
Далее,
> Input::getPost( );
Не используй тут статический метод, данные запроса это отдельная сущность для которой стоит создать отдельный объект.
Далее, сами данные запроса принято называть Request а не Input. Более того, готовится стандарт PSR-7 который описывает как должен выглядеть класс хранящий эти данные:
https://github.com/php-fig/fig-standards/blob/master/proposed/http-message.md#321-psrhttpmessageserverrequestinterface
Пока этот стандарт не вступил в силу, фреймворки придумывали свои классы. Вот как класс Request в Юи 2: http://www.yiiframework.com/doc-2.0/yii-web-request.html
Вот русский мануал:
https://github.com/yiisoft/yii2/blob/master/docs/guide-ru/runtime-requests.md
Вот русский мануал по работе с формами в Юи: https://github.com/yiisoft/yii2/blob/master/docs/guide-ru/start-forms.md
Вот как выглядит класс Request в Симфони 2:
http://symfony-gu.ru/documentation/ru/html/book/http_fundamentals.html
http://api.symfony.com/2.0/Symfony/Component/HttpFoundation/Request.html (англ)
Почитай сначала как это сделано в фреймворках, а потом изобретай свои варианты этого класса.
Если у тебя есть еще вопросы, я буду рад ответить.
> переписывать рабочий код с 0 - плохо, и нужно учиться над ним работать, а не делать поновой те же велосипеды.
Да, это правильно, так как с точки зрения бизнеса от переписывания кода одни убытки (на зарплату программиста), а прибыль от этого не увеличится.
Но в нашем случае твое время пока ничего не стоит (как бы это тебя не огорчало) и мы можем себе позволить его хоть 3 раза переписать. В учебных задачах мы стремимся к максимально правильному коду, в рабочих — решить задачу с минимальными затратами. Ну и мы надеемся что помучавшись сейчас с доведением кода до идеала ты потом с первого раза будешь писать его правильно.
А так да, в бизнесе больше всего любят тех кто умеет все делать быстро, а не устраивать рефакторинг каждые 2 недели или жаловаться на качество кода.
> ибо когда у тебя код как запутанный клубок и если правишь в одном месте и ломается другое,
Это значит что код плохой. Помнишь, я писал выше что классы (должны быть как) — независимые модули? В таком коде сломать все гораздо труднее.
А если ты вдобавок используешь тесты, то проблема будет легко обнаружена до выкладывания кода в продакшен (обзорный урок про тестирование у меня тоже есть, если что).
Лол. Какая лапша?
ProductController {
protected $repository;
public function __construct(IProductRepository $repository) {
$this->repository = $respository;
}
}
Опиши минусы такого решения касательно laravel.
'Ловить' всмысле if (isset($_POST['submit_edit_profile'])) и так далее.
>Во-вторых, в MVC ты обычно просто выделяешь действие (экшен) в контроллере для работы с формой. То есть у тебя есть например контроллер News и в нем метод listAction для просмотра списка новостей и editAction для редактирования и создания новости. Он и форму выводит и принимает отправленные ей данные.
Вот об этом хотелось бы поподробнее. Вот смотри, как я вижу алгоритм работы приложения.
Направляем все запросы в индекс.
Подключаем в индекс конфиг с константами для БД и прочего.
Подключаем базовые классы Модель, Контроллер, Вид, от которых наследуются дочерние, типа Контроллер_профиль (да, в курсе был насчет правил именования, когда делал думал так нагляднее будет, руки не доходят поправить).
Подключаем класс Роутер и запускаем метод start(). Он разбивает url, составляет имя файла с классом переданного контроллера и подключает его. То есть к этому моменту индексный файл выглядит как-то как на пике
При этом если url будет вида localhost/profile/edit роутер найдет в классе Контроллер_профиль экшен edit и запустит его, это понятно и этот функционал у меня реализован. И если дальше будут параметры, например edit/18/ - тоже. А как мне вызвать этот экшен не из url, а, например, после нажатия на субмит? Я ж не буду делать субмит ссылкой типа a href='localhost/profile/edit'
Разбирать фреймворки не очень получается, точнее как бы мне не приходит в голову что input::getPost() это плохо и надо как-то по-другому.
Спасибо за усердие.
Для контроллеров обычно не применяют DI, обычно контроллер имеет доступ к любым объектам. То есть в той же симфони в контроллере через
$this->getContainer()->get('some_service');
можно получить что угодно.
А вот сервисы уже пишутся с использованием DI.
> Опиши минусы такого решения касательно laravel.
Не знаю, какие минусы есть в этом решении. Мне lavarel не нравится так что я скорее в нем минусы найду.
> Какая лапша?
Доступность статических методов приводит к тому что их используют везде, в том числе в сервисах, моделях, вместо DI, что приводит к спутанному коду.
Возьмем пример из доков лавареля:
http://laravel.com/docs/5.0/requests
> $name = Request::input('name');
Ну это же типичный быдлокод. Он подразумевает что
1) реквест — глобальная переменная доступная в любом месте кода
2) в любой момент в приложении ровно один реквест
А как должно быть? Мне кажется должно быть как например в Симфони:
$reponse = $app->handle($request);
Красиво и логично: приложение получает на вход реквест и генерирует респонс.
Ну или возьмем например популярный HTTP фреймворк для ноды под названием Express:
http://expressjs.com/starter/hello-world.html
> app.get('/', function (req, res) {
> res.send('Hello World!');
> });
Функция-контроллер получает на вход реквест и заготовку респонса. Здесь реквест лишь локальная переменнная, а не глобальная.
Разработики лавареля думают что они умные и не такие как все, а на самом деле они обычные велосипедисты. Как и авторы руби он рельс кстати, которым они вдохновляются.
Для контроллеров обычно не применяют DI, обычно контроллер имеет доступ к любым объектам. То есть в той же симфони в контроллере через
$this->getContainer()->get('some_service');
можно получить что угодно.
А вот сервисы уже пишутся с использованием DI.
> Опиши минусы такого решения касательно laravel.
Не знаю, какие минусы есть в этом решении. Мне lavarel не нравится так что я скорее в нем минусы найду.
> Какая лапша?
Доступность статических методов приводит к тому что их используют везде, в том числе в сервисах, моделях, вместо DI, что приводит к спутанному коду.
Возьмем пример из доков лавареля:
http://laravel.com/docs/5.0/requests
> $name = Request::input('name');
Ну это же типичный быдлокод. Он подразумевает что
1) реквест — глобальная переменная доступная в любом месте кода
2) в любой момент в приложении ровно один реквест
А как должно быть? Мне кажется должно быть как например в Симфони:
$reponse = $app->handle($request);
Красиво и логично: приложение получает на вход реквест и генерирует респонс.
Ну или возьмем например популярный HTTP фреймворк для ноды под названием Express:
http://expressjs.com/starter/hello-world.html
> app.get('/', function (req, res) {
> res.send('Hello World!');
> });
Функция-контроллер получает на вход реквест и заготовку респонса. Здесь реквест лишь локальная переменнная, а не глобальная.
Разработики лавареля думают что они умные и не такие как все, а на самом деле они обычные велосипедисты. Как и авторы руби он рельс кстати, которым они вдохновляются.
Классы принято хранить в отдельных файлах, 1 файл = 1 класс, имя файла соответствует с точностью до регистра букв имени класса.
SomeClass => SomeClass.php
Подробнее: PSR-4 http://www.php-fig.org/psr/psr-4/ru/
Соответственно тогда тебе не надо будет подключать их руками, а можно использовать автозагрузчик. Причем если ты следуешь PSR-4 то например в композере (это такая программа для установки библиотек: http://habrahabr.ru/post/145946/ ) уже есть готовый загрузчик соответствующий этому стандарту.
> Подключаем класс Роутер и запускаем метод start(). Он разбивает url, составляет имя файла с классом переданного контроллера и подключает его.
Тогда это не роутер. роутер ничего не подключает, а просто анализирует URL и возвращает например имя контроллера, дейтсвие и дополнительные параметры.
> А как мне вызвать этот экшен не из url, а, например, после нажатия на субмит?
А что происходит после нажатия на субмит? Что делает браузер? Что происходит на сервере?
Я не вижу почему запросы от форм должны обрабатываться каким-то особым образом, а не точно так же как и любые другие.
> Я ж не буду делать субмит ссылкой типа a href='localhost/profile/edit'
Тебе надо сначала изучить как работает HTTP и что происходит при отправке формы, я вижу ты этого не знаешь.
Тут конечно есть проблема: я не знаю хорошего сайта, где бы это объяснялось. Вот, попробуй извлечь что-то полезное из этих ссылок:
http://habrahabr.ru/post/215117/
http://phpclub.ru/detail/article/http_request
Что я хочу сказать: отправка формы вызывает отправку браузером HTTP-запроса на сервер и ты обрабатываешь его точно так же как и например запрос на получение страницы. Там точно так же есть URL которй можно разбирать роутером.
> Разбирать фреймворки не очень получается, точнее как бы мне не приходит в голову что input::getPost() это плохо и надо как-то по-другому.
Для изучения фреймворка надо читать документацию с начала, а не одну главу. Если бы ты изучил например Юи вместо придумывания странных велосипедов ты бы получил гораздо больше пользы.
Классы принято хранить в отдельных файлах, 1 файл = 1 класс, имя файла соответствует с точностью до регистра букв имени класса.
SomeClass => SomeClass.php
Подробнее: PSR-4 http://www.php-fig.org/psr/psr-4/ru/
Соответственно тогда тебе не надо будет подключать их руками, а можно использовать автозагрузчик. Причем если ты следуешь PSR-4 то например в композере (это такая программа для установки библиотек: http://habrahabr.ru/post/145946/ ) уже есть готовый загрузчик соответствующий этому стандарту.
> Подключаем класс Роутер и запускаем метод start(). Он разбивает url, составляет имя файла с классом переданного контроллера и подключает его.
Тогда это не роутер. роутер ничего не подключает, а просто анализирует URL и возвращает например имя контроллера, дейтсвие и дополнительные параметры.
> А как мне вызвать этот экшен не из url, а, например, после нажатия на субмит?
А что происходит после нажатия на субмит? Что делает браузер? Что происходит на сервере?
Я не вижу почему запросы от форм должны обрабатываться каким-то особым образом, а не точно так же как и любые другие.
> Я ж не буду делать субмит ссылкой типа a href='localhost/profile/edit'
Тебе надо сначала изучить как работает HTTP и что происходит при отправке формы, я вижу ты этого не знаешь.
Тут конечно есть проблема: я не знаю хорошего сайта, где бы это объяснялось. Вот, попробуй извлечь что-то полезное из этих ссылок:
http://habrahabr.ru/post/215117/
http://phpclub.ru/detail/article/http_request
Что я хочу сказать: отправка формы вызывает отправку браузером HTTP-запроса на сервер и ты обрабатываешь его точно так же как и например запрос на получение страницы. Там точно так же есть URL которй можно разбирать роутером.
> Разбирать фреймворки не очень получается, точнее как бы мне не приходит в голову что input::getPost() это плохо и надо как-то по-другому.
Для изучения фреймворка надо читать документацию с начала, а не одну главу. Если бы ты изучил например Юи вместо придумывания странных велосипедов ты бы получил гораздо больше пользы.
Учебник чтобы закрепить основы php, потом дополнительные задания и параллельно учи верстку,SQL, JS (на все эти темы у нас есть задания, мы проверяем решения и даем советы).
А, я придумал как тебе объяснить. Попробуй в своем индекс.php в самом начале поставить такой код:
var_dump($_SERVER);
var_dump($_POST);
var_dump($_GET);
и отправить форму. И тогда ты увидишь чему равны значения всяких переменных при отправленной форме. Обрати внимание на:
REQUEST_URI
REQUEST_METHOD
HTTP_CONTENT_TYPE
Документация по _SERVER тут: https://php.net/manual/ru/reserved.variables.server.php
Попробуй сделать то что написано тут
https://gist.github.com/codedokode/10774100#q-%D0%9E%D0%BA-%D0%90%D0%BF%D0%B0%D1%87-%D0%B8-php-%D1%8F-%D1%83%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%B8%D0%BB-%D0%BD%D0%BE-%D0%90%D0%BF%D0%B0%D1%87-%D0%BD%D0%B5-%D0%B2%D1%8B%D0%BF%D0%BE%D0%BB%D0%BD%D1%8F%D0%B5%D1%82-php-%D1%84%D0%B0%D0%B9%D0%BB%D1%8B-%D0%B0-%D0%BF%D1%80%D0%BE%D1%81%D1%82%D0%BE-%D0%BF%D0%BE%D0%BA%D0%B0%D0%B7%D1%8B%D0%B2%D0%B0%D0%B5%D1%82-%D0%B8%D1%85-%D0%B8%D1%81%D1%85%D0%BE%D0%B4%D0%BD%D1%8B%D0%B9-%D0%BA%D0%BE%D0%B4-%D0%91%D1%83-
> Q. Ок, Апач и PHP я установил, но Апач не выполняет PHP-файлы, а просто показывает их исходный код. Бу :(
> Естественно, Апач же не знает, что у тебя есть PHP и что php-файлы надо выполнять с помощью интерпретатора PHP. Надо подправить кое-что в конфиге Апача, например вот так: http://php.net/manual/ru/install.windows.apache2.php
> Все пути естественно надо заменить на правильные.
> Если все верно, то ты можешь положить в папку htdocs, например, файл 1.php с кодом <?php phpinfo() ?>, открыть в браузере http://localhost/1.php и увидеть синюю таблицу.
Спасибо, заработало.
>А что происходит после нажатия на субмит? Что делает браузер? Что происходит на сервере?
В моем поверхностном понимании когда кто-то нажимает субмит происходит переход по адресу указанному в атрибуте action (если он пустой то на тот же самый) и при этом в массив $_POST или $_GET в зависимости от того что указано в method попадают значения в полях ввода с атрибутами name. В процедурном подходе у меня ни разу не возникало необходимости углубляться в протоколы, все работало как часы: указал на какой странице идет обработка форм, а там isset($_POST['submit']) { обработка формы}. Все просто и понятно. В MVC же не понятно куда направлять эти данные для обработки. Тот код что раньше у меня был в файле operations.php. Вот мы вроде определились что в методе контроллера, например таком
class ProfileController
{
public function edit() { echo 'works'; }
}
Но как его вызвать? В классе Router у меня происходит что-то вроде
$url = explode ("/", $_SERVER["REQUEST_URI"]);
...
$action_name = (empty($url[2])) ? "index" : $url[2] ;
То есть сейчас единственная возможность вызвать экшен - ввести его в адресной строке, например если я ввожу localhost/profile/edit - все работает, пишет 'works'. Всё, вот кристально чистый и понятный вопрос: как добиться того же после нажатия на submit (расположенный на странице с адресом localhost/profile/)?
Исправил все кроме создавания и добавления работников, какой-то треш происходит у меня.
http://ideone.com/8x9W0K
Наверное спать пойду, завтра на свежую голову буду перепиливать, а то пока не могу понять, почему мой временный массив $temp не дополняется работниками.
И вообще, эту фабрику оказалось просто только в теории сделать, в итоге я плохо понимаю как её написать.
Открой исходный код (Ctrl+ U) в браузере и увидишь что переводит. Просто браузер его не отображает.
Чтобы переносы строк нормально работали и в браузере и в ideone (и в консоли), можно использовать для этого \n, а в начале программы поставить
header("Content-Type: text/plain; charset=utf-8");
Это заставит браузер воспринимать то, что выводит твоя программа, как обычный текст, а не HTML, и уважать переносы строк в нем (так как в языке HTML перенос строки равносилен пробелу).
Иначе перенос строки будет в исходном коде страницы (его можно увидеть нажав Ctrl + U), но на самой странице его не будет.
>>458469
> происходит переход по адресу указанному в атрибуте action (если он пустой то на тот же самый) и при этом в массив $_POST или $_GET в зависимости от того что указано в method попадают значения в полях ввода с атрибутами name.
Так, только чуть сложнее. Браузер отправляет POST/GET запрос, а PHP перед выполнением программы анализирует его и заполняет массивы _POST/_GET.
> В процедурном подходе у меня ни разу не возникало необходимости углубляться в протоколы,
Это неправильный подход, HTTP все равно надо знать. Я вообще не понимаю как можно делать веб приложения не зная HTTP.
> В MVC же не понятно куда направлять эти данные для обработки.
Ты читал мой урок про формы? Там же написано, на тот же адрес что и выводит форму.
И MVC тут вообще не при чем. Формы работают одинаково независимо от того что на сервере.
> Всё, вот кристально чистый и понятный вопрос: как добиться того же после нажатия на submit (расположенный на странице с адресом localhost/profile/)?
написать action="/profile/edit", нет?
Тебе надо сначала разобраться с HTTP как следует, а еще лучше, изучить фреймворк вроде Yii. Так ты будешь на каждой вещи спотыкаться.
>>458487
> $temp +=
Ты думаешь это добавляет новые эелементы в массив, а это не так. Ты читал мануал?
http://php.net/manual/ru/language.operators.array.php
Если ты видел такое (добавление элеиентов через +) в других языках, то в PHP это так не работает.
Открой исходный код (Ctrl+ U) в браузере и увидишь что переводит. Просто браузер его не отображает.
Чтобы переносы строк нормально работали и в браузере и в ideone (и в консоли), можно использовать для этого \n, а в начале программы поставить
header("Content-Type: text/plain; charset=utf-8");
Это заставит браузер воспринимать то, что выводит твоя программа, как обычный текст, а не HTML, и уважать переносы строк в нем (так как в языке HTML перенос строки равносилен пробелу).
Иначе перенос строки будет в исходном коде страницы (его можно увидеть нажав Ctrl + U), но на самой странице его не будет.
>>458469
> происходит переход по адресу указанному в атрибуте action (если он пустой то на тот же самый) и при этом в массив $_POST или $_GET в зависимости от того что указано в method попадают значения в полях ввода с атрибутами name.
Так, только чуть сложнее. Браузер отправляет POST/GET запрос, а PHP перед выполнением программы анализирует его и заполняет массивы _POST/_GET.
> В процедурном подходе у меня ни разу не возникало необходимости углубляться в протоколы,
Это неправильный подход, HTTP все равно надо знать. Я вообще не понимаю как можно делать веб приложения не зная HTTP.
> В MVC же не понятно куда направлять эти данные для обработки.
Ты читал мой урок про формы? Там же написано, на тот же адрес что и выводит форму.
И MVC тут вообще не при чем. Формы работают одинаково независимо от того что на сервере.
> Всё, вот кристально чистый и понятный вопрос: как добиться того же после нажатия на submit (расположенный на странице с адресом localhost/profile/)?
написать action="/profile/edit", нет?
Тебе надо сначала разобраться с HTTP как следует, а еще лучше, изучить фреймворк вроде Yii. Так ты будешь на каждой вещи спотыкаться.
>>458487
> $temp +=
Ты думаешь это добавляет новые эелементы в массив, а это не так. Ты читал мануал?
http://php.net/manual/ru/language.operators.array.php
Если ты видел такое (добавление элеиентов через +) в других языках, то в PHP это так не работает.
И вопрос, а ты сделал то что я советовал (поставить вар дамп в начале и посмотреть что выведется при отправке формы)? Почему нет?
>написать action="/profile/edit", нет?
Так что, так и надо делать и это правильно?
>>458500
Я сделал, но я и так знал что там выведется. В методе - метод, в URI - адрес, в CONTENT_TYPE вот та штука ну которая если нужно загружать несколько файлов то прописывается отдельно через enctype или как-то так, не помню, а если нет то стандартное что-то там www/application которое можно не указывать. В _GET и _POST соответственно содержимое этих массивов, если ничего не отправлено то пустой массив.
Но ведь я пытался сделать вот это:
$a + $b \tОбъединение \tОбъединение массива $a и массива $b.
> Так что, так и надо делать и это правильно?
Ну да, а почему нет? Ну если хочешь можно написать что-нибудь другое например /profile/save и тд. Но лучше прочитай сначала мой урок про формы.
>>458515
> Объединение массива $a и массива $b.
да, а ты прочел правила по которым массивы объединяются? Выполни код
$a = ['a', 'b'];
$b = ['c'];
$c = $a + $b;
$d = $b + $a;
var_dump($a, $b, $c, $d);
то что ты ищешь это либо array_merge либо $x[] = ...
Какой домен выбрать из бесплатных? Остались только .tk, .ml, .ga, .cf и .gq.
Не хотел скидывать не готовый вариант, но я просто подумал, что у тебя наверняка будут какие-то замечания по коду, а чем быстрей исправлю тем лучше.
https://github.com/someApprentice/Cat-and-Mouse
В общем, логика такая: сначала мы создаем карту и животное, затем передаем животному карту на текущий момент, и там уже животное само решает что ей лучше сделать, и после передает в мир свою относительную карту, и этот мир уже передвигает само животное.
Я знаю что мог бы сделать проще (обращаться к карте на прямую через животное), но мне интересней сделать как есть на самом деле. Ведь в жизни мы же получаем относительную картину мира.
Надеюсь с этим понятно.
Спасибо.
Это вообще нормальная практика? Хочется разделить все по разным файлам, но как быть с передачей данных из одного языка в другой? Придется постоянно ебаться с вклиниванием php кода в html и js? Есть ли какие-нибудь правила хорошего тона, как нужно организовывать свои страницы? Максимум что я умею - инклудить php файлы и js скрипты. Пример моего говно кода на пике.
Есть ли, и где, простая либа для нечеткого текстового поиска. Без словарей.
Такой вот тупой вопрос.
Ну вот вроде бы разобрался с переносом создания работника из департамента в другой класс, вангую что от правильной фабрики у меня тут только название и ничего больше.
Далее по поводу public / protected: прочитал, вроде понял, что если у меня например в методе департамента написано обращаться к методам работника, то у работника должны быть свойства public. Ну а если только сам департамент обращается к своим свойствам, то можно и private?
Если метод будет вызываться просто так, где-то в другом месте кода, то он должен быть public в общем.
>$vector->makeReport();
В общем в таком большом коде уже не сильно понятно куда и что переделывать, поэтому делал больше методом эксперимента, менял свойства и смотрел, не сломается ли ничего.
http://ideone.com/8x9W0K
Вскоре начну прикручивать антикризис.
Подсмотрел что у других анонов вроде бы был отдельный класс, но я чет не понимаю как сделать так что бы ему в управление передать организацию, и что бы этот класс там делал кадровые перестановки. Пока что мысль, что модно добавить антикризисные методы прямо в класс Organisation, и что бы они работали с департаментами, вот.
> Пока ты решал задачу по выводу отчета о сотрудниках и департаментах, страны запада разразили мировой экономический кризис. Доходы компании начали снижаться, и совет директоров поставил перед руководством задачу принять меры. Менеджеры 3-го ранга, блестящие выпускники топовых экономических вузов столицы, быстро смогли разработать три альтернативных антикризисных решения:
> 1. Сократить в каждом департаменте 40% (округляя в большую сторону) инженеров, преимущественно самого низкого ранга. Если инженер является боссом, вместо него надо уволить другого инженера, не босса.
> 2. Увеличить в целях стимуляции умственной деятельности базовую ставку аналитика с 800 до 1100 тугриков, а количество выпиваемого им кофе с 50 до 75 литров. В тех департаментах, где руководитель не является аналитиком, заменить его на аналитика самого высшего ранга из этого департамента (а бывшего руководителя вернуть к обычной работе)
> 3. В каждом департаменте повысить 50% (округляя в большую сторону) менеджеров 1-го и 2-го ранга на один ранг с целью расширить их полномочия.
> Совет директоров в затруднении: какой путь выбрать? Помоги им с этим, распечатав прогноз по потреблению и расходам (аналогичный тому что требуется в задаче) после принятия каждой из мер.
*целесообразно
Делать бэкенд самое то, а для фронтенда нужен фотожоп, тут придется что-то придумывать. А браузеры сейчас и на линух станут, для ие просто виртуалку поднимешь.
isset($_POST['name']) ? strval($_POST['name']) : '';
по каким тегам гуглить?
Кеш в браузере почисти. а вообще скорее всего ты что-то делаешь не так, например правишь не тот файл или забываешь его сохранить.
Вот счас ставил стили для h1 {color: #ffffff;}
Цвет не менялся что бы я не делал, уже и браузер закрыл и заново открыл, сохранял файл по много раз ctrl+s и закрывал и открывал заново, спустя секунд 40 обновились стили на сайте.
Ты сейчас говоришь про свой локалхост на своем компьютере или про сайт где-то на хостинге?
Также, вопрос 2, при скачивании CSS файла браузер получает какие-то кеширующие заголовки?
Также,
> уже и браузер закрыл и заново открыл,
Я сказал не закрыть браузер а очистить кеш. Это разные вещи.
Локалхост, очистка вроде помогла, спасибо.
Кто не понимает английский: если ваш контент не отображается без яваскрипта, его не увидят поисковые машины, архиваторы интернета и прочие программы (ну и так же его не увидят пользователи если в вашем яваскрипте проиойдет ошибка). Это все равно что он мертв. Незачем тратить время на его чтение.
А все эти новомодные веяния переносить рендеринг на сторону клиента (angular и прочая ересь) это как грязь на берегах реки которую весной смоет вода.
Разумеется это не значит что рендеринг на стороне клиента это всегда плохо. Если ты делаешь приложение или допустим админку которой пользуется один человек, на яваскрипте, в этом нет ничего плохого.
Но не делайте блог на ангуларе.
Капитанство чистой воды.
Подобные вставки пхп кода - это нормально? в джаваскрипт вставлять так же - тоже считается нормой? Пиздец вырвиглаз же? Можно как-нибудь вставлять пхп код, не отделяя его конструкуией <?php ... ?> ?
Ой-ой, ты опять начинаешь придумывать какие-то нестандартные идеи. Иногда наверно это хорошо, но не в этом случае.
> https://github.com/someApprentice/Cat-and-Mouse/blob/master/Classes/World.php#L37
Если ты хочешь вывести карту, надо сделать метод для этого. А не использовать деструктор. Потому что использовать деструктор для вывода карты это то же самое что налить крысиный яд в баночку с надписью «варенье».
Деструктор нужен для освобождения ресурсов, принадлежавших объекту.
Обычно в PHP все освобождается само и деструктор не нужен в большинстве случаев.
> echo "<br>";
Это лишнее. Во-первых, не надо смешивать HTML и логику, во-вторых, а что если мы хотим вывести карту не в браузер а например в текстовый файл или в консоль?
> https://github.com/someApprentice/Cat-and-Mouse/blob/master/Classes/World.php#L9
> public function createMap
Не очень понятно почему функция публичная. Ее можно вызывать после создания объекта?
> https://github.com/someApprentice/Cat-and-Mouse/blob/master/Classes/Animal.php#L12
> $this->overviewWorld($world);
Вот это наиболее непонятная строчка. зачем ты в животном сохраняешь какой-то массив непонятного вида, который соответствует тому как выглядела карта на 0 ходу. Зачем он? Что ты с ним собрался делать?
> $world->moveAnimal($mouse);
Вот эта строчка мне не нравится. Почему мы не можем обращаться к животному напрямую, и написать
$animal->move( );
? Ну то есть логичнее сказать животному: «двигайся», а не вводить лишнего посредника, через которого мы передаем команды.
Также, мне не нравится вот это:
> $mouse = new Mouse($world);
> $world->addAnimalToMap($mouse);
Почему животное не добавит себя на карту самостоятельно? Почему мы должны писать 2 строчки вместо одной? Что будет если мы напишем только первую строчку?
Вообще, у тебя в World куча непонятных методов. Не знаю, стоит ли подсказывать тебе как сделать лучше? Связь животные <-> карта очень напоминает связь работник <-> департамент.
> затем передаем животному карту на текущий момент, и там уже животное само решает что ей лучше сделать, и после передает в мир свою относительную карту
Это верный путь переусложнить код и все запутать. Ну подймай сам, «животное передает в мир свою карту» — то есть мышь может например передвинуть кошек, которые она видит? зачем животное вообще что-то должно передавать в мир? Оно может только бегать по миру, оно не может ничего изменить в нем.
> Ведь в жизни мы же получаем относительную картину мира.
В этом случае ты мог бы сделать объект WorldView, который представляет себе картину мира как его видит животное:
$worldView = $world->getView(12, 10, 5); // картина которую видно из указанной точки с указанным радиусом зрения
// получаем список всех кошек которые видны мыши
$cats = $worldView->getByType(TYPE_CAT);
То есть ты не можешь получать информацию непосредственно от мира, у него нет таких методов, ты должен сначала создать картину мира, и запрашивать информацию через нее. А она уже отсеивает тех животных которые видны. При этом сама WorldView не хранит никакой информации — она получает все данные от World.
Но по моему, тут можно и без этого обойтись. Но если хочешь, можешь сделать так, я не против.
Я даже думаю, есть такой паттерн. В языке C# например есть такая штука как CollectionView, то есть представление коллекции, например отсортированное или отфильрованное по какому-то критерию (коллекция это что-то вроде массива в PHP).
Ой-ой, ты опять начинаешь придумывать какие-то нестандартные идеи. Иногда наверно это хорошо, но не в этом случае.
> https://github.com/someApprentice/Cat-and-Mouse/blob/master/Classes/World.php#L37
Если ты хочешь вывести карту, надо сделать метод для этого. А не использовать деструктор. Потому что использовать деструктор для вывода карты это то же самое что налить крысиный яд в баночку с надписью «варенье».
Деструктор нужен для освобождения ресурсов, принадлежавших объекту.
Обычно в PHP все освобождается само и деструктор не нужен в большинстве случаев.
> echo "<br>";
Это лишнее. Во-первых, не надо смешивать HTML и логику, во-вторых, а что если мы хотим вывести карту не в браузер а например в текстовый файл или в консоль?
> https://github.com/someApprentice/Cat-and-Mouse/blob/master/Classes/World.php#L9
> public function createMap
Не очень понятно почему функция публичная. Ее можно вызывать после создания объекта?
> https://github.com/someApprentice/Cat-and-Mouse/blob/master/Classes/Animal.php#L12
> $this->overviewWorld($world);
Вот это наиболее непонятная строчка. зачем ты в животном сохраняешь какой-то массив непонятного вида, который соответствует тому как выглядела карта на 0 ходу. Зачем он? Что ты с ним собрался делать?
> $world->moveAnimal($mouse);
Вот эта строчка мне не нравится. Почему мы не можем обращаться к животному напрямую, и написать
$animal->move( );
? Ну то есть логичнее сказать животному: «двигайся», а не вводить лишнего посредника, через которого мы передаем команды.
Также, мне не нравится вот это:
> $mouse = new Mouse($world);
> $world->addAnimalToMap($mouse);
Почему животное не добавит себя на карту самостоятельно? Почему мы должны писать 2 строчки вместо одной? Что будет если мы напишем только первую строчку?
Вообще, у тебя в World куча непонятных методов. Не знаю, стоит ли подсказывать тебе как сделать лучше? Связь животные <-> карта очень напоминает связь работник <-> департамент.
> затем передаем животному карту на текущий момент, и там уже животное само решает что ей лучше сделать, и после передает в мир свою относительную карту
Это верный путь переусложнить код и все запутать. Ну подймай сам, «животное передает в мир свою карту» — то есть мышь может например передвинуть кошек, которые она видит? зачем животное вообще что-то должно передавать в мир? Оно может только бегать по миру, оно не может ничего изменить в нем.
> Ведь в жизни мы же получаем относительную картину мира.
В этом случае ты мог бы сделать объект WorldView, который представляет себе картину мира как его видит животное:
$worldView = $world->getView(12, 10, 5); // картина которую видно из указанной точки с указанным радиусом зрения
// получаем список всех кошек которые видны мыши
$cats = $worldView->getByType(TYPE_CAT);
То есть ты не можешь получать информацию непосредственно от мира, у него нет таких методов, ты должен сначала создать картину мира, и запрашивать информацию через нее. А она уже отсеивает тех животных которые видны. При этом сама WorldView не хранит никакой информации — она получает все данные от World.
Но по моему, тут можно и без этого обойтись. Но если хочешь, можешь сделать так, я не против.
Я даже думаю, есть такой паттерн. В языке C# например есть такая штука как CollectionView, то есть представление коллекции, например отсортированное или отфильрованное по какому-то критерию (коллекция это что-то вроде массива в PHP).
А тебе нужны красивые урл или достаточно стандартного вида?
>>458619
Шаблоны используй.
JS код выноси в js-файлы, а в html оставляй только минимальный код инициализации вроде
var x = <?= intval($x) ?>;
var y = <?= json_encode($y) ?>;
initSomething(x, y);
То что у тебя это конечно помойка не выдерживающая никакой критики. разнеси все в отдельные файлы.
>>458634
Поиска текста в чем? В массиве? Базе данных? Что значит нечеткого?
Я думаю что готового решения нет.
>>458712
Джаваскрипт ты пишешь в отдельном js файле без всяких вставок.
> Подобные вставки пхп кода - это нормально?
Как у тебя нет. Как в статье про шаблоны да.
> Можно как-нибудь вставлять пхп код, не отделяя его конструкуией <?php ... ?> ?
<?= html($x) ?> либо используй шаблонизаторы вроде twig в которых это чуть короче выходит.
Ты статью по ссылке внимательно прочел?
А тебе нужны красивые урл или достаточно стандартного вида?
>>458619
Шаблоны используй.
JS код выноси в js-файлы, а в html оставляй только минимальный код инициализации вроде
var x = <?= intval($x) ?>;
var y = <?= json_encode($y) ?>;
initSomething(x, y);
То что у тебя это конечно помойка не выдерживающая никакой критики. разнеси все в отдельные файлы.
>>458634
Поиска текста в чем? В массиве? Базе данных? Что значит нечеткого?
Я думаю что готового решения нет.
>>458712
Джаваскрипт ты пишешь в отдельном js файле без всяких вставок.
> Подобные вставки пхп кода - это нормально?
Как у тебя нет. Как в статье про шаблоны да.
> Можно как-нибудь вставлять пхп код, не отделяя его конструкуией <?php ... ?> ?
<?= html($x) ?> либо используй шаблонизаторы вроде twig в которых это чуть короче выходит.
Ты статью по ссылке внимательно прочел?
> Ну а если только сам департамент обращается к своим свойствам, то можно и private?
Не можно а нужно. надо стараться ставить наиболее закрытый режим доступа из возможных. Чем меньше у тебя public методов тем проще другому человеку разобраться в твоем коде так как снаружи можно вызывать только public методы.
Ну сам подумай в каком устройстве проще разобраться — у которого 2 кнопки или у которого 32 кнопки? Объект это как коробочка с кнопками (публичные методы) которые можно нажимать чтобы добиться результата.
> Подсмотрел что у других анонов вроде бы был отдельный класс, но я чет не понимаю как сделать так что бы ему в управление передать организацию
1) через конструктор
$anticrisis = new AntiCrisisManagement($company);
$anticrisis->takeMeasures( );
2) через аругменты
$anticrisis = new AntiCrisisManagement( );
$anticrisis->takeMeasures($company);
В первом случае ты навсегда привязываешь менеджемент к компании, во втором ты как бы приглашаешь менеджеров поуправлять компанией на время (а потом например можно попуправлять какой-то другой компанией).
> Пока что мысль, что модно добавить антикризисные методы прямо в класс Organisation
Лучше отдельно, а то так у тебя класс разрастется до огромных размеров.
Замечания и советы:
Во-первых, если мы попросим твою организацию сделать отчет 3 раза то программа падает: http://ideone.com/zH5ZSg
Никогда не объявляй функции внутри других функций.
Во-вторых, я не уверен что это хорошая идея поместить makeReport внутрь организации (ведь завтра нам понадобится другой вид отчета, посезавтра третий и скоро у тебя будет 10 методов makeReport). Но в общем это примелемо.
Также, это плохая идея что у тебя класс что-то выводит через echo. Все echo надо вынести за пределы класса, почему класс занимается выводом данных? Я не знаю, как объяснить это, но обычно выводом занимаются только специально для этого сделанные классы, а обычные классы ничего не выводят, а только возвращают данные через return и ты их можешь как угодно использовать.
> protected function countTotalEfficiency()
Ты уверен что эта функция вернет что-то осмысленное? Разве можно складывать отношение одного числа к другому? ну то есть если первый департамент тратит 5 тугриков на страницу, а второй 7 то какой смысл имеет число 5 + 7 = 12? Что оно значит?
Ну то есть у одного ученика средний балл 4.2, у второго 3.7. Какой смысл имеет число 4.2 + 3.7 = 7.9? По моему никакого.
Мне кажется тут имеет смысл только средняя эффективность по всей компании, то есть расходы на производство страниц, деленные на число страниц.
> Ну а если только сам департамент обращается к своим свойствам, то можно и private?
Не можно а нужно. надо стараться ставить наиболее закрытый режим доступа из возможных. Чем меньше у тебя public методов тем проще другому человеку разобраться в твоем коде так как снаружи можно вызывать только public методы.
Ну сам подумай в каком устройстве проще разобраться — у которого 2 кнопки или у которого 32 кнопки? Объект это как коробочка с кнопками (публичные методы) которые можно нажимать чтобы добиться результата.
> Подсмотрел что у других анонов вроде бы был отдельный класс, но я чет не понимаю как сделать так что бы ему в управление передать организацию
1) через конструктор
$anticrisis = new AntiCrisisManagement($company);
$anticrisis->takeMeasures( );
2) через аругменты
$anticrisis = new AntiCrisisManagement( );
$anticrisis->takeMeasures($company);
В первом случае ты навсегда привязываешь менеджемент к компании, во втором ты как бы приглашаешь менеджеров поуправлять компанией на время (а потом например можно попуправлять какой-то другой компанией).
> Пока что мысль, что модно добавить антикризисные методы прямо в класс Organisation
Лучше отдельно, а то так у тебя класс разрастется до огромных размеров.
Замечания и советы:
Во-первых, если мы попросим твою организацию сделать отчет 3 раза то программа падает: http://ideone.com/zH5ZSg
Никогда не объявляй функции внутри других функций.
Во-вторых, я не уверен что это хорошая идея поместить makeReport внутрь организации (ведь завтра нам понадобится другой вид отчета, посезавтра третий и скоро у тебя будет 10 методов makeReport). Но в общем это примелемо.
Также, это плохая идея что у тебя класс что-то выводит через echo. Все echo надо вынести за пределы класса, почему класс занимается выводом данных? Я не знаю, как объяснить это, но обычно выводом занимаются только специально для этого сделанные классы, а обычные классы ничего не выводят, а только возвращают данные через return и ты их можешь как угодно использовать.
> protected function countTotalEfficiency()
Ты уверен что эта функция вернет что-то осмысленное? Разве можно складывать отношение одного числа к другому? ну то есть если первый департамент тратит 5 тугриков на страницу, а второй 7 то какой смысл имеет число 5 + 7 = 12? Что оно значит?
Ну то есть у одного ученика средний балл 4.2, у второго 3.7. Какой смысл имеет число 4.2 + 3.7 = 7.9? По моему никакого.
Мне кажется тут имеет смысл только средняя эффективность по всей компании, то есть расходы на производство страниц, деленные на число страниц.
>А тебе нужны красивые урл или достаточно стандартного вида?
Я делаю задание про сайт с тестами и
мне просто интересно, как чаще принято.
Начинающий веб-разработчик или PHP программист?
Стоит ли писать про дропнутный вуз?
По поводу модификаторов доступа public/private. С их помощью ты, автор класса, задаешь правила его использования: что другие программисты могут делать с твоим классом и что не могут. Взамен ты гарантируешь что при соблюдении правил класс будет во всех случаях работать корректно и выдавать правильные данные. Попробуй воспринимать это именно в таком смысле.
>>458650
Можно. Хром и фаерфокс работают под Убунтой примерно как под Win (только шрифты рисуют чуть по-другому), а для IE придется либо использовать виртуалку (как и на виндоуз) либо какие-то из вариантов отсюда: https://www.modern.ie/ru-ru (ну например browsershots для начала, хотя он годится только для простых страниц без яваскрипта).
Ну и как анон заметил, с фотошопом проблема, да. Я знаю, что старый фотошоп (CS2) вроде более-менее работает под вайном, а более новый наверно только в виртуалке.
>>458714
Постраничная навигация может выглядеть примерно так:
<a href="index.php?page=1">1</a>
<a href="index.php?page=2">2</a>
<a href="index.php?page=3">3</a>
параметр page попадет в _GET откуда его можно взять:
http://php.net/manual/ru/reserved.variables.get.php
https://php.net/manual/ru/language.variables.external.php
Если ты используешь CSS Bootstrap (рекомендуется), то там есть верстка для постраничной навигации которая выводит красивые квадратики с цифрами:
http://getbootstrap.com/components/#pagination
По поводу модификаторов доступа public/private. С их помощью ты, автор класса, задаешь правила его использования: что другие программисты могут делать с твоим классом и что не могут. Взамен ты гарантируешь что при соблюдении правил класс будет во всех случаях работать корректно и выдавать правильные данные. Попробуй воспринимать это именно в таком смысле.
>>458650
Можно. Хром и фаерфокс работают под Убунтой примерно как под Win (только шрифты рисуют чуть по-другому), а для IE придется либо использовать виртуалку (как и на виндоуз) либо какие-то из вариантов отсюда: https://www.modern.ie/ru-ru (ну например browsershots для начала, хотя он годится только для простых страниц без яваскрипта).
Ну и как анон заметил, с фотошопом проблема, да. Я знаю, что старый фотошоп (CS2) вроде более-менее работает под вайном, а более новый наверно только в виртуалке.
>>458714
Постраничная навигация может выглядеть примерно так:
<a href="index.php?page=1">1</a>
<a href="index.php?page=2">2</a>
<a href="index.php?page=3">3</a>
параметр page попадет в _GET откуда его можно взять:
http://php.net/manual/ru/reserved.variables.get.php
https://php.net/manual/ru/language.variables.external.php
Если ты используешь CSS Bootstrap (рекомендуется), то там есть верстка для постраничной навигации которая выводит красивые квадратики с цифрами:
http://getbootstrap.com/components/#pagination
В задании с тестами надо сделать красивые URL. Вроде
/test/1/start - стартовая страница теста с id = 1
Чтобы из этих URL было ясно на какую страницу они ведут.
Вот еще мысли: http://www.artlebedev.ru/kovodstvo/sections/48/
Ты можешь составить план и написать как будут выглядеть URL, а я проверю и предупрежу про подвохи.
Также, вот черновик урока про URL, может он даст тебе какие-то идеи: https://gist.github.com/codedokode/772a4ccc03e41d6b7cba
>>458780
веб-разработчик звучит лучше и более широко.
про вуз не знаю. Мне это ничего не говорит, но у HR могут быть другие представления.
Для начала, вот список замечаний, которые обнаружил робот:
В файле ./sql:
Файл с SQL дампом принято называть с расширением .sql, например students.sql
Для полей пола и места жительства (и для любых других полей где есть выбор одного из нескольких вариантов) стоит использовать тип ENUM. Он идеально подходит для них так как сразу видно какие варианты значений существуют и БД не позволит вставить неправильные значения. Если ты с ним не знаком, почитай про существующие в MySQL типы колонок:
http://phpclub.ru/mysql/doc/column-types.html
Похоже что ты не использовал тип YEAR для хранения года рождения, а ведь такой тип специально для этого придуман. Если ты про него не знал, то почитай про то какие типы есть в MySQL:
http://phpclub.ru/mysql/doc/column-types.html
Задал ли ты кодировку соединения с базой при работе через PDO? Это можно сделать либо параметром charset= при соединении либо командой SET NAMES в PDO::MYSQL_ATTR_INIT_COMMAND. Мануал: http://php.net/manual/ru/ref.pdo-mysql.connection.php
В файле ./class/student.php:
> strlen(
> strlen(
Ты используешь функции, которые работают неправильно с нелатинскими символами в utf8. Они рассчитаны на однобайтные кодировки, а utf-8 многобайтная. Надо использовать функции вроде mb_strlen, которые корректно поддерживают utf-8. (В этом примере конечно у тебя только латинница, но проще везде использовать функции mb_xxx чем разбираться по каждому случаю).
Подробнее про строки и utf-8: https://gist.github.com/codedokode/ff99e357e9860ea169b8
Ты используешь функции mb_xxx в своем коде, а указал ли ты для них используемую кодировку с помощью mb_internal_encoding(...)? Без этого эти функции могут неправильно обрабатывать строки.
В файле ./input2.php:
Похоже, ты забыл указать флаг ENT_QUOTES при использовании htmlspecialchars(), это плохо так как в этом случае эта функция не будет экранировать одиночные кавычки. Мануал: http://php.net/manual/ru/function.htmlspecialchars.php
В файле ./class/page.php:
Согласно PSR-0 и PSR-4 имя файла с классом должно соответствовать имени класса с точностью до регистра букв, например MyAwesomeClass => MyAwesomeClass.php. Имя файла с классом «Page» не соответствует этим правилам. Учти, что под Windows, чтобы гит увидел изменения в регистре букв в имени файла придется повозиться: http://stackoverflow.com/questions/1793735/change-case-of-a-file-on-windows
В файле ./class/student.php:
Согласно PSR-0 и PSR-4 имя файла с классом должно соответствовать имени класса с точностью до регистра букв, например MyAwesomeClass => MyAwesomeClass.php. Имя файла с классом «Student» не соответствует этим правилам. Учти, что под Windows, чтобы гит увидел изменения в регистре букв в имени файла придется повозиться: http://stackoverflow.com/questions/1793735/change-case-of-a-file-on-windows
В файле ./class/page.php:
Похоже, что ты выводишь данные прямо из файла с кодом? Это плохая идея, так как смесь логики и HTML выглядит как каша. Весь вывод и HTML код надо вынести в отдельные файлы-шаблоны, например, в папке templates, как описано тут: http://www.phpinfo.su/articles/practice/shablony_v_php.html
В файле ./Header.php:
Не используй короткий открывающий тег <? так как он может быть отключен в настройках. Используй либо длинный открывающий тег <?php для кода, либо короткий <?= для вывода значений в шаблонах.
В файле ./input1.php:
Не используй короткий открывающий тег <? так как он может быть отключен в настройках. Используй либо длинный открывающий тег <?php для кода, либо короткий <?= для вывода значений в шаблонах.
В файле ./register.php:
Не используй короткий открывающий тег <? так как он может быть отключен в настройках. Используй либо длинный открывающий тег <?php для кода, либо короткий <?= для вывода значений в шаблонах.
В файле ./Header.php:
Слеш в конце одиночного тега (<link href="sty…s" />) используется только в XHTML и XML, в HTML он не ставится.
В файле ./register.php:
Слеш в конце одиночного тега (<link href="sty…s" />) используется только в XHTML и XML, в HTML он не ставится.
Для начала, вот список замечаний, которые обнаружил робот:
В файле ./sql:
Файл с SQL дампом принято называть с расширением .sql, например students.sql
Для полей пола и места жительства (и для любых других полей где есть выбор одного из нескольких вариантов) стоит использовать тип ENUM. Он идеально подходит для них так как сразу видно какие варианты значений существуют и БД не позволит вставить неправильные значения. Если ты с ним не знаком, почитай про существующие в MySQL типы колонок:
http://phpclub.ru/mysql/doc/column-types.html
Похоже что ты не использовал тип YEAR для хранения года рождения, а ведь такой тип специально для этого придуман. Если ты про него не знал, то почитай про то какие типы есть в MySQL:
http://phpclub.ru/mysql/doc/column-types.html
Задал ли ты кодировку соединения с базой при работе через PDO? Это можно сделать либо параметром charset= при соединении либо командой SET NAMES в PDO::MYSQL_ATTR_INIT_COMMAND. Мануал: http://php.net/manual/ru/ref.pdo-mysql.connection.php
В файле ./class/student.php:
> strlen(
> strlen(
Ты используешь функции, которые работают неправильно с нелатинскими символами в utf8. Они рассчитаны на однобайтные кодировки, а utf-8 многобайтная. Надо использовать функции вроде mb_strlen, которые корректно поддерживают utf-8. (В этом примере конечно у тебя только латинница, но проще везде использовать функции mb_xxx чем разбираться по каждому случаю).
Подробнее про строки и utf-8: https://gist.github.com/codedokode/ff99e357e9860ea169b8
Ты используешь функции mb_xxx в своем коде, а указал ли ты для них используемую кодировку с помощью mb_internal_encoding(...)? Без этого эти функции могут неправильно обрабатывать строки.
В файле ./input2.php:
Похоже, ты забыл указать флаг ENT_QUOTES при использовании htmlspecialchars(), это плохо так как в этом случае эта функция не будет экранировать одиночные кавычки. Мануал: http://php.net/manual/ru/function.htmlspecialchars.php
В файле ./class/page.php:
Согласно PSR-0 и PSR-4 имя файла с классом должно соответствовать имени класса с точностью до регистра букв, например MyAwesomeClass => MyAwesomeClass.php. Имя файла с классом «Page» не соответствует этим правилам. Учти, что под Windows, чтобы гит увидел изменения в регистре букв в имени файла придется повозиться: http://stackoverflow.com/questions/1793735/change-case-of-a-file-on-windows
В файле ./class/student.php:
Согласно PSR-0 и PSR-4 имя файла с классом должно соответствовать имени класса с точностью до регистра букв, например MyAwesomeClass => MyAwesomeClass.php. Имя файла с классом «Student» не соответствует этим правилам. Учти, что под Windows, чтобы гит увидел изменения в регистре букв в имени файла придется повозиться: http://stackoverflow.com/questions/1793735/change-case-of-a-file-on-windows
В файле ./class/page.php:
Похоже, что ты выводишь данные прямо из файла с кодом? Это плохая идея, так как смесь логики и HTML выглядит как каша. Весь вывод и HTML код надо вынести в отдельные файлы-шаблоны, например, в папке templates, как описано тут: http://www.phpinfo.su/articles/practice/shablony_v_php.html
В файле ./Header.php:
Не используй короткий открывающий тег <? так как он может быть отключен в настройках. Используй либо длинный открывающий тег <?php для кода, либо короткий <?= для вывода значений в шаблонах.
В файле ./input1.php:
Не используй короткий открывающий тег <? так как он может быть отключен в настройках. Используй либо длинный открывающий тег <?php для кода, либо короткий <?= для вывода значений в шаблонах.
В файле ./register.php:
Не используй короткий открывающий тег <? так как он может быть отключен в настройках. Используй либо длинный открывающий тег <?php для кода, либо короткий <?= для вывода значений в шаблонах.
В файле ./Header.php:
Слеш в конце одиночного тега (<link href="sty…s" />) используется только в XHTML и XML, в HTML он не ставится.
В файле ./register.php:
Слеш в конце одиночного тега (<link href="sty…s" />) используется только в XHTML и XML, в HTML он не ставится.
Теперь то, что обнаружил я:
> pswrd
Лучше писать password (хотя в этой задаче нет пароля). Выгоды никакой от таих сокращений нет, только читать тяжелее.
Имена полей в БД обычно принято писать маленькими буквами в стиле birth_date
В главной папке у тебя слишком много php-файлов. Там должны быть только 2 файла (просмотр списка и регистрация/редактирование), остальное надо убрать в подпапки.
Далее, в файле https://github.com/Si0n/registr/blob/master/config.php#L2 непонятно что делают require_once. Эти классы нужны для работы конфига? Я думаю, нет. Раз так, не надо тут их подключать.
Инициализацию можно вынессти в файл, например app/bootstrap.php.
По файлу https://github.com/Si0n/registr/blob/master/Header.php: шаблон должен выводить те данные которые ему переданы. он не должен сам куда-то лезть в базу и выяснять есть ли пароль в базе или нет, как тут:
> if ($db->isPswrdInDB())
также, шаблоны стоит положить в отдельную папку, например templates.
Вообще этот файл надо разрезать на куски и переделать, тут в кучу свалены HTML и PHP, плохо.
> input1.php
> input2.php
Назови файлы правильно. Я уверен, что никто не догадается почему тут 2 файла с похожими названиями и в чем разница.
> https://github.com/Si0n/registr/blob/master/class/student.php#L24
> public function getInfo()
Непонятно зачем эта функция и как ей пользоваться, то есть как запомнить какое поле каким по счету идет? Их же много.
> https://github.com/Si0n/registr/blob/master/class/student.php#L13
> public function __construct($name, $surname, $sex, $group, $email, $mark, $local, $birthDate)
Слишком много аргументов. Я советую сделать конструктор вообще без аргументов
> generatePswrd() {
Не сокращай слова, выгоды никакой а читаемость снижается.
> while (strlen($code) < $length) {
тут лучше (чтобы сразу было понятно что в цикле фиксированное число шагов) использовать for.
> $code = sha1($code);
Не очень понятно зачем эта строка, она ведь не увеличивает число возможных вариантов кода, лишь удлиняет его. В принципе ничего плохого, просто непонятно зачем это нужно.
> https://github.com/Si0n/registr/blob/master/class/StudentsMapper.php#L16
> while($students = $STH->fetch())
Есть fetchAll для таких случаев, почитай например это http://phpfaq.ru/pdo
Также, название getData ничего не говорит. так можно любую функцию назвать, потому что почти любая функция возвращает данные. Придумай более подходящее название, например getAllStudentsAsArray
> $_COOKIE['pswrd']);
Класс для работы с базой данных не должен использовать куки. Он должен делать ровно одну задачу: брать данные и сохранять их в базу. Ты искуственно усложняешь логику, добавляя сюда куки. Этим самым ты вместо четкого разделения смешиваешь код который должен быть а разных файлах.
> https://github.com/Si0n/registr/blob/master/class/StudentsMapper.php#L49
> "SELECT x FROM students
Чтобы проверить есть ли запись в БД не надо ее выбирать, есть запрос SELECT COUNT(...)
> https://github.com/Si0n/registr/blob/master/class/page.php
HTML код должен быть в шаблонах, а не в классах. Что делает этот класс, также непонятно. Мне кажется, он вообще не нужен.
Ты не исплоьзуешь htmlspecialchars при выводе данных. Прочти тогда урок про XSS: https://github.com/codedokode/pasta/blob/master/security/xss.md
> print "<b>При регистрации произошли следующие ошибки:</b><br>";
> Назад
Нет, так не пойдет. Это неудобно для пользователя, возвращаться назад и вводить все данные с нуля. При ошибке надо выводить ту же форму с уже введенными значениями и сообщениями об ошибках. это гораздо удобнее. Прочти мой урок про работу с формами: https://github.com/codedokode/pasta/blob/master/forms.md
Теперь то, что обнаружил я:
> pswrd
Лучше писать password (хотя в этой задаче нет пароля). Выгоды никакой от таих сокращений нет, только читать тяжелее.
Имена полей в БД обычно принято писать маленькими буквами в стиле birth_date
В главной папке у тебя слишком много php-файлов. Там должны быть только 2 файла (просмотр списка и регистрация/редактирование), остальное надо убрать в подпапки.
Далее, в файле https://github.com/Si0n/registr/blob/master/config.php#L2 непонятно что делают require_once. Эти классы нужны для работы конфига? Я думаю, нет. Раз так, не надо тут их подключать.
Инициализацию можно вынессти в файл, например app/bootstrap.php.
По файлу https://github.com/Si0n/registr/blob/master/Header.php: шаблон должен выводить те данные которые ему переданы. он не должен сам куда-то лезть в базу и выяснять есть ли пароль в базе или нет, как тут:
> if ($db->isPswrdInDB())
также, шаблоны стоит положить в отдельную папку, например templates.
Вообще этот файл надо разрезать на куски и переделать, тут в кучу свалены HTML и PHP, плохо.
> input1.php
> input2.php
Назови файлы правильно. Я уверен, что никто не догадается почему тут 2 файла с похожими названиями и в чем разница.
> https://github.com/Si0n/registr/blob/master/class/student.php#L24
> public function getInfo()
Непонятно зачем эта функция и как ей пользоваться, то есть как запомнить какое поле каким по счету идет? Их же много.
> https://github.com/Si0n/registr/blob/master/class/student.php#L13
> public function __construct($name, $surname, $sex, $group, $email, $mark, $local, $birthDate)
Слишком много аргументов. Я советую сделать конструктор вообще без аргументов
> generatePswrd() {
Не сокращай слова, выгоды никакой а читаемость снижается.
> while (strlen($code) < $length) {
тут лучше (чтобы сразу было понятно что в цикле фиксированное число шагов) использовать for.
> $code = sha1($code);
Не очень понятно зачем эта строка, она ведь не увеличивает число возможных вариантов кода, лишь удлиняет его. В принципе ничего плохого, просто непонятно зачем это нужно.
> https://github.com/Si0n/registr/blob/master/class/StudentsMapper.php#L16
> while($students = $STH->fetch())
Есть fetchAll для таких случаев, почитай например это http://phpfaq.ru/pdo
Также, название getData ничего не говорит. так можно любую функцию назвать, потому что почти любая функция возвращает данные. Придумай более подходящее название, например getAllStudentsAsArray
> $_COOKIE['pswrd']);
Класс для работы с базой данных не должен использовать куки. Он должен делать ровно одну задачу: брать данные и сохранять их в базу. Ты искуственно усложняешь логику, добавляя сюда куки. Этим самым ты вместо четкого разделения смешиваешь код который должен быть а разных файлах.
> https://github.com/Si0n/registr/blob/master/class/StudentsMapper.php#L49
> "SELECT x FROM students
Чтобы проверить есть ли запись в БД не надо ее выбирать, есть запрос SELECT COUNT(...)
> https://github.com/Si0n/registr/blob/master/class/page.php
HTML код должен быть в шаблонах, а не в классах. Что делает этот класс, также непонятно. Мне кажется, он вообще не нужен.
Ты не исплоьзуешь htmlspecialchars при выводе данных. Прочти тогда урок про XSS: https://github.com/codedokode/pasta/blob/master/security/xss.md
> print "<b>При регистрации произошли следующие ошибки:</b><br>";
> Назад
Нет, так не пойдет. Это неудобно для пользователя, возвращаться назад и вводить все данные с нуля. При ошибке надо выводить ту же форму с уже введенными значениями и сообщениями об ошибках. это гораздо удобнее. Прочти мой урок про работу с формами: https://github.com/codedokode/pasta/blob/master/forms.md
>>458781
Большое спасибо, ты тут пишешь пояснений больше, чем я кода в день строчу. Я вот хоть и все понимаю, но у меня уже задача по моим меркам разрослась так, что я не могу в ней ориентироваться нормально, и не знаю как впиливать что. Вот вроде придумал как сделать что бы 3й антикризисный проект принять, и как будто опять надо другие функции и классы переделывать под это дело. Как будто в каждом классе должно быть 3 обязательных метода:
создаем класс(параметры)
спросить_объект_класса_о_чем_то(о чем)
изменить_какое_то_свойство_объекта(на что)
Ну и если у класса не 1-2 поля, то соответственно методов становится БОЛЬШЕ, а потом еще и еще. Что бы даже тех же менеджеров назначать, нужно сначала узнать кто там в департаментах с каким классом, потом еще переделать им классы. И это еще минуя хитрую функцию, которая как-то будет выбирать половину из всех тех ребят.
И так под каждый антикризисный случай придется расширять свои уже вроде как готовые классы. Нужно просто немного поднатаскаться в ООП и потом буду легко планировать подобное?
>Для полей пола и места жительства (и для любых других полей где есть выбор одного из нескольких вариантов) стоит использовать тип ENUM.
Я прочитал в рекомендациях об этом, когда я уже создал бд и заполнил таблицу, а потом уже выдавало ошибку при попытке смены типа столбца. Всю логику вывода на экран вынести в отдельные файлы(шаблоны), да? Нельзя для этого класс создать, который бы разными методами работал с инфой которая ему передается из обработчиков?
Придумал только очевидное решение передачи их через свойства контроллера. Можно ли так делать? (Подробнее здесь http://ideone.com/gDahj2)
Я переспрашиваю, потому что четких указаний по этому поводу не нашел, приходится о многом догадываться, изобретать; поэтому опасаюсь нерациональных решений ("зачем ты так написал? так сейчас никто не пишет" ©).
Скобка приклеилась http://ideone.com/gDahj2
Объясните пошагово, что происходит в методе render контроллера, а то я совсем запутался.
А то моё решение этой проблемы вызывает у меня подозрение.
https://github.com/tokotun/uppy/blob/master/uppy/app/File.php#L22
Мануал читал? как там написано, так и делай
http://www.yiiframework.com/doc/guide/1.1/ru/basics.view
там вроде оба способа одобрены.
> Объясните пошагово, что происходит в методе render контроллера,
Открой исходники и изучай ( https://github.com/yiisoft/yii/tree/1.1.15-branch ), если непонятно какое-то конкретное место, можешь постить ссылку на гитхаб, обсудим.
>>458893
> а потом уже выдавало ошибку при попытке смены типа столбца.
можно удалить таблицу и создать заново
> логику вывода на экран вынести в отдельные файлы(шаблоны), да?
да
> Нельзя для этого класс создать, который бы разными методами работал с инфой которая ему передается из обработчиков?
нет. Ну посмотри на свой класс Page, это же ужасно смотрится, вывод HTML через echo. Еще и пляски постоянные с экранированием кавычек. Для этой цели давно придуманы шаблоны.
>>458892
> но у меня уже задача по моим меркам разрослась так, что я не могу в ней ориентироваться нормально
А в чем сложность? Если ты пишешь код правильно то классы у тебя независимы и тебе достаточно в голове держать только класс с которым ты работаешь.
> Как будто в каждом классе должно быть 3 обязательных метода:
Вполне возможно что так. Если в задаче тебе требуется менять ранг то логично для этого сделать метод. Если надо узнать сколько он кофе выпил, еще метод. И так далее.
> то соответственно методов становится БОЛЬШЕ, а потом еще и еще
И что страшного? Ты наверно классы на 3000 строчек не видел (но это конечно плохо, при 700-800 строках пора задумываться о том как разбить класс на отдельные части).
> И так под каждый антикризисный случай придется расширять свои уже вроде как готовые классы.
Если бы ты с начала предусмотрел нужные методы, то не пришлось бы, а так придется. Ну ничего страшного. Если ты добавляешь методы, не трогая старые, код ведь не сломается.
> Нужно просто немного поднатаскаться в ООП и потом буду легко планировать подобное?
Думаю, да.
Мануал читал? как там написано, так и делай
http://www.yiiframework.com/doc/guide/1.1/ru/basics.view
там вроде оба способа одобрены.
> Объясните пошагово, что происходит в методе render контроллера,
Открой исходники и изучай ( https://github.com/yiisoft/yii/tree/1.1.15-branch ), если непонятно какое-то конкретное место, можешь постить ссылку на гитхаб, обсудим.
>>458893
> а потом уже выдавало ошибку при попытке смены типа столбца.
можно удалить таблицу и создать заново
> логику вывода на экран вынести в отдельные файлы(шаблоны), да?
да
> Нельзя для этого класс создать, который бы разными методами работал с инфой которая ему передается из обработчиков?
нет. Ну посмотри на свой класс Page, это же ужасно смотрится, вывод HTML через echo. Еще и пляски постоянные с экранированием кавычек. Для этой цели давно придуманы шаблоны.
>>458892
> но у меня уже задача по моим меркам разрослась так, что я не могу в ней ориентироваться нормально
А в чем сложность? Если ты пишешь код правильно то классы у тебя независимы и тебе достаточно в голове держать только класс с которым ты работаешь.
> Как будто в каждом классе должно быть 3 обязательных метода:
Вполне возможно что так. Если в задаче тебе требуется менять ранг то логично для этого сделать метод. Если надо узнать сколько он кофе выпил, еще метод. И так далее.
> то соответственно методов становится БОЛЬШЕ, а потом еще и еще
И что страшного? Ты наверно классы на 3000 строчек не видел (но это конечно плохо, при 700-800 строках пора задумываться о том как разбить класс на отдельные части).
> И так под каждый антикризисный случай придется расширять свои уже вроде как готовые классы.
Если бы ты с начала предусмотрел нужные методы, то не пришлось бы, а так придется. Ну ничего страшного. Если ты добавляешь методы, не трогая старые, код ведь не сломается.
> Нужно просто немного поднатаскаться в ООП и потом буду легко планировать подобное?
Думаю, да.
О! Я забыл проверить твой код. Не беда, завтра наверно проверю, не жди меня, делай дальше.
Оставить проще всего так:
preg_replace("/[^a-z]/u", "_", $name);
Твой способ какой-то странный.
Я думаю, через this удобно передавать какие-то вещи которые общие для всех действий контроллера, а через переменные те которые отличаются в разных действиях.
Вот тебе пока кратко замечания:
Не создавай новое соединение на каждый маппер, сделай PDO тоже синглтоном
Также, не вижу где ты задаешь кодировку соединения через SET NAMES или параметр charset в DSN.
> header("Location: $file->key");
Там есть удобная функция redirect: http://docs.slimframework.com/#Response-Helpers
> https://github.com/tokotun/uppy/blob/master/uppy/app/Uploader.php#L19
Эту функцию я бы перенес в контроллер в index.php, а вместо обращения к POST лучше использовать Request в Слиме.
>Твой способ какой-то странный.
Просто не получалось запустить preg_replace, подумал что с иероглифами тут какие то тонкости естьскорей всего закорючку какую-нибудь проглядел Но сейчас работает.
Ты вот проверяешь тонны кода, удобно ли тебе в них ориентироватся? Есть там какие гайды, или замечания по правильному комментированию кода, что б тебе легче было его читать?
> скорей всего закорючку какую-нибудь проглядел
Флаг u скорее всего
> Ты вот проверяешь тонны кода, удобно ли тебе в них ориентироватся?
Я человек привычный, в коде гораздо худшего качества разбирался, так что норм (если будешь работать программистом, тебе тоже придется :) ). Тем более что приложение простое и я его не первый раз вижу.
> Есть там какие гайды, или замечания по правильному комментированию кода,
Есть такая вещь как самодокументируемый код, когда методы и переменные правильно названы, и код читается почти как обычный текст. Это самый лучший вариант.
Комментарии надо писать только в неоднозначных ситуациях, и в простом приложении вряд ли они часто встречаются.
Ну и структура кода важна, когда каждый класс и файл занимается своим делом и все по папочкам разложено.
То есть что бы он результаты моих php скриптов отображал корректно с пробелами, переносами строк и прочими табами.
>Поиска текста в чем? В массиве? Базе данных? Что значит нечеткого?
Ну нечеткий же, текст. Поиск по сайтику сделать.
По "ничокейпоекс" - должно находиться "нечеткий поиск". Лучше всего сразу в базе, но за неимением и в массиве поищу.
Пока самое близкое "из коробки" нашел - soundex() для мускула и он же для пхп. Но либу бы... :(
>>458712
Плюс <? ... ?> если настроено.
$zaprSQL = "SELECT * FROM table";
$rezs = mysql_query($zaprSQL);
while ($row = mysql_fetch_array($rezs)) {
\techo "<option value=" . $row['Name'] . ">" .$row['Name']. "</option>";
}
?>
На экран выводится полностью, а в value почему-то обрезается до первого пробела и передается в action так же (или обрезается уже после передачи). Почему так и как сделать, чтобы было нормально?
Как правильно, так:
class Controller {
public function delete() {
$id = (!empty($_POST['id'])) ? $_POST['id'] : null ;
$this -> model -> deleteArticle($id);
}
}
class Model {
public function deleteArticle($id) {
...
}
}
или так
class Controller {
public function delete() {
$this -> model -> deleteArticle();
}
}
class Model {
public function deleteArticle() {
$id = (!empty($_POST['id'])) ? $_POST['id'] : null;
}
}
Чтобы переносы строк нормально работали и в браузере и в ideone (и в консоли), можно использовать для этого \n, а в начале программы поставить
header("Content-Type: text/plain; charset=utf-8");
Это заставит браузер воспринимать то, что выводит твоя программа, как обычный текст, а не HTML, и уважать переносы строк в нем (так как в языке HTML перенос строки равносилен пробелу).
Иначе перенос строки будет в исходном коде страницы (его можно увидеть нажав Ctrl + U), но на самой странице его не будет.
>>459261
soundex даже рядом не стоит, во-первых он только для латинницы, во-вторых он просто удаляет часть букв. Почитай описание, он был придуман для поиска фамилий с возможностью небольших опечаток и очень примитивен.
Для поиска по сайту есть движки вроде sphinx, но в них нет такого функционала.
Насколько я знаю, для нечеткого поиска (например найти слово с учетом любого числа пропущенных букв но без опечаток или найти слово с учетом до N опечаток) используются Trie ( http://en.wikipedia.org/wiki/Trie ), причем по умоланию trie довольно громоздкое и тебе нужен будет какой-то оптимизированный способ для его хранения.
Также для поиска с опечатками вроде бы можно использовать n-грамы, но я не видел готового решения. Я вообще не уверен что этот способ дает хорошие результаты.
В общем, ты можешь погуглить, но вряд ли ты найдешь готовое решение. Тебе придется скорее всего писать свой индексер и свой вариант для поиска.
Я например смог нагуглить некий модуль для нечеткого поиска в движке lucene но не знаю, то ли это: https://lucene.apache.org/core/4_0_0/core/org/apache/lucene/search/FuzzyQuery.html
Также, помни что в твоем примере под эти буквы найдется еще куча других вариантов.
> Плюс <? ... ?> если настроено.
Не надо это использовать. Стандарты PSR советуют только <?php
>>459268
> а в value почему-то обрезается до первого пробела
Может там кавычка есть? посмотри как выголядит исходный код в браузере и что приходит в _GET/POST при отправке формы.
>>459271
> Должен ли контроллер передавать данные в модель, или же их нужно получать уже в модели?
Модель не должна обращаться к POST/GET/COOKIE и потому что это уже будет не модель. Это задача контроллера, принимать и обрабатывать запрос пользователя.
Более того подумай головой, что правильнее: сделать универсальный метод который удаляет запись с любым переданным id или сделать метод который берет id только из POST данных, а если ты хочещь удалить например 2 статьи, id которых сохранены в файле, то пиши новый метод.
Ну и еще советы.
> class Model {
Придумай нормальное название. Твое название ничего не говорит. В приложении может быть 30 моделей, какая это из них?
Более того это не модель. Класс, который загружает данные из БД называется либо TableGateway, либо DataMapper (в зависимости от того, как он реализован. И по моему я давал тебе урок где это объясняется, я уверен что давал).
Моделью в твоем случае мог бы быть класс Статья с полями заголовок, текст, датаПубликации.
> class Controller {
То же самое
> $this -> model ->
Вокруг стрелки не ставятся пробелы, также зачем писать model? Дай переменной нормальное название, например articleMapper
И еще. В MVC модель это не один класс. Это часть приложения, которая может состоять из 200 классов например. Также, моделью иногда называют объект, который соответствует какой-то сущности, например Статья, Пост, Пользователь.
И еще одна ошибка
$id = (!empty($_POST['id'])) ? $_POST['id'] : null ;
$this -> model -> deleteArticle($id);
Зачем ты передаешь null в класс работы с БД? Нельзя удалить несуществующую запись.
Если тебе не передали id то можно например вывести страницу ошибки 500 (500 это HTTP код прочитать при них можно тут https://ru.wikipedia.org/wiki/%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2_%D1%81%D0%BE%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%B8%D1%8F_HTTP ) или сделать редирект куда-нибудь.
>Может там кавычка есть? посмотри как выголядит исходный код в браузере и что приходит в _GET/POST при отправке формы.
Там наоборот, кавычек не было. Спасибо.
Тогда вдогонку вопрос, а нужно ли эти переменные как-то предварительно обрабатывать в контроллере? Валидация и прочее это уже в модели, но по крайней мере проверять на пустые значения или передавать все как есть, а там уже разбираться? Так:
class Controller {
public function delete() {
$id = (!empty($_POST['id'])) ? $_POST['id'] : null ;
$this -> model -> deleteArticle($id);
}
class Model {
public function deleteArticle($id) {
...
}
или так
class Controller {
public function delete() {
$id = $_POST['id'];
$this -> model -> deleteArticle($id);
}
class Model {
public function deleteArticle($id) {
$checkedId = (!empty($id)) ? $id : null ;
...
}
>>459294
>Придумай нормальное название.
Да это для краткости, у меня это ArticleModel
>Более того это не модель. Класс, который загружает данные из БД называется либо TableGateway, либо DataMapper (в зависимости от того, как он реализован. И по моему я давал тебе урок где это объясняется, я уверен что давал).
С этим я как раз собирался разобраться, точнее планировал использовать датамаппер внутри модели, ну как-то так например
class ArticleMapper
{
private $pdo
public function __construct() {
$this->pdo = DB::getInstance();
}
public function deleteArticleById($id) {
...
}
public function deleteArticleByTitle($title) {
...
}
public function deleteArticlesByAuthor($author) {
...
}
}
__________________
class ArticleModel
{
private $mapper;
public function __construct() {
$this->mapper = new ArticleMapper;
}
public function deleteArticle($id) {
$this->mapper->deleteArticleById($id);
}
}
>>459294
>Придумай нормальное название.
Да это для краткости, у меня это ArticleModel
>Более того это не модель. Класс, который загружает данные из БД называется либо TableGateway, либо DataMapper (в зависимости от того, как он реализован. И по моему я давал тебе урок где это объясняется, я уверен что давал).
С этим я как раз собирался разобраться, точнее планировал использовать датамаппер внутри модели, ну как-то так например
class ArticleMapper
{
private $pdo
public function __construct() {
$this->pdo = DB::getInstance();
}
public function deleteArticleById($id) {
...
}
public function deleteArticleByTitle($title) {
...
}
public function deleteArticlesByAuthor($author) {
...
}
}
__________________
class ArticleModel
{
private $mapper;
public function __construct() {
$this->mapper = new ArticleMapper;
}
public function deleteArticle($id) {
$this->mapper->deleteArticleById($id);
}
}
> но по крайней мере проверять на пустые значения или передавать все как есть, а там уже разбираться?
Пустой id передавать нельзя конечно. Ну какой смысл? Я б даже в маппере поставил условие, выбрасывать исключение если передан пустой id, чтобы не передавали.
>>459310
> у меня это ArticleModel
ArticleMapper будет лучше, я вижу ты так и написал, хорошо.
Я тут хорошую аналогию придумал. Вот представь себе порт и кран который разгружает/загружает корабли.
Модель статьи (Article) это контейнер с грузом. Маппер это портовый кран. База данных это корабль. Кран может доставать грузы с корабля (загружать объекты из базы) или наоборот класть туда (сохранять в базу).
> $this->pdo = DB::getInstance( );
Плохой код, лучше передавать PDO явно в конструктор
> class ArticleModel
Это бессмысленный класс. Во-первых непонятно зачем он нужен если мы можем вызвать delete напрямую у маппера. Во-вторых, это не модель. Модель это класс который хранит информацию об одной статье, а у тебя этого нет. Удали этот бесполезный класс.
Спасибо, я просто пытаюсь перекатиться со своим вектором громоздким для идеона уже на локалхост, и не могу настроить нормальный вывод отчета.
А ты знаешь HTML? HTML это язык разметки текста с помощью тегов, на котором пишутся веб страницы и который отображает браузер. В HTML есть теги для разметки таблиц, и с ними тебе не надо отбивать текст пробелами — браузер берет выравнивание на себя.
Знакомиться с HTML тебе придется все равно рано или поздно, так что могу посоветовать попробовать (и тут я хотел найти хорошие ссылки рассказывающие про таблицы, но хороших не нашел потому бери какие есть):
основы HTML
http://htmlbook.ru/samhtml
https://htmlacademy.ru/learn_map
таблицы в HTML
http://www.exlab.net/html/tables.html
http://htmlbook.ru/samhtml/tablitsy
Ну и конкретно в твоем случае таблица разъехалась не из-за браузера а из-за неправильного расчета ширины колонок.
Так и что, модель в таком случае вообще не нужна и контроллер просто будет к мапперу обращаться? И как в таком случае с аналогией "модель = груз" если модель тут не нужна. Да и зачем, например, может понадобиться модель Статьи?
Дизайн (оформление) и CSS это разные вещи. Одно дело уметь сделать красиво, другое дело перенести красивость на верстку с помощью CSS. То есть знания CSS будет мало.
Но тем не менее, вот например ссылка:
http://htmlbook.ru/samcss
Насчет умения делать красиво, этому учатся не один год, я думаю в твоем случае проще всего будет посмотреть как делают другие и скопировать понравившиеся идеи. Посмотри например сайты:
https://dribbble.com/
http://www.siteinspire.com/
http://fltdsgn.com/
http://www.materialup.com/
>>459334
Во-первых, помни что слово «модель» имеет 2 смысла. Может быть из-за того ты путаешься.
1) так называется один из трех компонентов MVC. Тут модель значит не один класс, а часть приложения, обычно это много классов.
2) объект, соответствующий какой-то сущности, например статье, тоже называют моделью (domain model)
Маппер (а также класс Article) это часть M (модели) из MVC.
> И как в таком случае с аналогией "модель = груз" если модель тут не нужна
Модель всегда есть в явном или неявном виде. Вот смотри, тебе надо загрузить статью из базы и отобразить. В чем ты будешь хранить заголовок, текст, и т.д? Либо в массиве, либо в объекте класса Article. То есть модель всегда есть, только она может быть сделана нормально в виде класса а может быть в виде массива.
Второе (массив) это плохо так как в большом приложении у тебя получается куча массивов непонятных видов и разобраться в этом сложно. также, у класса есть методы, а у массива нет, для работы с массивом ты пишешь функции которые находятся где-то отдельно от него и надо еще догадаться какая функция с каким массивом работает.
Как называется код, в котором много массивов непонятного вида и отдельных функций для работы с ними? Быдлокод. Чтобы его избежать, используй классы.
> Да и зачем, например, может понадобиться модель Статьи?
Чтобы например найти ее в базе и вывести. Или чтобы добавить в базу. И при этом не использовать массивы.
Дизайн (оформление) и CSS это разные вещи. Одно дело уметь сделать красиво, другое дело перенести красивость на верстку с помощью CSS. То есть знания CSS будет мало.
Но тем не менее, вот например ссылка:
http://htmlbook.ru/samcss
Насчет умения делать красиво, этому учатся не один год, я думаю в твоем случае проще всего будет посмотреть как делают другие и скопировать понравившиеся идеи. Посмотри например сайты:
https://dribbble.com/
http://www.siteinspire.com/
http://fltdsgn.com/
http://www.materialup.com/
>>459334
Во-первых, помни что слово «модель» имеет 2 смысла. Может быть из-за того ты путаешься.
1) так называется один из трех компонентов MVC. Тут модель значит не один класс, а часть приложения, обычно это много классов.
2) объект, соответствующий какой-то сущности, например статье, тоже называют моделью (domain model)
Маппер (а также класс Article) это часть M (модели) из MVC.
> И как в таком случае с аналогией "модель = груз" если модель тут не нужна
Модель всегда есть в явном или неявном виде. Вот смотри, тебе надо загрузить статью из базы и отобразить. В чем ты будешь хранить заголовок, текст, и т.д? Либо в массиве, либо в объекте класса Article. То есть модель всегда есть, только она может быть сделана нормально в виде класса а может быть в виде массива.
Второе (массив) это плохо так как в большом приложении у тебя получается куча массивов непонятных видов и разобраться в этом сложно. также, у класса есть методы, а у массива нет, для работы с массивом ты пишешь функции которые находятся где-то отдельно от него и надо еще догадаться какая функция с каким массивом работает.
Как называется код, в котором много массивов непонятного вида и отдельных функций для работы с ними? Быдлокод. Чтобы его избежать, используй классы.
> Да и зачем, например, может понадобиться модель Статьи?
Чтобы например найти ее в базе и вывести. Или чтобы добавить в базу. И при этом не использовать массивы.
> И как в таком случае с аналогией "модель = груз" если модель тут не нужна.
Если ты будешь загружать статьи из базы или сохранять в нее, модель будет нужна. Если ты только удаляешь то достаточно только id, но ведь вряд ли у тебя будет только возможность удалять без возможности добавлять?
Да, хотел без этого обойтись как бы. Не вручную же строить табличку. Думаешь у меня функция неправильно считает? Та же самая функция на идеоне выводит все отлично. Может быть дело в том что на идеоне пробелы равны по ширине с другими символами, а тут все не так? Строки одинаковой длины (количество символов) могут быть по факту разной длины (количетсов пикселей)
>Чтобы например найти ее в базе и вывести. Или чтобы добавить в базу.
>>459340
>Если ты будешь загружать статьи из базы или сохранять в нее, модель будет нужна
И почему в этом случае тоже не использовать маппер? Методами вроде getArticleById($id), insertNewArticle($title, $author, $text). Ну или приведите пример метода контроллера в котором нужно использовать модель Статья.
Мне надо не то чтобы прям охуеть как красиво, но более-менее приятно глазу и читаемо. И да, есть ссылки на русскоязычные материалы? Понятно, что в гугле их хоть жопой жуй, но годные ли они?
> Может быть дело в том что на идеоне пробелы равны по ширине с другими символами, а тут все не так?
при text/plain браузер использует моноширинный шрифт. Если не веришь замени пробел например на точку и посчитай их количество.
Проблема в твоем коде.
> Да, хотел без этого обойтись как бы. Не вручную же строить табличку.
С html таблицей как раз было бы проще, так как не надо пробелами добивать. Но можешь пока текстом делать. Но все равно потом будешь HTML изучать (и у нас кстати есть годные задачки на HTML/CSS).
> Строки одинаковой длины (количество символов) могут быть по факту разной длины (количетсов пикселей)
Могут но не в этом случае.
>>459376
> Методами вроде getArticleById($id),
А что возвращает getArticleById? Модель статьи.
> insertNewArticle($title, $author, $text).
это у тебя сейчас 3 поля. А если их 10 будет, что ты будешь делать? Функция с больше чем 4-5 аргументами недопустима, так как в них становится тяжело разбираться.
> Ну или приведите пример метода контроллера в котором нужно использовать модель Статья.
Метод который берет статью из базы и выводит.
>>459383
Там сайты с картинками, там нет объяснений, только картинки которые ты можешь смотреть и копировать удачные идеи оформления. Так что неважно на каком они языке.
Ну вот если хочешь на русском, можешь посмотреть сайты например от студии Лебедева, как пример: http://www.artlebedev.ru/everything/web/
Также ты можешь взять готовые CSS фреймворки например Twitter Bootstrap которые содержат готовые хорошо выглядящие компоненты, таблицы, кнопки, и т.д.
> И да, есть ссылки на русскоязычные материалы?
Я не знаю, может какие-нибудь книги про дизайн? Не уверен что это можно найти в виде статей, я думаю, нет. И я ни разу не видел статей например про то, как сделать красивую страницу сайта. Я видел книги про шрифты и оформление текста, книги про юзабилити, книги про принципы дизайна, например, но они большие и ты замучаешься их изучать.
Для начинающих например могу посоветовать книгу «недизайнерская книга о дизайне» - она не про дизайн сайтов, но она рассказывает на какие вещи надо обращать внимание при верстке текста и про принципы диазйна (близость/контрастность и т.д.)
Дизайнеры сайтов, насколько я знаю, учатся больше по примерам, то есть смотрят как делают другие. Ну и теорию тоже изучают конечно.
> Может быть дело в том что на идеоне пробелы равны по ширине с другими символами, а тут все не так?
при text/plain браузер использует моноширинный шрифт. Если не веришь замени пробел например на точку и посчитай их количество.
Проблема в твоем коде.
> Да, хотел без этого обойтись как бы. Не вручную же строить табличку.
С html таблицей как раз было бы проще, так как не надо пробелами добивать. Но можешь пока текстом делать. Но все равно потом будешь HTML изучать (и у нас кстати есть годные задачки на HTML/CSS).
> Строки одинаковой длины (количество символов) могут быть по факту разной длины (количетсов пикселей)
Могут но не в этом случае.
>>459376
> Методами вроде getArticleById($id),
А что возвращает getArticleById? Модель статьи.
> insertNewArticle($title, $author, $text).
это у тебя сейчас 3 поля. А если их 10 будет, что ты будешь делать? Функция с больше чем 4-5 аргументами недопустима, так как в них становится тяжело разбираться.
> Ну или приведите пример метода контроллера в котором нужно использовать модель Статья.
Метод который берет статью из базы и выводит.
>>459383
Там сайты с картинками, там нет объяснений, только картинки которые ты можешь смотреть и копировать удачные идеи оформления. Так что неважно на каком они языке.
Ну вот если хочешь на русском, можешь посмотреть сайты например от студии Лебедева, как пример: http://www.artlebedev.ru/everything/web/
Также ты можешь взять готовые CSS фреймворки например Twitter Bootstrap которые содержат готовые хорошо выглядящие компоненты, таблицы, кнопки, и т.д.
> И да, есть ссылки на русскоязычные материалы?
Я не знаю, может какие-нибудь книги про дизайн? Не уверен что это можно найти в виде статей, я думаю, нет. И я ни разу не видел статей например про то, как сделать красивую страницу сайта. Я видел книги про шрифты и оформление текста, книги про юзабилити, книги про принципы дизайна, например, но они большие и ты замучаешься их изучать.
Для начинающих например могу посоветовать книгу «недизайнерская книга о дизайне» - она не про дизайн сайтов, но она рассказывает на какие вещи надо обращать внимание при верстке текста и про принципы диазйна (близость/контрастность и т.д.)
Дизайнеры сайтов, насколько я знаю, учатся больше по примерам, то есть смотрят как делают другие. Ну и теорию тоже изучают конечно.
Что-то я окончательно запутался.
Попробую сначала. Изначально в моем понимании все должно было работать так - пользователь вызывает метод КонтроллераСтатьи, КонтроллерСтатьи создает экземпляр МоделиСтатьи и вызывает похожий метод МоделиСтатьи, передавая туда айди. Внутри этого метода берется экземпляр Маппера, Маппер производит какие-то операции с базой, возвращает результат в Модель, Модель - в Контроллер, Контроллер - во Вью. И тут вы говорите, что для, например, удаления модель не нужна, а для поиска - нужна. Мне не понятны сразу два момента.
Нормально ли то что Контроллер запускает методы Маппера, разве это не 'бизнес-логика' которая по определению должна быть в модели?
Почему же все-таки для поиска статьи нельзя точно также использовать Маппер? Если вы хотите сказать, что удаление по идее должно возвращать только true/false, а поиск ассоциативный массив вроде {'автор' => 'вася', 'заголовок' => 'aaa','текст' => "ххх"}, то почему его нельзя передать во вью и дальше работать. Зачем тут модель?
И вот еще
>Метод который берет статью из базы и выводит.
Хорошо, а как он будет использовать модель-то? Вот пусть
class ArticleController
{
public function getArticle() {
$model = new ArticleModel();
//что дальше, разве не такой же вызов маппера?
}
так может у тебя твой файл сохранен в плохой кодировке? Пересохрани сам файл который открываешь в браузере в utf-8
А хуй тебе не пососать?
Да не торопись, как оп запилит, так и перекатимся, он сначала должен всем ответить и все такое. Он же тут главный у нас.
Я один в тайне надеюсь, что когда я решу все задачки из его учебника, он пришлет мне на почту инструкцию как устроиться в крутую контору, где он тимлид или сорт оф, и уже работают олдфаги отсюда??
>Я один в тайне надеюсь, что когда я решу все задачки из его учебника, он пришлет мне на почту инструкцию как устроиться в крутую контору, где он тимлид или сорт оф, и уже работают олдфаги отсюда??
Даже круче, он даст тебе задачку на сайт студентов.
В HTML коде пропиши <meta charset>: http://htmlbook.ru/html/meta/charset с utf-8
>>459449
> КонтроллерСтатьи создает экземпляр МоделиСтатьи и вызывает похожий метод МоделиСтатьи, передавая туда айди
Ты не понял что такое модель (хотя я уже 3-й раз пытаюсь объяснить). Модель это класс содержащий информацию об одной статье, а не класс удаляющий их из базы. Также моделью называют часть приложения отвечающую за бизнес логику (но это не один класс, а несколько).
Потому это неправильно:
> КонтроллерСтатьи создает экземпляр МоделиСтатьи
не надо создавать МодельСтатьи если ты хочешь просто удалить запись из базы.
> И тут вы говорите, что для, например, удаления модель не нужна, а для поиска - нужна.
Нет. Мы просто о разных моделях говорим. Я тебе говорю, что у слова модель 2 разных значения, а ты думаешь что приложение должно содержать класс Модель который работает с базой (что неправильно). Если ты прочел это в какой-то статье то она неправильная. Если ты это сам придумал то ты ошибся.
Вся работа с базой данных делается через класс ArticleMapper или как-то так.
> Нормально ли то что Контроллер запускает методы Маппера, разве это не 'бизнес-логика' которая по определению должна быть в модели?
Маппер это часть модели. Потому бизнес-логика в модели, все нормально. Модель в MVC это же не один класс, а много: мапперы, сервисы, хелперы, сущности, валидаторы и т.д.
> Почему же все-таки для поиска статьи нельзя точно также использовать Маппер?
Можно:
$article = $articleMapper->findById(100);
// возвращает объект-сущность класса Article
> , а поиск ассоциативный массив вроде {'автор' => 'вася', 'заголовок' => 'aaa','текст' => "ххх"}
Это плохая идея. Лучше возвращать объект Article, у нас же ООП код, а не массиво-ориентированное программирование
> то почему его нельзя передать во вью и дальше работать. Зачем тут модель?
Так этот массив и есть модель статьи, только в странном извращенном виде. Ну я же написал выше чем массивы плохие:
> массив это плохо так как в большом приложении у тебя получается куча массивов непонятных видов и разобраться в этом сложно. также, у класса есть методы, а у массива нет, для работы с массивом ты пишешь функции которые находятся где-то отдельно от него и надо еще догадаться какая функция с каким массивом работает.
> Хорошо, а как он будет использовать модель-то? Вот пусть
> class ArticleController
> {
> public function getArticle() {
> $model = new ArticleModel();
Что такое ArticleModel? Я не понимаю этот код. Мне кажется ее тут не должно быть а должно быть так:
public function viewArticle() {
$id = 100;
$article = $this->articleMapper->findByid($id);
if (!$article) {
//Если статья не найдена, покажем ошибку
return $this->show404Page( );
}
// Если все ок то выведем страницу со статьей
// c помощью соотв. шаблона
return $this->render('article.phtml', array(
'article' => $article
));
}
В HTML коде пропиши <meta charset>: http://htmlbook.ru/html/meta/charset с utf-8
>>459449
> КонтроллерСтатьи создает экземпляр МоделиСтатьи и вызывает похожий метод МоделиСтатьи, передавая туда айди
Ты не понял что такое модель (хотя я уже 3-й раз пытаюсь объяснить). Модель это класс содержащий информацию об одной статье, а не класс удаляющий их из базы. Также моделью называют часть приложения отвечающую за бизнес логику (но это не один класс, а несколько).
Потому это неправильно:
> КонтроллерСтатьи создает экземпляр МоделиСтатьи
не надо создавать МодельСтатьи если ты хочешь просто удалить запись из базы.
> И тут вы говорите, что для, например, удаления модель не нужна, а для поиска - нужна.
Нет. Мы просто о разных моделях говорим. Я тебе говорю, что у слова модель 2 разных значения, а ты думаешь что приложение должно содержать класс Модель который работает с базой (что неправильно). Если ты прочел это в какой-то статье то она неправильная. Если ты это сам придумал то ты ошибся.
Вся работа с базой данных делается через класс ArticleMapper или как-то так.
> Нормально ли то что Контроллер запускает методы Маппера, разве это не 'бизнес-логика' которая по определению должна быть в модели?
Маппер это часть модели. Потому бизнес-логика в модели, все нормально. Модель в MVC это же не один класс, а много: мапперы, сервисы, хелперы, сущности, валидаторы и т.д.
> Почему же все-таки для поиска статьи нельзя точно также использовать Маппер?
Можно:
$article = $articleMapper->findById(100);
// возвращает объект-сущность класса Article
> , а поиск ассоциативный массив вроде {'автор' => 'вася', 'заголовок' => 'aaa','текст' => "ххх"}
Это плохая идея. Лучше возвращать объект Article, у нас же ООП код, а не массиво-ориентированное программирование
> то почему его нельзя передать во вью и дальше работать. Зачем тут модель?
Так этот массив и есть модель статьи, только в странном извращенном виде. Ну я же написал выше чем массивы плохие:
> массив это плохо так как в большом приложении у тебя получается куча массивов непонятных видов и разобраться в этом сложно. также, у класса есть методы, а у массива нет, для работы с массивом ты пишешь функции которые находятся где-то отдельно от него и надо еще догадаться какая функция с каким массивом работает.
> Хорошо, а как он будет использовать модель-то? Вот пусть
> class ArticleController
> {
> public function getArticle() {
> $model = new ArticleModel();
Что такое ArticleModel? Я не понимаю этот код. Мне кажется ее тут не должно быть а должно быть так:
public function viewArticle() {
$id = 100;
$article = $this->articleMapper->findByid($id);
if (!$article) {
//Если статья не найдена, покажем ошибку
return $this->show404Page( );
}
// Если все ок то выведем страницу со статьей
// c помощью соотв. шаблона
return $this->render('article.phtml', array(
'article' => $article
));
}
А если открыть исходный код (Ctrl + U) там тоже все криво когда используются пробелы?
>>459512
Не торопи лошадей. ОП запилит завтра или послезавтра.
>>459519
:)
>>459516
Учебник только начало долгого пути. Так что не завышай свои ожидания.
Ну и в «крутую» контору вроде яндекса с одним знанием php попасть маловероятно, у них требования к студентам-стажерам как в обычных компаниях к миддлам. Изучать придется еще другие языки, алгоритмы, структуры данных и все такое (но в нашем треде при желании мы и этому научим).
И кстати, заметил еще ошибку: значение «всего» для отношения тугрикки/документы не имеет смысла и не надо его выводить.
>Маппер это часть модели. Потому бизнес-логика в модели, все нормально. Модель в MVC это же не один класс, а много: мапперы, сервисы, хелперы, сущности, валидаторы и т.д.
Хм. Из статьи на хабре, вот этой http://habrahabr.ru/post/150267/ я решил что модель это класс, который наследуется от базового и заводится под каждый соответствующий контроллер и вид, и да, я решил что он должен работать с базой - сам или через экземпляр маппера; при этом у статических страничек модели может и не быть, так как им не нужна инфа из базы. Вощемта цитата оттуда
>Модель обычно включает методы выборки данных, например:
>1. методы нативных библиотек pgsql или mysql;
Ладно, похоже я просто угорел уже, буду завтра разбираться заново.
> Из статьи на хабр
статья не идеальная. Ну например схема MVC в начале это схема MVC из десктопных, а не веб приложений (кто-то в комментах обратил внимание на странную стрелку, но причину не понял)
В вебе View не вызывает методы контроллера.
Ну и автор вместо моделей сделал хранение информации о портфолио на массивах, тоже наверно ради упрощения.
> я решил что модель это класс, который наследуется от базового и заводится под каждый соответствующий контроллер и вид,
Нет, это не так. Моделью называют все классы отвечающие за хранение и обработку данных предметной области. Не только работающие с БД.
> я решил что он должен работать с базой - сам или через экземпляр маппера
Маппер это и есть часть модели.
> Вощемта цитата оттуда
>>Модель обычно включает методы выборки данных, например:
Ну маппер это часть модели и он включает методы выборки данных, тут все ок. Просто автор статьи решил зачем-то все что относится к модели засунуть в класс с названием Model, может он думал что так понятнее будет. На практике если ты будешь все в один класс запихивать, то он будет огромным.
Потому делают отдельные классы:
- мапперы для работы с БД
- классы-сущности хранящие информацию об объектах предметной области, например статья, новость и тд
- хелперы для работы не с Бд, а например что-то делать с файлами или еще что-нибудь
- сервисы для более высокоуровневых действий, они могут объединять работу с несколькими мапперами например
Это по разному в разных фреймворках называется, но суть примерно та же.
> модель это класс, который наследуется от базового и заводится под каждый соответствующий контроллер и вид
Нет, это тоже не так. Контроллеры соответствуют обычно разделам сайта, сколько разделов столько и контроллеров. Мапперы соответствуют таблицам в БД. И их число не обязательно совпадает с числом контроллеров.
В общем, в статье есть неточности, может автор сам что-то не допонимает или пытается излишне упростить.
Ну и повторю то что говорил раньше, если бы ты изучал как реализован MVC в Yii2/Symfony 2 ты бы все это увидел.
> Из статьи на хабр
статья не идеальная. Ну например схема MVC в начале это схема MVC из десктопных, а не веб приложений (кто-то в комментах обратил внимание на странную стрелку, но причину не понял)
В вебе View не вызывает методы контроллера.
Ну и автор вместо моделей сделал хранение информации о портфолио на массивах, тоже наверно ради упрощения.
> я решил что модель это класс, который наследуется от базового и заводится под каждый соответствующий контроллер и вид,
Нет, это не так. Моделью называют все классы отвечающие за хранение и обработку данных предметной области. Не только работающие с БД.
> я решил что он должен работать с базой - сам или через экземпляр маппера
Маппер это и есть часть модели.
> Вощемта цитата оттуда
>>Модель обычно включает методы выборки данных, например:
Ну маппер это часть модели и он включает методы выборки данных, тут все ок. Просто автор статьи решил зачем-то все что относится к модели засунуть в класс с названием Model, может он думал что так понятнее будет. На практике если ты будешь все в один класс запихивать, то он будет огромным.
Потому делают отдельные классы:
- мапперы для работы с БД
- классы-сущности хранящие информацию об объектах предметной области, например статья, новость и тд
- хелперы для работы не с Бд, а например что-то делать с файлами или еще что-нибудь
- сервисы для более высокоуровневых действий, они могут объединять работу с несколькими мапперами например
Это по разному в разных фреймворках называется, но суть примерно та же.
> модель это класс, который наследуется от базового и заводится под каждый соответствующий контроллер и вид
Нет, это тоже не так. Контроллеры соответствуют обычно разделам сайта, сколько разделов столько и контроллеров. Мапперы соответствуют таблицам в БД. И их число не обязательно совпадает с числом контроллеров.
В общем, в статье есть неточности, может автор сам что-то не допонимает или пытается излишне упростить.
Ну и повторю то что говорил раньше, если бы ты изучал как реализован MVC в Yii2/Symfony 2 ты бы все это увидел.
Прошу проверки.
http://ideone.com/3NpjcF
Думаю что косяки есть в плане логики и прочих вещей. Не знаю как выбирать например половину объектов, пришлось сначала посчитать все, потом пройтись по списку объектов циклом со счетчиком, и первую половину повышать. В общем наверное тупо как-то все.
>Контроллеры соответствуют обычно разделам сайта, сколько разделов столько и контроллеров. Мапперы соответствуют таблицам в БД.
Вот это предельно ясно. Если бы с моделью было все также просто.
>- мапперы для работы с БД
>- классы-сущности
>- хелперы
>- сервисы
Если я пока необходимости в хелперах и сервисах не вижу можно ли временно упростить понятие до модель = мапперы и сущности? Вероятно я пытался засунуть экземпляр маппера в сущность, их-то я и называл ArticleModel по аналогии с model_portfolio из статьи. Опять же, момент где автор возвращает из model_portfolio массив массивов с инфой по статьям я понял как упрощенный метод добычи их из базы. Но раз сущности нужны не для этого, то для чего? В пред. постах ты говоришь - для хранения информации об одной статье. То есть маппер будет возвращать что-то вроде
public function getArticleById ($id) {
...
return new Article('title', 'author', 'text');
}
или
public function getArticlesByAuthor ($author) {
...
return [new Article('title1', 'authorX', 'text1'), new Article('title2', 'authorX', 'text2'), new Article('title3', 'authorX', 'text3') ]
}
А у этого класса Article будут методы вроде getAuthor() которые вызываются во view там куда надо подставить автора.
Охщет, круто же придумано.
>Ну и повторю то что говорил раньше, если бы ты изучал как реализован MVC в Yii2/Symfony 2 ты бы все это увидел.
Я тогда попробовал еще раз, но там очень много файлов, много кода, сама структура папок не совсем понятная и на каждом шагу встречается что-то, чего я еще не знаю, про композер, пространства имен, шаблонизаторы, например, я лезу читать про них, отвлекаюсь от основной цели и очень туго это все идет. Но да, пожалуй начну параллельно.
Вот в yii я создал отдельную MVC для взаиможействия с таблицей тестов, всё отдельными файлами, теперь создать отельную страничку для прсмотра табица не сложно.
Но вот как правильние будет вывести список тестов на главной странице, которая управляется другой MVC ?
Можно же, как то их подключить друг к другу не копипастя коды взаимоействия с бд.
Пару лет назад запилил маме небольшой сайт- галерею с картинами , иногда пополняю. там почти голый html с css , сейчас хочу ей помочь , ну и сам потренироваться-
прикрутить небольшую базу чтобы под над/на/не суть каждой картиной сделать значок о том продается она или нет. Подскажите новичку как это делать по уму.
Чтобы управлять этим из админки*
По нажатию кнопки на страничке?
Гуглишь как сделать кнопку, прописываешь ей метод POST
а в коде пхп скрипта у тебя должно быть что-то типа:
if (isset($_POST) {
вызываешь тут свою функцию.
}
Ну тип приметивнейший способ.
А ну еще можно сделать кнопку, которая просто ведет на страницу, на которой собственно php код с твоей функцией, и можно обойтись без всяких проверок даже.
> Если я пока необходимости в хелперах и сервисах не вижу можно ли временно упростить понятие до модель = мапперы и сущности?
да. Ты не обязан их делать если они не нужны
> Опять же, момент где автор возвращает из model_portfolio массив массивов с инфой по статьям я понял как упрощенный метод добычи их из базы.
Да. Модель и не обязана данные брать из базы, можно их и в коде прописать если они не меняются.
> Но раз сущности нужны не для этого, то для чего?
Они нужны там где ты хочешь передать информацию о статье откуда-то куда-то
> То есть маппер будет возвращать что-то вроде
> return new Article('title', 'author', 'text');
Да
> А у этого класса Article будут методы вроде getAuthor() которые вызываются во view там куда надо подставить автора.
Да
> но там очень много файлов, много кода, сама структура папок не совсем понятная и на каждом шагу встречается что-то, чего я еще не знаю, про композер, пространства имен, шаблонизаторы,
Ну ок но это все равно потом все придется изучить. Кстати у нас есть задание на список студентов и файлообменник которое проще чем Yii но в нем тебе тоже некоторые вещи вроде датамаппера и шаблонов встретятся, а также простой микрофреймворк Slim (задание в оп посте)
> Можно же, как то их подключить друг к другу не копипастя коды взаимоействия с бд.
Код взаимодействия с БД в YIi обычно пишут в моделях. Соответственно копипасты не требуется. Покаже код или кусочек кода чтобы было понятнее.
>>459734
> $dep->countManagers12( );
Это слишком специфичный метод, ну подумай сам тогда ты должен для универсальности добавить кучу методов вроде countEngineers123, countAnalysts1 и тд. Тут лучше сделать универсальный метод отбора с параметрами, куда например передается профессия или же ты можешь сделать отбор кандидатов из полного списка внутри Anticrisis по нужным тебе критериям (функция array_filter хорошо для этого подходит).
Далее, чтобы отобрать половину массива, удобно использовать array_slice. Не забудь перед этим отсортировать массив чтобы первыми шли те люди которые требуются по условию (там как я помню отбирать надо в первую очередь людей определенного ранга).
> public function askManager()
То же самое, странный метод. Наверно проверять менеджер ли это лучше снаружи.
>>459793
А ты SQL знаешь? Если нет то надо начать с изучения. У нас кстати в оп посте есть ссылки и простые задачки на него.
После SQL наверн придется освоить PDO чтобы взаимодействовать с базй из php
>>459802
С помощью HTML формы или ссылки.
>о слишком специфичный метод, ну подумай сам тогда ты должен для универсальности добавить кучу методов вроде countEngineers123
Ну мне тяжело пока дается планирование таких вещей, я просто сажусь и пытаюсь решить задачу сразу.
>То же самое, странный метод. Наверно проверять менеджер ли это лучше снаружи.
Вот это замечание я вообще не понял.
Может ты мне дашь пару рекомендаций как построить это антикризисное решение?
> Вот это замечание я вообще не понял.
Просто перенеси функцию askManager (которая слишком специфична) в класс Anticrisis. Она же нужна только для антикризисного решения, пусть там и будет. Если ты добавляешь функции в классы Emplyee/Department то лучше добавлять более универсальные функции, а не функции вроде «посчитать число инженеров 1 ранга не являющимися боссом».
> Может ты мне дашь пару рекомендаций как построить это антикризисное решение?
Смотри, как можно отбирать людей для повышения/увольнения/etc
- берем всех сотрудников депатамента
- через array_filter отбираем тех кто подходит под наши условия
- через usort сортируем их, например если требуется уволить в первую очередь людей низкого ранга то сортируем по возрастанию
- через array_slice отбираем нужный процент
- через foreach повышаем\увольняем/сокращаем зарплату
http://ideone.com/BxS32J
Подскажите книгу для чайников о компьютерном железе. Хочется понимать, как устроен жесткий диск и файловая система, как работает процессор и оперативная память, разобраться в этих биосах/досах.
Таненбаума не предлагать, слишком сложно.
Есть таблица пользователей и таблица неких элементов. По запросу, нужно выдавать юзеру случайный элемент, который ему еще не выдавался. Как это можно реализовать, анон?
Пилить третью таблицу с историей выдачи юзерам элементов и каждый раз сверяться с ней.
а то я изучаю сейчас и всё в куче, а на собеседованиях
любят такое спрашивать
Спасибо!
Дизайнеры рисуют, версталы верстают, а я юзаю бутстрап и мне норм
>бутстрап
Я правильно понимаю, это сборка шаблонов, форм, кнопочек, стилей и прочей полезной херни?
Лучше научиться использовать float/clear/проценты/margin чтобы ты сам мог сделать любой аналогичный лейаут. Эти примеры можно использовать только как примеры для изучения, не более. А то что это за верстальщик который не может 3 колонки сверстать?
>>460281
Бустрап подходит только когда макет изначально под него делается (например админка или что-нибудь с формами), если его совать везде, то придется кучу стилей переопределять. Неудобно.
>>460289
да
Окей, вот стараюсь сделать по твоей рекомендации:
подаю организацию в свой антикризисный метод, далее иду по всем департаментам, внутри каждого департамента я смог пройтись по массиву сотрудников, и вывести на экран своих менеджеров 1-2 ранга через array_filter.
И сразу проблема: функция которая у меня используется для array_filter должна быть обычной функцией, а не методом класса, пришлось её выкинуть за пределы департамента.
>- через usort сортируем их, например если требуется уволить в первую очередь людей низкого ранга то сортируем по возрастанию
Что-то я не особо понимаю что мне дальше с этим можно сделать? Зачем их сортировать, если они и так все подходят уже.
Я что-то не понимаю как мне теперь дальше действовать с отсортировкой и array_slice
У меня ведь на руках сейчас не массив работников, а по факту обрывки массива. У меня не хватает понимания как работать то с этим? Их можно в какой-то временный массив сохранить?
>Бустрап подходит только когда макет изначально под него делается (например админка или что-нибудь с формами), если его совать везде, то придется кучу стилей переопределять. >Неудобно.
У меня вообще голый код, ничего не дизайнил никогда. Надеюсь, не будет трудно разобраться.
> И сразу проблема: функция которая у меня используется для array_filter должна быть обычной функцией
Нет. В PHP ты можешь передать обычную функцию, обычный или статический метолд, анонимную функцию.
Открой мануал http://php.net/manual/en/function.array-filter.php
Видишь, там написано callable $callback
Прочти что такое callable: http://php.net/manual/ru/language.types.callable.php
Кстати, анонимная функция имеет доступ к this внутри метода и потому ее удобнее всего тут использовать: https://php.net/manual/ru/functions.anonymous.php
А использовать внешнюю функцию тут не лучшая идея, так как во-первых она далеко от места использования, во-вторых она больше нигде не нужна кроме антикризисного метода.
> Зачем их сортировать, если они и так все подходят уже.
Ты невнимательно читал задание. Вот смотри, у тебя есть 5 инженеров 1 ранга и 15 второго. Ты должен уволить 10, начиная с самого нижнего ранга. То есть ты должен уволить всех кто с первым рангом и часть со вторым. Без сортировки если ты возьмешь первых 10 инженеров не факт что они будут распределены как нужно.
> У меня ведь на руках сейчас не массив работников, а по факту обрывки массива. У меня не хватает понимания как работать то с этим? Их можно в какой-то временный массив сохранить?
Обрывок массива это такой же массив. Сохраняй конечно.
http://ideone.com/sqdexe
Вот код, он в принципе работал так как я и хотел, но до момента когда я решил приделать поиск по базе через get запрос:
<li><a href="http://localhost/php/register/index.php?page=<?=$previousPage?>"><?=$previousPage?></a></li>
Вот эта часть http://localhost/php/register/index.php?page= удаляет гет запрос, я уже пытался саму функцию пагинатора переделать и вставить сюда текущий урл
<li><a href="<?=$currentURL ?>?page=<?=$previousPage?>"><?=$previousPage?></a></li>
Но так выходят бесконечные адреса если кликать по страницам поиска: например вот так
http://localhost/php/register/index.php?page=2?page=2?page=3?page=2?page=2?page=2?page=1 , и сам вопрос, как можно добавить универсальности без привязки к странице через http://localhost/php/register/index.php?page=
?
http://ideone.com/y41o84 пошел он нахуй
> я уже пытался саму функцию пагинатора переделать и вставить сюда текущий урл
Удобно не брать текущий URL, а передавать в пагинатор шаблон URL:
index.php?x=1&y=2&page{page}
в который он будет подставлять номера страниц.
И еще.
Если честно, код очень тяжело читать, так как ты намешал все в одну кучу, тут и функция, и куски HTML. Вот, что стоит сделать чтобы его улучшить:
— вынести весь HTML в отдельный шаблон как тут http://www.phpinfo.su/articles/practice/shablony_v_php.html
— не писать require внутри функции, а писать в начале файла
— дать переменной data номальное имя. Вот статья для вдохновения: http://learn.javascript.ru/write-unmain-code
> aria-label
Ты знаешь стандарт ARIA или ты это скопировал откуда-то? Если не знаешь то надо либо удалить атрибуты либо изучить их, так как неправильно проставленные атрибуты только навредят и помешают работе программы чтения с экрана.
Ну и если ты делаешь задачку о студентах, тебе придется переделать это на ООП. Ничего страшного, выложи свой код, например на гитхаб, и я дам подробные советы что и как делать.
В твоем коде наверно точки с запятой не хватает. Но SQL надо выкладывать не на ideone, а на сайт sqlfiddle, попробуй. очень удобно.
Ну и у нас в ОП треде есть годные задачки на SQL
А, и еще. AUTO_INCREMENT это не часть стандарта SQL это особенность MySQL. Соответственно на ideone может быть используется другой диалект SQL (там sqlite) и там это не сработает. Но на sqlfiddle есть поддержка MySQL Почему я и советую его использовать.
>Ты знаешь стандарт ARIA или ты это скопировал откуда-то? Если не знаешь то надо либо удалить атрибуты либо изучить их, так как неправильно проставленные атрибуты только навредят и помешают работе программы чтения с экрана.
это с bootstrap стиля
>Удобно не брать текущий URL, а передавать в пагинатор шаблон URL:
index.php?x=1&y=2&page{page}
в который он будет подставлять номера страниц.
Есть пример? Я в теории всё это представляю, но с практической точки зрения не знаю с чего начать.
Примеров, боюсь, нет.
Ты не знаешь как в строке заменить конструкцию {page} на номер страницы? str_replace например можно использовать.
>>460410
Вот переделал сайт студентов и доделал то, чего не хватало https://github.com/Si0n/register
sql таблицу я ещё не переделывал (типы данных столбцов) по старым замечаниям.
Есть пхп код, на фоне его нужно запилить библиотеку передачи файлов на FTP\SFTP
<?php
include 'file_transfer_lib.php';
use FileTransfer as FT;
$factory = new FT\Factory();
try
{
$conn = $factory->getConnection('ssh', 'user', 'pass', 'hostname.com', 2222);
$conn->cd('/var/www')
->download('dump.tar.gz')
->close();
}
catch(Exception $e)
{
echo $e->getMessage();
}
try
{
$conn = $factory->getConnection('ftp', 'user', 'pass', 'hostname.com');
echo $conn->pwd() . "\n";
$conn->upload('archive.zip');
print_r($conn->exec('ls -al'));
}
catch (Exception $e)
{
echo $e->getMessage();
}
Не могу понять, что должно быть в этой библиотеке, если конкретно в этом скрипте можно прописать все необходимые инструкции.
Есть пхп код, на фоне его нужно запилить библиотеку передачи файлов на FTP\SFTP
<?php
include 'file_transfer_lib.php';
use FileTransfer as FT;
$factory = new FT\Factory();
try
{
$conn = $factory->getConnection('ssh', 'user', 'pass', 'hostname.com', 2222);
$conn->cd('/var/www')
->download('dump.tar.gz')
->close();
}
catch(Exception $e)
{
echo $e->getMessage();
}
try
{
$conn = $factory->getConnection('ftp', 'user', 'pass', 'hostname.com');
echo $conn->pwd() . "\n";
$conn->upload('archive.zip');
print_r($conn->exec('ls -al'));
}
catch (Exception $e)
{
echo $e->getMessage();
}
Не могу понять, что должно быть в этой библиотеке, если конкретно в этом скрипте можно прописать все необходимые инструкции.
Я тоже не понимаю, зачем запиливать библиотеку если она уже есть — файл file_transfer_lib.php
А, ты спрашивал что в этом файле должно быть? Ну очевидно что класс FT\Factory и другие классы, обраузющие библиоетку. Проще говоря после того как ты напишешь этот файл, код выше должен работать.
И еще, у меня ощущение что это тестовое задание. Тестовое задание проверяет твои знания, а не наши, потому тебе придется писать его самостоятельно в любом случае.
> Не могу понять, что должно быть в этой библиотеке, если конкретно в этом скрипте можно прописать все необходимые инструкции.
Как я понимаю, ты не можешь менять этот файл, а должен написать file_transfer_lib.php. Ну и от тебя требуется написать универсальную ООП библиотеку для FTP а не работающие только в одном случае «инструкции»
И если это тестовое задание то такие вопросы надо уточнять у того кто тебе его дал. Ты делаешь большую глупость, уточняя задание у случайных анонов с двача.
Ты CSS знаешь? Там есть свойство width. Если не знаешь то тебе надо сначала изучить CSS (это тебе пригодится не только в этом случае, а еще во многих).
Если ты хочешь лучше разобраться в CSS, то у нас в ОП посте есть хорошие задания по CSS, ты мог бы их порешать, а я бы проверил и дал советы как сделать лучше. После этих заданий поменять ширину формы для тебя будет задачей на полминуты.
Уже разобрался. В бустрапе по-хитрому это можно редактировать, через колонки, на которые делится страница. Затык был в том, что не мог найти подходящего примера, как нашел, так сразу все понятно стало.
Вот тебе пока порция замечаний от робота, чтобы не скучать:
Ты используешь функции mb_xxx в своем коде, а указал ли ты для них используемую кодировку с помощью mb_internal_encoding(...)? Без этого эти функции могут неправильно обрабатывать строки.
Задал ли ты кодировку соединения с базой при работе через PDO? Это можно сделать либо параметром charset= при соединении либо командой SET NAMES в PDO::MYSQL_ATTR_INIT_COMMAND. Мануал: http://php.net/manual/ru/ref.pdo-mysql.connection.php
В файле ./action.php:
Не используй короткий открывающий тег <? так как он может быть отключен в настройках. Используй либо длинный открывающий тег <?php для кода, либо короткий <?= для вывода значений в шаблонах.
В файле ./register.php:
Не используй короткий открывающий тег <? так как он может быть отключен в настройках. Используй либо длинный открывающий тег <?php для кода, либо короткий <?= для вывода значений в шаблонах.
(замечания про ENUM и YEAR я вырезал)
>, а я юзаю бутстрап и мне норм
Давай поясняй, как сделать так, чтобы спойлер был открыт при загрузке страницы?
Спойлер сделал так:
<a href="#spoiler-1" data-toggle="collapse" class="btn btn-primary spoiler">Спойлер</a>
<div class="collapse" id="spoiler-1">
\t<div class="well">
</div>
</div>
Бля, как всегда - стоит только попросить, как находишь решение самостоятельно.
Где хранить личные фотографии юзеров? Не в паблике же? А если не в паблике, то как их доставлять куда нужно?
>>459028
Анон, я тут немного проверил твой код. Вот комменатрии.
> `comment_path` text NOT NULL,
это плохая идея, исплоьзовать для пути текст, так как его нельзя добавить в индексы и мы не сможем быстро выбирать отсортированные комментарии. Надо использовать varchar с разумным значением длины.
> `file_id` int(11) NOT NULL,
Не проставлены внешние ключи: http://denis.in.ua/foreign-keys-in-mysql.htm
> PRIMARY KEY (`id`),
> UNIQUE KEY `id` (`id`)
UNIQUE тут лишний так как PRIMARY KEY по определению уникален (первыичнй ключ это набор колонок отличающих запись от других).
> `size` int(11) NOT NULL,
int хранит числа от -2 млрд до +2 млрд. Значит, размер больше 2 Гб не запишется. Не уверен что такой файл вообще получится загрузить, но помнить о таких вещах стоит.
> `file_key` varchar(10) CHARACTER SET utf8 NOT NULL,
Наверно надо пометить как уникальное
https://github.com/tokotun/uppy/blob/master/index.php#L76
> $errorLoad = \Uppy\ErrorLoad::validateLoadFile($maxFileSize);
> $file = \Uppy\Uploader::createFile($errorLoad);
Вот это странно смотрится. Попробуй понять логику:
файл = Загрузчик::создатьФайл(ошибка)
зачем передавать ошибку в функцию создания файла? Если ошибка то создавать наверно файл уже нет смысла.
> https://github.com/tokotun/uppy/blob/master/uppy/app/ErrorLoad.php#L9
> public static function validateLoadFile($maxFileSize)
Эту функцию я бы перенес в Uploader. Класс же называется Ошибка а не ПроверяльщикФайлов.
> public $error = true;
> public $errorSize = '';
> public $errorUpload = '';
Лучше наверно закрыть к ним доступ, у тебя все равно есть методы, а с закрытыми полями класс гораздо понятнее (не надо думать что мы кладем в эти поля) и надежнее. Ну и не забывай, если какое-то из полей обязательное то стоит передавать его через конструктор.
> https://github.com/tokotun/uppy/blob/master/uppy/app/ErrorLoad.php#L26
> if ($error == 0) {
Что за магические числа? Там константа есть, по моему PHP_UPLOAD_OK или как-то так, погугли
> public function errorUpload()
Эта функция вообще непонятно зачем нужна. Она публичная, значит можно вызывать ее снаружи. Но зачем? ЧТо она делает? Мне кажется, от нее надо избавиться.
Также, имена функций должны начинаться с глагола.
> if (getimagesize($app->config('uploadPath') . $fileName)){
Это лучше записать как if (Uploader::isImageFile(...))
Uploader кстати лучше было бы сделать нестатическим классом. У него же есть свойства, например папка для загрузки файлов.
> https://github.com/tokotun/uppy/blob/master/index.php#L104
> 'errorSize' => $errorLoad->errorSize,
Можно сразу объект передавать в шаблонизатор и не плодить сущности
> https://github.com/tokotun/uppy/blob/master/index.php#L129
> $mediaInfo = new \Uppy\MediaInfo( );
> $mediaInfo->info = $getID3->analyze($filePath);
Вот это плохо. У тебя info это массив сложной структуры и ты выставляешь его в общий доступ. Лучше сделать статический конструктор:
$mediaInfo = MediaInfo::createFromGetId3Result($id3Result)
Также, мне не нравится что ты при каждом обращении к странице файла вызваешь тяжелую библиотеку анализа файла. Лучше анализировать файл при загрузке и сохранять в БД информацию например в формате JSON. Для этого в MediaInfo можно предусмотреть методы сохранения в массив и восстановления из него.
> 'hostName' => $app->config('hostName')
Чтобы не копипастить, там можно как-то эту переменную передать один раз в начале index.php. Но как? По моему, $app->view->set(...) или как-то так. Попробуй посмотреть в документации и в исходниках слима.
настройки надо бы вынести в config.php
> https://github.com/tokotun/uppy/blob/master/index.php#L148
> $newComment->fileId = $fileMapper->getId($key);
а что если передан несуществующий key?
> https://github.com/tokotun/uppy/blob/master/uppy/app/CommentsMapper.php#L75
> //извлекает последнюю цифру из строки (из 2.1.13 извлекет 13)
> preg_match('/\d+$/u', $result['comment_path'], $n);
Эти тонкие моменты надо бы вынести в отдельные функции. Например, удобно сделать 2 функции: преобразовать путь в массив id и наоборот. C массивом работать гораздо удобнее. Это сильно упростит работу с путями которая пока выглядит как набор хитрых хаков. А также позволит при желании перейти на более эффективный алгоритм.
Пути надо добивать нулями для правильной сортировки. Неправильно:
1.1
1.10
1.2
правильно:
0001.0001
0001.0002
0001.0010
> https://github.com/tokotun/uppy/blob/master/uppy/app/CommentsMapper.php#L71
> $result = $statment->fetch(\PDO::FETCH_ASSOC);
Если тебе надо выбрать одно поле то есть fetchColumn
> SELECT `comment_path` FROM comments WHERE file_id = :file_id
> ORDER BY `comment_path` DESC LIMIT 1"
наверно можно написать SELECT MAX(comment_path) ... ? По моему это даже оптимальнее так как там будет «Select tables optimized away» при наличии индекса.
А, да, тебе надо добавить индексы на таблицу комментариев. Ты у нас сообразительный, так что вооружись мануалами и придумай хорошие индексы. Если сомневаешься, сделай EXPLAIN и напиши в тред, я подскажу. Ссылки на мануалы тут:
https://gist.github.com/codedokode/10539213#%D0%98%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D1%8B
(пост на highload.ru хороший для начинающего)
>>459028
Анон, я тут немного проверил твой код. Вот комменатрии.
> `comment_path` text NOT NULL,
это плохая идея, исплоьзовать для пути текст, так как его нельзя добавить в индексы и мы не сможем быстро выбирать отсортированные комментарии. Надо использовать varchar с разумным значением длины.
> `file_id` int(11) NOT NULL,
Не проставлены внешние ключи: http://denis.in.ua/foreign-keys-in-mysql.htm
> PRIMARY KEY (`id`),
> UNIQUE KEY `id` (`id`)
UNIQUE тут лишний так как PRIMARY KEY по определению уникален (первыичнй ключ это набор колонок отличающих запись от других).
> `size` int(11) NOT NULL,
int хранит числа от -2 млрд до +2 млрд. Значит, размер больше 2 Гб не запишется. Не уверен что такой файл вообще получится загрузить, но помнить о таких вещах стоит.
> `file_key` varchar(10) CHARACTER SET utf8 NOT NULL,
Наверно надо пометить как уникальное
https://github.com/tokotun/uppy/blob/master/index.php#L76
> $errorLoad = \Uppy\ErrorLoad::validateLoadFile($maxFileSize);
> $file = \Uppy\Uploader::createFile($errorLoad);
Вот это странно смотрится. Попробуй понять логику:
файл = Загрузчик::создатьФайл(ошибка)
зачем передавать ошибку в функцию создания файла? Если ошибка то создавать наверно файл уже нет смысла.
> https://github.com/tokotun/uppy/blob/master/uppy/app/ErrorLoad.php#L9
> public static function validateLoadFile($maxFileSize)
Эту функцию я бы перенес в Uploader. Класс же называется Ошибка а не ПроверяльщикФайлов.
> public $error = true;
> public $errorSize = '';
> public $errorUpload = '';
Лучше наверно закрыть к ним доступ, у тебя все равно есть методы, а с закрытыми полями класс гораздо понятнее (не надо думать что мы кладем в эти поля) и надежнее. Ну и не забывай, если какое-то из полей обязательное то стоит передавать его через конструктор.
> https://github.com/tokotun/uppy/blob/master/uppy/app/ErrorLoad.php#L26
> if ($error == 0) {
Что за магические числа? Там константа есть, по моему PHP_UPLOAD_OK или как-то так, погугли
> public function errorUpload()
Эта функция вообще непонятно зачем нужна. Она публичная, значит можно вызывать ее снаружи. Но зачем? ЧТо она делает? Мне кажется, от нее надо избавиться.
Также, имена функций должны начинаться с глагола.
> if (getimagesize($app->config('uploadPath') . $fileName)){
Это лучше записать как if (Uploader::isImageFile(...))
Uploader кстати лучше было бы сделать нестатическим классом. У него же есть свойства, например папка для загрузки файлов.
> https://github.com/tokotun/uppy/blob/master/index.php#L104
> 'errorSize' => $errorLoad->errorSize,
Можно сразу объект передавать в шаблонизатор и не плодить сущности
> https://github.com/tokotun/uppy/blob/master/index.php#L129
> $mediaInfo = new \Uppy\MediaInfo( );
> $mediaInfo->info = $getID3->analyze($filePath);
Вот это плохо. У тебя info это массив сложной структуры и ты выставляешь его в общий доступ. Лучше сделать статический конструктор:
$mediaInfo = MediaInfo::createFromGetId3Result($id3Result)
Также, мне не нравится что ты при каждом обращении к странице файла вызваешь тяжелую библиотеку анализа файла. Лучше анализировать файл при загрузке и сохранять в БД информацию например в формате JSON. Для этого в MediaInfo можно предусмотреть методы сохранения в массив и восстановления из него.
> 'hostName' => $app->config('hostName')
Чтобы не копипастить, там можно как-то эту переменную передать один раз в начале index.php. Но как? По моему, $app->view->set(...) или как-то так. Попробуй посмотреть в документации и в исходниках слима.
настройки надо бы вынести в config.php
> https://github.com/tokotun/uppy/blob/master/index.php#L148
> $newComment->fileId = $fileMapper->getId($key);
а что если передан несуществующий key?
> https://github.com/tokotun/uppy/blob/master/uppy/app/CommentsMapper.php#L75
> //извлекает последнюю цифру из строки (из 2.1.13 извлекет 13)
> preg_match('/\d+$/u', $result['comment_path'], $n);
Эти тонкие моменты надо бы вынести в отдельные функции. Например, удобно сделать 2 функции: преобразовать путь в массив id и наоборот. C массивом работать гораздо удобнее. Это сильно упростит работу с путями которая пока выглядит как набор хитрых хаков. А также позволит при желании перейти на более эффективный алгоритм.
Пути надо добивать нулями для правильной сортировки. Неправильно:
1.1
1.10
1.2
правильно:
0001.0001
0001.0002
0001.0010
> https://github.com/tokotun/uppy/blob/master/uppy/app/CommentsMapper.php#L71
> $result = $statment->fetch(\PDO::FETCH_ASSOC);
Если тебе надо выбрать одно поле то есть fetchColumn
> SELECT `comment_path` FROM comments WHERE file_id = :file_id
> ORDER BY `comment_path` DESC LIMIT 1"
наверно можно написать SELECT MAX(comment_path) ... ? По моему это даже оптимальнее так как там будет «Select tables optimized away» при наличии индекса.
А, да, тебе надо добавить индексы на таблицу комментариев. Ты у нас сообразительный, так что вооружись мануалами и придумай хорошие индексы. Если сомневаешься, сделай EXPLAIN и напиши в тред, я подскажу. Ссылки на мануалы тут:
https://gist.github.com/codedokode/10539213#%D0%98%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D1%8B
(пост на highload.ru хороший для начинающего)
>>459028
Также, робот жалуется:
В файле ../tokotun/uppy/templates/base.html.twig:
Слеш в конце одиночного тега (<link href="bootstrap/css/boot…ss"/>) используется только в XHTML и XML, в HTML он не ставится.
И еще ему не нравится что у тебя в файлах бутстрапа стоит 2012 год вместо 2013. Ты какую-то неофициальную сборку качал? Откуда она?
> - Copyright 2013 Twitter, Inc
> + Copyright 2012 Twitter, Inc
https://github.com/Si0n/register/blob/master/Header.php
Этот файл надо переделать и удалить. У тебя тут явно смесь php логики (реквайры) и html кода. HTML код надо вынести в шаблон, шаблон положить в папку templates
Далее, всю инициализацию надо собрать в один файл, например app/bootstrap.php
Сейчас у тебя реквайры раскиданы по куче файлов:
https://github.com/Si0n/register/blob/master/Header.php
https://github.com/Si0n/register/blob/master/config.php (в конфиге надо оставить только параметры, все остальное вынести)
https://github.com/Si0n/register/blob/master/files/loader.php
папку files переименовать или удалить. переименовать можно например в app или src. И объединить ее с class (название не очень удачное так как в ООП 99% файлов с классами).
Bootstrap надо бы переложить в папку с названием bootstrap (а в ней уже css/js и тд).
Тут смесь php кода и html https://github.com/Si0n/register/blob/master/class/pager.php
Надо вынести html в шаблон, шаблон в папку templates
То же самое с остальными файлами, весь HTML должен быть в папке templates, а не размазан по коду.
Тут https://github.com/Si0n/register/blob/master/class/View.php функцию надо бы переименовать более правильно, например html() или h() или как-то так.
Проверку правильности введенных данных (валидацию) надо сделать в отдельной функции или методе.
> window.setTimeout("document.location.href='register.php'", 4000);
для редиректа есть заголовок location, не надо делать такие странные вещи.
При ошибке надо не показывать надпись на 4 секунды (за которые ее невозможно прочесть), а надо выводить ту же самую форму с сообщениями об ошибке и заполненными полями.
Этот файл https://github.com/Si0n/register/blob/master/class/Student.php надо отформатировать, это можно сделать на сайте phpformatter
Если тебе что-то непонятно, обязательно пиши в тред. Наша цель научить тебя делать правильно.
Также, вопрос, а ты читал комментарии к этому заданию тут? https://github.com/codedokode/pasta/blob/master/student-list.md
https://github.com/Si0n/register/blob/master/Header.php
Этот файл надо переделать и удалить. У тебя тут явно смесь php логики (реквайры) и html кода. HTML код надо вынести в шаблон, шаблон положить в папку templates
Далее, всю инициализацию надо собрать в один файл, например app/bootstrap.php
Сейчас у тебя реквайры раскиданы по куче файлов:
https://github.com/Si0n/register/blob/master/Header.php
https://github.com/Si0n/register/blob/master/config.php (в конфиге надо оставить только параметры, все остальное вынести)
https://github.com/Si0n/register/blob/master/files/loader.php
папку files переименовать или удалить. переименовать можно например в app или src. И объединить ее с class (название не очень удачное так как в ООП 99% файлов с классами).
Bootstrap надо бы переложить в папку с названием bootstrap (а в ней уже css/js и тд).
Тут смесь php кода и html https://github.com/Si0n/register/blob/master/class/pager.php
Надо вынести html в шаблон, шаблон в папку templates
То же самое с остальными файлами, весь HTML должен быть в папке templates, а не размазан по коду.
Тут https://github.com/Si0n/register/blob/master/class/View.php функцию надо бы переименовать более правильно, например html() или h() или как-то так.
Проверку правильности введенных данных (валидацию) надо сделать в отдельной функции или методе.
> window.setTimeout("document.location.href='register.php'", 4000);
для редиректа есть заголовок location, не надо делать такие странные вещи.
При ошибке надо не показывать надпись на 4 секунды (за которые ее невозможно прочесть), а надо выводить ту же самую форму с сообщениями об ошибке и заполненными полями.
Этот файл https://github.com/Si0n/register/blob/master/class/Student.php надо отформатировать, это можно сделать на сайте phpformatter
Если тебе что-то непонятно, обязательно пиши в тред. Наша цель научить тебя делать правильно.
Также, вопрос, а ты читал комментарии к этому заданию тут? https://github.com/codedokode/pasta/blob/master/student-list.md
А, и еще вопрос. У тебя там с стоит session_start при этом сама сессия нигде не используется. Зачем тогда session_start?
Что бы показать что выдало.
Так все равно в цикле надо будет выводить html-код через echo. Или ты предлагаешь делать отдельный шаблон под цикл и вызывать в цикле уже его?
Без echo через htmlspecialcharcters и <php=
Не обязательно, будет что-то типа
<table>
<tr>
<?php
foreach ($array as $item) {
?>
<td><?=$item; ></td>
<?php
}
?>
</tr>
</table>
Или сокращенный вариант с двоеточием.
То есть все, что в теле цикла, будет выводиться в этом самом цикле даже без echo? Ебать я тупой. Мучался тут, кавычки экранировал.
Там ответ около 61280 должен быть. Также, у тебя анон уходит, не доплатив банку 262 рубля.
Попробуй переписать код внутри цикла примерно так:
- прибавляем проценты и комиссию к остатку долга
- если остаток маленький, выплачиваем сколько осталось и уходим
- иначе платим 5000
«Платим» здесь значит уменьшаем долг и увеличиваем общую сумму выплаченного.
>>460868
Передаешь в шаблон массив (желательно массив объектов-студентов).
>>460920
> Или сокращенный вариант с двоеточием.
именно это
>>460921
О, это хороший пример.
Те примеры где смешивают выборку из БД и HTML это лапша где все в кучу смешано, не делай так.
Ну да, внутрь циклов, ифов, свичей можно вставлять обычный хтмл, а в этот хтмл - пхп, а туда опять хтмл правда вот этот триппер <?php } ?> или <?php endif; ?> немного глаза режет, а так норм.
>Также, вопрос, а ты читал комментарии к этому заданию тут?
Да читал, но уже в процессе выполнения.
>Надо вынести html в шаблон, шаблон в папку templates
Я не совсем понимаю что будет находиться в шаблоне и как в него перенести данные из обработчика, та статья про шаблоны где сперва показаны неправильные способы, а в конце правильный, там ничего нет о том, как в этот шаблон перенести данные, плюс я не пойму чем отличаются мои файлы от последнего примера в той же статье. Есть ли примеры или другая статья?
Я сперва хотел через сессию передавать форму поиска, потом под гет переделал, а сессию не удалил
Должно быть так:
// файл с логикой
<?php
$x = 1;
$y = 2;
require 'templates/index.phtml';
// файл шаблона
<p>x=<?= html($x) ?></p>
<p>y=<?= html($y) ?></p>
То есть ты можешь например поменять внешний вид страницы, не трогая логику, и наоборот. А у тебя пока все свалено в кучу, в один файл.
> там ничего нет о том, как в этот шаблон перенести данные,
ты просто создаешь переменную и когда ты подключаешь шаблон через require она в нем будет видна.
> плюс я не пойму чем отличаются мои файлы от последнего примера в той же статье
Тем что у тебя все свалено в кучу. Вместо того чтобы аккуратно сложить верстку в отдельную папку ты размазал ее по нескольким файлам и смешал с логикой.
Вот посмотри сам:
https://github.com/Si0n/register/blob/master/Header.php
Тут в верстку примешана например логика проверки авторизации:
> $_COOKIE[
> $db = new StudentsMapper($pdo);
> if ($db->isPswrdInDB($password))
так не должно быть. У тебя проверяет авторизацию файл обработчик а шаблон только выводит переданные ему переменные. И не лезет ни в базу ни в куки ни куда-то еще.
Более того, ты пока не умеешь разделять код на функции и надо этому учиться. Например, проверка залогинен ли пользователь это отдельное действие и ее однозначно надо вынести в функцию:
$isLoggedIn = isUsedLoggedIn( );
Но у тебя пока этого не сделано. Ты просто взял этот код и смешал его с другим кодом в Header.
Или давай посмотрим на этот файл:
https://github.com/Si0n/register/blob/master/action.php
тут мы видим:
- создание соединения с БД и StudentMapper
- проверка данных введенных в форму
- экранирование HTML символов, сделанное не в том месте ( makeProtect(strval($_POST['name']))), мне это напоминает старые неправильные учебники где в начале скрипта навалена куча бессмысленных фунций вроде strip_tags(addslashes(mysql_real_escape_string))
- вывод уведомлений с помощью HTML кода: <div class="alert alert-success" role="alert">Регистрация/изменения данных прошла успешно</div>
Все это надо разнести по функциями и файлам, а не сваливать вместе. Ну посмотри сам. Допустим у нас появится задача: пройтись по базе и проверить нет ли в ней неправильных записей. Для этого надо каждую запись достать из базы, проверить функцией валидации и вывести ошибки. Но у тебя это сделать нельзя так как код проверки у тебя вшит намертво в файл action.php. Ты не можешь просто так его вызвать.
Кстати, давай это сделаем тебе дополнительным заданием: напиши отдельный php-скрипт, который запускается из командной строки (гайд по ком. строке https://gist.github.com/codedokode/10539568 ) и проверяет всех студентов в базе на правильность, если есть ошибки, то выводит. Думаю, это поможет тебе понять как надо разбивать код на функции.
> Есть ли примеры или другая статья?
Посмотри на код в начале этого поста. Должно быть примерно также как и там.
Должно быть так:
// файл с логикой
<?php
$x = 1;
$y = 2;
require 'templates/index.phtml';
// файл шаблона
<p>x=<?= html($x) ?></p>
<p>y=<?= html($y) ?></p>
То есть ты можешь например поменять внешний вид страницы, не трогая логику, и наоборот. А у тебя пока все свалено в кучу, в один файл.
> там ничего нет о том, как в этот шаблон перенести данные,
ты просто создаешь переменную и когда ты подключаешь шаблон через require она в нем будет видна.
> плюс я не пойму чем отличаются мои файлы от последнего примера в той же статье
Тем что у тебя все свалено в кучу. Вместо того чтобы аккуратно сложить верстку в отдельную папку ты размазал ее по нескольким файлам и смешал с логикой.
Вот посмотри сам:
https://github.com/Si0n/register/blob/master/Header.php
Тут в верстку примешана например логика проверки авторизации:
> $_COOKIE[
> $db = new StudentsMapper($pdo);
> if ($db->isPswrdInDB($password))
так не должно быть. У тебя проверяет авторизацию файл обработчик а шаблон только выводит переданные ему переменные. И не лезет ни в базу ни в куки ни куда-то еще.
Более того, ты пока не умеешь разделять код на функции и надо этому учиться. Например, проверка залогинен ли пользователь это отдельное действие и ее однозначно надо вынести в функцию:
$isLoggedIn = isUsedLoggedIn( );
Но у тебя пока этого не сделано. Ты просто взял этот код и смешал его с другим кодом в Header.
Или давай посмотрим на этот файл:
https://github.com/Si0n/register/blob/master/action.php
тут мы видим:
- создание соединения с БД и StudentMapper
- проверка данных введенных в форму
- экранирование HTML символов, сделанное не в том месте ( makeProtect(strval($_POST['name']))), мне это напоминает старые неправильные учебники где в начале скрипта навалена куча бессмысленных фунций вроде strip_tags(addslashes(mysql_real_escape_string))
- вывод уведомлений с помощью HTML кода: <div class="alert alert-success" role="alert">Регистрация/изменения данных прошла успешно</div>
Все это надо разнести по функциями и файлам, а не сваливать вместе. Ну посмотри сам. Допустим у нас появится задача: пройтись по базе и проверить нет ли в ней неправильных записей. Для этого надо каждую запись достать из базы, проверить функцией валидации и вывести ошибки. Но у тебя это сделать нельзя так как код проверки у тебя вшит намертво в файл action.php. Ты не можешь просто так его вызвать.
Кстати, давай это сделаем тебе дополнительным заданием: напиши отдельный php-скрипт, который запускается из командной строки (гайд по ком. строке https://gist.github.com/codedokode/10539568 ) и проверяет всех студентов в базе на правильность, если есть ошибки, то выводит. Думаю, это поможет тебе понять как надо разбивать код на функции.
> Есть ли примеры или другая статья?
Посмотри на код в начале этого поста. Должно быть примерно также как и там.
Спасибо, буду переделывать.
Когда ты делаешь реквайр считай что ты склеваешь два кода.
А вот в какой нибудь рендер, уже нужно будет передавать переменные
вот у меня массив :
\t$records = array(
\t
\tarray(
\t\t'header' => 'Blog Entry',
\t\t'content' => 'Test'
\t));
в соседнем файле
<?php foreach($records as $row):
\techo $row ['header'];
\tendforeach;
?>
все работает. Но стоит мне сделать что-то вроде
<h3><?=$row['header']?></h3>
Страница перестает отображаться, без вывода ошибки.
Как мне правильно выводить куски php кода в заголовки , списки и т.д. Я правильно делаю что использую альтернативный синтаксис?
Как понять страница перестает отображаться?
У тебя массив-то как называется - records, в случае с циклом ты по синтаксису указываешь переменную для каждого члена этого массива и потому можешь к ней обращаться, если же ты цикл не вызываешь то обращаться надо не к row которое у тебя не объявлено даже, а к records. Типа так
<h3><?=$records[0]['header']?></h3>
То есть берешь первый член, а из него хедер.
А во нашел, там у меня автозаполнение форм при ошибочном введении данных через сессию, я храню введенную инфу в массиве $_SESSION['student'] и оттуда достаю уже данные для заполнения форм при повторной попытке регистрации.
>Обрывок массива это такой же массив. Сохраняй конечно.
А дальше что? вот я могу "отфильтровать" массив всех работников депортамента, получу кусочек этого массива. Далее я в этот кусочек вношу изменения. А как мне назад этот кусочек вклеить в изначальный большой массив который лежит внутри депортамента? Я в ступоре на этом моменте. Сори, я не садился за задачу полтора дня, и у меня нет пока прогресса в ней, не смотря на твои комментарии. Я из тех людей, которых надо везде водить за ручку, и долго сам допираю. Алсо начал сейчас смотреть курс "специалист" что бы восстановить пробелы и продвинуться в php, ведь теперь у тебя теоретическая часть закончилась в учебника, и теперь нужно искать инфу самому по большей части, что бы дальше решать задачи.
А еще, антоны. Может есть кого самописный форум простенький? Не на фреймворках. Но на ООП например написаный, хотелось бы посмотреть чужой код для лучшего понимания как такие вещи писать. Мне просто предстоит написать для тестового задания форум с регистрацией, авторизацией, комментированием и прочими прелестями в одну контору. Не могу пока понять как делать такие вещи. Писал до этого лапшу всякую с кучей разных файлов и общим файлом с функциями - functions.php, в которых были всякие функции установки и проверки кукисов и прочие коннекты к базе, но понимаю что это фейл, если дальше дописывать, то будет еще больше лапши.
А еще я не понимаю, как должно быть реализовано все, когда все точки сходятся у тебя на index.php, и пользователь как бы сидит только на этой страничке, а не на веренице страниц для каждого случая. Кароче как уйти от многостраничного html- мышления?
Есть такое:
<div class="panel panel-default">
<a href="#spoiler-1" data-toggle="collapse"><div class="panel-heading">
\t<h4 class="panel-title">Панель поиска</h4>
</div></a>
<div class="panel collapse<?if ($isSearch) {echo " in";}?>" id="spoiler-1">
<div class="well">
Тут спойлер открыт, если в форме поиска что-то было забито. Но так неудобно же, хочется, чтобы страничка запоминала состояние спойлера, а не обязательно открывала его при непустом поисковом запросе.
>Должно быть так:
А у меня вот при пустом поисковом запросе сделано
die("Поиск не дал результатов!");
При использовании шаблона не получится вывести футер, например. Как обойти? В пхп же нет GOTO, лол.
> Далее я в этот кусочек вношу изменения. А как мне назад этот кусочек вклеить в изначальный большой массив который лежит внутри депортамента?
Объекты копируются как будто по ссылке. Те объекты что лежат в твоем кусочке это те же самые работники что и в департаменте. И если ты меняешь их свойства то они меняются и в департаменте потому что это просто 2 ссылки на один и тот же объект. Не надо ничего вклеивать обратно.
Вот тебе пример для понимания:
$a = new Manager(1, false);
$b = $a;
$b->setRank(2);
var_dump($b->getRank( )); // 2
var_dump($a->getRank( )); // что выведется?
Вот тебе мануал: http://php.net/manual/ru/language.oop5.references.php (кстати если ты не прочел все остальные разделы в мануале про ООП, самое время это сделать).
Чтобы явно создать новый объект надо использовать new либо clone, иначе этот будет тот же самый объект. В примере выше new выполняется только один раз потому у нас только один объект.
Это одна из особенностей ООП, так же объекты передаются и в других языках (в php4 было не так и это было большой ошибкой и в нем ООП был очень неудобный в использовании).
> я не садился за задачу полтора дня, и у меня нет пока прогресса в ней,
Это не проблема, у нас никто никого не торопит и все учатся в таком темпе который их устраивает.
> Я из тех людей, которых надо везде водить за ручку,
Ну я не против, задавай вопросы, я буду отвечать.
> и теперь нужно искать инфу самому по большей части, что бы дальше решать задачи.
Это верно, но я советую параллельно прочесть мануал по ООП, там может объясняется неидеально, по крайней мере примеров много. Ну и книжка Зандстры содержит немало страниц про ООП.
> Может есть кого самописный форум простенький? Не на фреймворках. Но на ООП например написаный, хотелось бы посмотреть чужой код для лучшего понимания как такие вещи писать.
Это плохая идея, писать форум с нуля а не на фреймворке так как ты тратишь время на переизобретение того что уже есть. Не знаю, как насчет простых, но открытые движки форумов в сети есть, в том числе самописные. Только я бы не советовал по ним учиться, так как они скорее представляют примеры как делать не надо. Но если у тебя нет времени то может быть это хороший вариант.
> А еще я не понимаю, как должно быть реализовано все, когда все точки сходятся у тебя на index.php, и пользователь как бы сидит только на этой страничке, а не на веренице страниц для каждого случая. Кароче как уйти от многостраничного html- мышления?
Это просто настройка веб-сервера. По умолчанию веб-сервер запускает тот файл который прописан в URL, например URL http://example.com/page/news.php соответствует файлу page/news.php
Но это лишь настройка по умолчанию. ты можешь перенастроить сервер по-другому, например чтобы при обращении по любому адресу начинающемуся с /page/ вызвыался скрипт page.php. Или чтобы при обращении по любому адресу вызывался index.php. Причем пользователь этого не увидит, он увидит только URL в своем браузере в котором будет написано что-то вроде /news/10 или /id123456
Такой подход дает тебе большую гибкость так как теперь ты можешь произвольно задавать URL для страниц. Вот у меня черновик урока про URL: https://gist.github.com/codedokode/772a4ccc03e41d6b7cba
На стороне сервера красивые URL реализуются так: перенаправляем все обращения на index.php например с помощью mod_rewrite и htaccess, а затем в PHP-скрипте анализируем REQUEST_URI и взываем нужную функию. Это можно делать как руками, на if и preg_match, так и какой-нибудь библиотекой-роутером, например Symfony Routing. Также, многие фреймворки уже содержат в себе роутер.
Если ты будешь делать наши задания на файлообменник, ты познакомишься с фреймворком Slim в котором есть роутер, и научишься им пользоваться.
> Далее я в этот кусочек вношу изменения. А как мне назад этот кусочек вклеить в изначальный большой массив который лежит внутри депортамента?
Объекты копируются как будто по ссылке. Те объекты что лежат в твоем кусочке это те же самые работники что и в департаменте. И если ты меняешь их свойства то они меняются и в департаменте потому что это просто 2 ссылки на один и тот же объект. Не надо ничего вклеивать обратно.
Вот тебе пример для понимания:
$a = new Manager(1, false);
$b = $a;
$b->setRank(2);
var_dump($b->getRank( )); // 2
var_dump($a->getRank( )); // что выведется?
Вот тебе мануал: http://php.net/manual/ru/language.oop5.references.php (кстати если ты не прочел все остальные разделы в мануале про ООП, самое время это сделать).
Чтобы явно создать новый объект надо использовать new либо clone, иначе этот будет тот же самый объект. В примере выше new выполняется только один раз потому у нас только один объект.
Это одна из особенностей ООП, так же объекты передаются и в других языках (в php4 было не так и это было большой ошибкой и в нем ООП был очень неудобный в использовании).
> я не садился за задачу полтора дня, и у меня нет пока прогресса в ней,
Это не проблема, у нас никто никого не торопит и все учатся в таком темпе который их устраивает.
> Я из тех людей, которых надо везде водить за ручку,
Ну я не против, задавай вопросы, я буду отвечать.
> и теперь нужно искать инфу самому по большей части, что бы дальше решать задачи.
Это верно, но я советую параллельно прочесть мануал по ООП, там может объясняется неидеально, по крайней мере примеров много. Ну и книжка Зандстры содержит немало страниц про ООП.
> Может есть кого самописный форум простенький? Не на фреймворках. Но на ООП например написаный, хотелось бы посмотреть чужой код для лучшего понимания как такие вещи писать.
Это плохая идея, писать форум с нуля а не на фреймворке так как ты тратишь время на переизобретение того что уже есть. Не знаю, как насчет простых, но открытые движки форумов в сети есть, в том числе самописные. Только я бы не советовал по ним учиться, так как они скорее представляют примеры как делать не надо. Но если у тебя нет времени то может быть это хороший вариант.
> А еще я не понимаю, как должно быть реализовано все, когда все точки сходятся у тебя на index.php, и пользователь как бы сидит только на этой страничке, а не на веренице страниц для каждого случая. Кароче как уйти от многостраничного html- мышления?
Это просто настройка веб-сервера. По умолчанию веб-сервер запускает тот файл который прописан в URL, например URL http://example.com/page/news.php соответствует файлу page/news.php
Но это лишь настройка по умолчанию. ты можешь перенастроить сервер по-другому, например чтобы при обращении по любому адресу начинающемуся с /page/ вызвыался скрипт page.php. Или чтобы при обращении по любому адресу вызывался index.php. Причем пользователь этого не увидит, он увидит только URL в своем браузере в котором будет написано что-то вроде /news/10 или /id123456
Такой подход дает тебе большую гибкость так как теперь ты можешь произвольно задавать URL для страниц. Вот у меня черновик урока про URL: https://gist.github.com/codedokode/772a4ccc03e41d6b7cba
На стороне сервера красивые URL реализуются так: перенаправляем все обращения на index.php например с помощью mod_rewrite и htaccess, а затем в PHP-скрипте анализируем REQUEST_URI и взываем нужную функию. Это можно делать как руками, на if и preg_match, так и какой-нибудь библиотекой-роутером, например Symfony Routing. Также, многие фреймворки уже содержат в себе роутер.
Если ты будешь делать наши задания на файлообменник, ты познакомишься с фреймворком Slim в котором есть роутер, и научишься им пользоваться.
> Страница перестает отображаться, без вывода ошибки.
У тебя наверно отключен вывод ошибок?
В PHP по умолчанию выключено отображение ошибок в браузере, так как обычному пользователю сайта эта информация ни к чему. Но тебе, как программисту, надо видеть эти ошибки. Вот, как можно их просмотреть:
- ошибки сохраняются в лог ошибок. Можно открыть его и почитать. Если ты запускаешь код на локалхосте, у себя, то лог хранится в папке Апача (обычно она называется logs) и имеет название вроде error.log (в линуксе в папку /var/log/apache2 ). Если на хостинге — там либо есть файл error.log либо раздел в панели управления, где лог можно посмотреть
- также, ты можешь включить отображение ошибок. Открой файл php.ini, поставь там display_errors = On и error_reporting = E_ALL и перезапусти сервер. Теперь ошибки должны выводиться на экран.
Проверить, работает ли вывод ошибок, можно запустив скрипт содержающий обращение к несуществующей переменной вроде echo $sdgasdad; и проверив, выведется ошибка или нет. Если все верно, то должна вывестись.
>>461034
Вообще не только в форич, но и после него эта переменная остается.
>>461039
Сессии использовать для этого плохо, так как сессия общая для всех вкладок. Представь что у тебя более сложный сайт и пользователь открыл несколько форм в разных вкладках.Данные из них перепутаются.
У меня есть урок про работу с формами: https://github.com/codedokode/pasta/blob/master/forms.md
В задаче про студентов лучше всего сделать так, как описано в этом уроке.
> как можно сохранить состояние спойлера (открыт или закрыт) в бутсрапе при смене странички?
яваскриптом в куки или локалсторадж. Куки имеют преимущество что они доступны на сервере.
> Желательно, чтобы можно было передавать это через GET.
Тогда надо дополнительно яваскриптом при загрузке страницы проверять что в GET. Но мне кажется, что это можно делать и на стороне PHP, проверяя GET и доабвляя какой-нибудь класс к верстке.
> Но так неудобно же, хочется, чтобы страничка запоминала состояние спойлера, а не обязательно открывала его при непустом поисковом запросе.
Может вообще тогда без спойлера обойтись?
>>461076
Это абсолютно неправильный код. Во-первых, это некрасиво, надпись на белом пустом экране. Во-вторых, пользователь должен тратить время нажимая кнопку назад, разве не логичнее вывести сразу страницу с формой поиска?
> При использовании шаблона не получится вывести футер, например. Как обойти?
Не надо ставить die. Если ты хочешь показать сообщение ты просто ставишь какую-нибудь переменную например $nothingFound = true а в шаблоне проверяешь чему она равна и если true то выводишь надпись.
В задаче про студентов die можно использовать только в одном случае: после редиректа.
Официальный мануал на английском не хочешь?
Есть туториал по мощному фреймворку Symfony 2 и MVC. Проходя туториал, ты сможешь сделать сайт на этом фреймворке.
этот http://symfony.in.ua/symfony2-jobeet-tutorial.html туториал действительно годный. Я советую всем, кто прошел мой учебник и сделал хотя бы задачу про файлообменник.
Но учти, что для изучения Symfony 2 надо кроме туториала:
- знать ООП на среднем уровне
- знать базы данных на среднем уровне
- знать HTML/CSS/JS на начальном уровне
- иметь представление о шаблонизаторе twig или быть готовым прочесть мануал по нему
- иметь представление о том что такое ORM и как он работает (ORM — это штука, которая позволяет сохранять в базу данные из объектов и загружать данные из базы прямо в объекты без написания sql-запросов, очень удобно)
- быть знакомым с Doctrine либо быть готовым прочесть мануал по ней
- быть готовым постоянно лезть в документацию Symfony и гугл
>Не надо ставить die. Если ты хочешь показать сообщение ты просто ставишь какую-нибудь переменную например $nothingFound = true а в шаблоне проверяешь чему она равна и если true то выводишь надпись.
А как сделать так, чтобы остальной код не выполнялся при этом условии? Ну, например мне не надо, чтобы выводилась таблица с результатами поиска, если ничего не нашлось. Городить кучу ifов?
>Объекты копируются как будто по ссылке. Те объекты что лежат в твоем кусочке это те же самые работники что и в департаменте. И если ты меняешь их свойства то они меняются и в департаменте потому что это просто 2 ссылки на один и тот же объект. Не надо ничего вклеивать обратно.
Вот, спасибо. Вот таких мелочей мне и не хватало для осознания. По сути прорыв сейчас произошел в понимании что делать дальше мне, вот от этих строк. У меня никуда не денутся сотруники из департамента ведь! я просто соберу массив ссылок на них, потом урежу массив до тех кто мне нужен, внесу изменения в сотрудников которые останутся, и вуаля, в депортаменте произойдут изменения.
А вот дальнейший поток ссылок и терминов это слишком много инфы для меня сейчас!
Обязательно разбирусь со всем, но позже. Мне либо нужна тут лекция с минипримерами и задачами, либо я буду сам медленно и долго через такие вот вещи открывать для себя все это.
Ну и задачи все собираюсь сделать со временем.
Просто меня ,внезапно, позвали на собеседование в котнтору где он используется, сам я только начал yii2 дрочить
https://php.net/manual/ru/control-structures.alternative-syntax.php
>>461148
> чтобы остальной код не выполнялся при этом условии?
if
> Городить кучу ifов?
Почему куча ифов? Одна таблица — один иф.
>>461156
Тогда тебе будет тяжело.
>>461151
Ок, я советую тогда доделать вектор и переходить к задаче про студентов, если ты ее не делал. Она правда еще сложнее чем вектор :)
Чет не работает у меня:
<?
while ($row = mysql_fetch_array($rezs)) {
?>
<TR>
<TD align = center><?=$row['TimeCreate']?></TD>\t
</TR>
<? } ?>
В итоге таблица пустая (одна строка с заголовками, которую вывожу без помощи пхп).
Короче, сам дурак. Там выше еще один темплейт вызывается, в котором я те же переменные использую, поэтому массив и пустой.
Да, ну ты смари, дотошные товарищи как ОП скажут что я тебя плохому научил, пиши лучше так
<?php
while ($row = mysql_fetch_array($rezs)) :
?>
<tr>
<td class='centered'><?=$row['timeCreate']; ?></td>\t
</tr>
<?php endwhile; ?>
Лучше вообще не пиши работу с БД в шаблоне, а также не используй устаревшие функции mysql
дотошный товарищ
Если их у тебя еще больше, и нужна максимальная скорость, то можно подумать над каким-нибудь хралищием типа редиса, но ему понадобятся гигабайты оперативки, у тебя они есть? Для миллиона записей и mySQL хватит.
Про устаревшие я в курсе, но как не писать работу с БД в шаблоне в данном случае, не подскажешь?
Перенести получение данных из БД из шаблона в другой файл и передавать в шаблон уже выбранные из базы данные.
>>461304
> Без индексов mysql помучался и умер. С индексами каждый запрос 0.4 секунды. Может я его неправильно готовлю?
да. В чем выгода не использовать индексы? В этом случае у тебя каждый запрос делает полный обход всей таблицы.
Также, не исопльзуй ORDER BY RAND. Это самый медленный способ сортировки.
Также не используй подзапросы, они неэффективны. используй джойны.
Вообще, я вижу у тебя очень слабые знания MySQL, тебе надо больше читать теории.
Вот тут есть ссылки, в том числе про индексы: https://gist.github.com/codedokode/10539213
>Перенести получение данных из БД из шаблона в другой файл и передавать в шаблон уже выбранные из базы данные.
Там в цикле создание таблицы. Покажи на примере, что ты имеешь в виду.
Алсо, есть ли способ (готовый, без изобретения велосипеда) создания ячейки таблицы в виде ссылки для бутстрапа?
Спасибо, теорию почитаю. А можно как нибудь еще соптимизировать? Ведь 0.4 секунды это очень много.
> не исопльзуй ORDER BY RAND
> не используй подзапросы
> использовать индексы
>>461319
> Покажи на примере, что ты имеешь в виду.
лень писать код, просто берешь все данные из Бд и кладешь в массив.
> создания ячейки таблицы в виде ссылки для бутстрапа?
Ячейка таблицы не может быть ссылкой, но ссылку можно поместить внутрь нее. Ссылка создается тегом <a>
Этот тред закрыт. Если я кого-то пропустил, напомните пожалуйста о себе в новом треде.
>Ну то есть логичнее сказать животному: «двигайся», а не вводить лишнего посредника, через которого мы передаем команды.
>Оно может только бегать по миру, оно не может ничего изменить в нем.
Ты прав. Я только сейчас понял, что животные двигаются сами по себе, а мир лишь является средой.
> $this->overviewWorld($world);
>Вот это наиболее непонятная строчка. зачем ты в животном сохраняешь какой-то массив непонятного вида, который соответствует тому как выглядела карта на 0 ходу. Зачем он? Что ты с ним собрался делать?
>В этом случае ты мог бы сделать объект WorldView, который представляет себе картину мира как его видит животное:
Я хотел чтобы эта функция занималась этим. А потом уже Животное само искало вокруг все сущности, т.е у Животного будет своей метод найтиСущность(... $сущность);
>Ой-ой, ты опять начинаешь придумывать какие-то нестандартные идеи. Иногда наверно это хорошо, но не в этом случае.
Давай я сделаю эту задачу в двух вариантах: по-своему и как делают её обычно. Хотя, я не думаю что они будут сильно различаться. Лишь только тем, что в моем способе Животное будет ориентироваться от своей относительной карты и все.
> Давай я сделаю эту задачу в двух вариантах: по-своему и как делают её обычно
Сделай тогда в 1 варианте, по-своему, и посмотрим.
вот массив 1 пик, 2 это как сейчас , всё работает. 3 как я пытаюсь сделать , то есть выводимое в скрипте сразу загонять в какие то тэги html . при этом я это не сам придумал , взял кусок с одного видеоурока , там выдается как положено , у меня скрипт ничего не выдает.
>>461133
я его имел в виду , я мониторю файл логов , периодически ребутая апач. обычные ошибки синтаксиса отображаются, а здесь нет.
А что выводится если открыть исходный код в браузере (Ctrl + U)?
> 3 как я пытаюсь сделать , то есть выводимое в скрипте сразу загонять в какие то тэги html . при этом я это не сам придумал , взял кусок с одного видеоурока , там выдается как положено , у меня скрипт ничего не выдает.
А ты этот скрипт через require подключаешь?
> взял кусок с одного видеоурока
В видеоуроках плохо объясняется теория. Читай параллельно мануал, например: http://php.net/manual/ru/language.basic-syntax.phpmode.php
Через require , да .
ну вот здесь пишут <?=?> это сокращение от echo , я так и хочу, да. вроде всё правильно, а стоит перейти на альтернативный синтаксис с изолированием от html и перестает работать
У тебя в PHP не включены короткие теги в php.ini потому он не выполняет код в них. Алсо сам php очень древний так как с 5.4 они (короткие теги) не отключаются. Советую обновиться.
$value - не элемент массива. $value - это значение, которое хранится в этой ячейке.
http://ideone.com/P6k3lp
Желаешь изменить данный элемент массива, тогда к нему и обращайся. По соответствующим координатам.
http://ideone.com/FrLNpe
Ты ведь это хотел получить?
Это копия, сохраненная 29 апреля 2015 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.