Это копия, сохраненная 8 ноября 2016 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
Это не чат! Высказывайтесь одним большим постом, а не цепочкой мелких
Это тред для начинающих. Не написал за свою жизнь ни одной программы и имеешь тройку по математике? Ты наш человек.
Устанавливать пока что ничего не требуется, разве что редактор кода вроде Sublime Text 3, Notepad++, Netbeans PHP или PhpStorm (с ним будет удобнее).
Предыдущий тред был тут: >>825576 (OP)
Двач лежит? Есть запасной тред: http://dobrochan.org/s/res/23225.xhtml#i46467
Что самое главное для программиста? Умение аккуратно оформлять код (читай второй пост, прежде чем писать код).
Правила: ведем себя воспитанно, помогаем новичкам, постим ссылки на решения задачек, ОП их проверяет и дает советы и замечания. ОП заходит редко, где-то раз в 2-3 дня, у него мало времени, не жди его, решай задачки дальше. ОП отвечает на все вопросы по его задачкам и учебнику, а вот насчет каких-то других вещей - только если останется время. Но в треде немало анонимных экспертов разного уровня, так что вряд ли вопрос останется без ответа.
У нас есть уроки по основам PHP, они собраны и выложены по адресу http://archive-ipq-co.narod.ru/ Это учебник для изучающих с нуля, то есть если ты вообще ничего не знаешь, то надо начать с него. Он простой и понятный (по крайней мере в начале). Там есть задачи, их надо решать обязательно (чтобы стать программистом, надо писать код — иначе никак). Пости ссылки на решения в тред, мы их проверим, напишем замечания и дадим советы по улучшению.
Если не знаешь как решать, запости код, напиши в каком месте остановился и попроси подсказку.
Ты прошел весь учебник? Молодец, но это были лишь основы языка PHP, этого недостаточно. Вот что в идеале надо изучить еще: ООП, как работает веб-сервер, HTML/CSS, SQL, PDO, работа с таблицами в БД, работа с формами, MVC, git, composer, JS, фреймворки, автоматизированное тестирование.
Надо переходить к более серьезным задачкам, которые научат тебя всему этому.
- для начала прочти урок https://github.com/codedokode/pasta/blob/master/soft/web-server.md
- установи Апач + PHP (советы выше и ниже) и читай туториал http://php.net/manual/ru/tutorial.php
- Учи HTML/CSS и SQL, PDO, хотя бы основы
- Далее простая, но полезная задача сделать список студентов, в ней много полезных советов: https://github.com/codedokode/pasta/blob/master/student-list.md
- Более сложная задача сделать файлообменник на микрофреймворке Slim: https://gist.github.com/codedokode/9424217
- Еще более сложная и долгая задача на Yii/Symfony: https://gist.github.com/codedokode/8733007
- После нее можно изучать автоматизированное тестирование https://gist.github.com/codedokode/a455bde7d0748c0a351a
- Если ты все решил, переходи к Symfony 2/Doctrine 2
- Почитать про паттерны http://designpatternsphp.readthedocs.org/ru/latest/README.html (если ты не изучил ни одного фреймворка, то это будет рановато), тут с примерами кода http://designpatternsphp.readthedocs.org/ru/latest/README.html . Имей в виду что без примеров использования их учить бесполезно - не поймешь, хочешь увидеть примеры использования паттернов - ковыряй исходники Симфони, например Symfony Forms. Не заучивай паттерны - смотри код и думай, зачем тут они использованы.
Чтобы делать эти задания, тебе надо установить Апач + PHP (можно заодно сразу и MySQL) на компьютер. Вот полезные инструкции:
https://github.com/codedokode/pasta/blob/master/soft/php-install.md
https://github.com/codedokode/pasta/blob/master/soft/apache-install.md
Может тебе понадобится пользоваться командной строкой, вот гайд https://github.com/codedokode/pasta/blob/master/soft/cli.md
Решения задач лучше показать мне, особенно на ООП,так как сам ты вряд ли увидишь все ошибки. Пости свой код на гитхаб и вкидывай ссылку в тред по мере решения. Я прокомментирую и укажу на ошибки.
Также, у нас есть задачи которые позволят тебе изучить или подтянуть до нормального уровня знания JS/HTML/CSS/SQL. Решай их параллельно с задачами выше.
- HTML/CSS: https://github.com/codedokode/pasta/blob/master/html/html.md
- JS: https://gist.github.com/codedokode/ce30e7a036f18f416ae0
- SPA (сложно): https://github.com/codedokode/pasta/blob/master/js/spa.md
- Проверялка решений на JS: http://dkab.github.io/jasmine-tests/
- MySQL: https://github.com/codedokode/pasta/blob/master/db/databases.md
Что почитать
- Мануал по PHP — http://www.php.net/manual/ru/langref.php
- Сайт phptherightway (перевод на русский: http://getjump.me/ru-php-the-right-way/ )
- По PHP: Профессиональное программирование на PHP Джордж Шлосснейгл
- По PHP: Мэтт Зандстра — PHP: Объекты, шаблоны, методики программирования
- JS: learn.javascript.ru
- Про Git: https://git-scm.com/book/ru/v1
Оформляй код аккуратно!!! — например пропусти через phpformatter.com . Также, если ты пользуешься IDE вроде PhpStorm, Netbeans, Eclipse, то в них эта опция встроена, подробнее: https://gist.github.com/codedokode/8759492
Платиновые вопросы
- Почему PHP? Потому что фейсбук и википедия на нем написаны, и вакансий море, и учить легко.
- Сайт опять упал!!!!! — Не паникуй, а открой http://rghost.ru/6bfCY9lfl и получи личную немного устаревшую оффлайновую копию сайта (можно читать хоть на андроиде без интернета)
- Что надо знать чтобы найти работу - разработчику: PHP, SQL, HTML/CSS, JS, ООП, Git, композер, MVC, фреймворк. Верстальщику - HTML/CSS, JS, jQuery
- Сколько времени надо изучать все это? - все зависит от тебя, но не меньше 6-8 месяцев
- Посоветуйте редактор кода - Sublime Text 3, Notepad++, PhpStorm
- Нужен ли ООП, фреймворки, MVC, git, composer? — Да, однозначно. Посмотри любую вакансию.
- Что самое главное для программиста? Умение аккуратно оформлять код.
- ОП, сделай за меня мою работу или домашнее задание? — Это конечно, хорошая идея, но нет.
- Подскажи сайты для поиска работы, я не умею гуглить? — hh.ru, geekjob.ru, moikrug.ru (склеен с brainstorage.me), fl.ru, upwork.com (бывший одеск). Имей в виду, что кроме фриланса есть еще постоянная удаленная работа (remote job) когда тебе не надо тратить время на поиск заказов и переговоры с неадекватными заказчиками.
Если тебе лень выравнивать код руками, закачай его на http://beta.phpformatter.com/ и нажми «format». Робот исправит выравнивание и отступы в мгновение ока (да, прогресс не стоит на месте). Если ты используешь мощную IDE вроде PhpStorm, там тоже есть функция форматирования кода.
Горячие клавиши для форматирования кода в разных IDE: https://gist.github.com/codedokode/8759492
Вообще, в 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/samdark/fig-standards-ru/blob/master/accepted/ru/PSR-1-basic-coding-standard.md
PSR-2: https://github.com/samdark/fig-standards-ru/blob/master/accepted/ru/PSR-2-coding-style-guide.md
------------------
Итак, ты зашел в тред и решил помочь какому-то анону, дав ему совет или подсказку. Спасибо! Но прочти сначала эти напоминания, чтобы твоя помощь действительно была полезной.
Давай удочку, а не рыбу
Лучше не давать готовое решение проблемы, а рассказать как его искать. Может дать ключевые слова для гугла или ссылку. Но помогай, а не пытайся показать превосходство. Если даешь ссылки на нерусскоязычные статьи, упомяни об этом.
Будь доброжелателен
Не годится: «Ты мануал хоть раз в жизни открывал, обезьяна?»
Не годится: «В гугле забанили?»
Не годится: «Твой код плохой»
Хорошо: «Вот, как можно улучшить этот код: ...»
Хорошо: «Ты неправильно используешь функцию abc(). Вот ее описание: ссылка, и как видишь ей надо передать строку, а не массив»
Не придирайся к знанию английского языка.
Объясняй
Не очень хорошо: «сделай как в этом коде»
Хорошо: «если ты вставляешь текст от пользователя в SQL запрос, то получается SQl-инъекция, которая позволяет взломать твой сервер (ссылки). Чтобы этого избежать, надо вставлять данные с помощью плейсхолдеров (ссылки)»
Хорошо: «Помни, что код пишется для людей. Если писать такие большие функции, то в них становится трудно разобраться...»
Не проповедуй
Мы учим использованию самых распространненных подходов, стандартов, библиотеки фреймворков. Если ты не любишь ООП, пробелы в коде, jQuery, сам PHP, то рассказать об этом стоит в каком-нибудь другом треде.
Не придирайся к знанию английского языка, анон пишет как умеет.
Ах да. Если тебе кажется, что что-то в учебнике или задачах можно сделать лучше — пиши, обратная связь всегда очень полезна.
Если тебе лень выравнивать код руками, закачай его на http://beta.phpformatter.com/ и нажми «format». Робот исправит выравнивание и отступы в мгновение ока (да, прогресс не стоит на месте). Если ты используешь мощную IDE вроде PhpStorm, там тоже есть функция форматирования кода.
Горячие клавиши для форматирования кода в разных IDE: https://gist.github.com/codedokode/8759492
Вообще, в 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/samdark/fig-standards-ru/blob/master/accepted/ru/PSR-1-basic-coding-standard.md
PSR-2: https://github.com/samdark/fig-standards-ru/blob/master/accepted/ru/PSR-2-coding-style-guide.md
------------------
Итак, ты зашел в тред и решил помочь какому-то анону, дав ему совет или подсказку. Спасибо! Но прочти сначала эти напоминания, чтобы твоя помощь действительно была полезной.
Давай удочку, а не рыбу
Лучше не давать готовое решение проблемы, а рассказать как его искать. Может дать ключевые слова для гугла или ссылку. Но помогай, а не пытайся показать превосходство. Если даешь ссылки на нерусскоязычные статьи, упомяни об этом.
Будь доброжелателен
Не годится: «Ты мануал хоть раз в жизни открывал, обезьяна?»
Не годится: «В гугле забанили?»
Не годится: «Твой код плохой»
Хорошо: «Вот, как можно улучшить этот код: ...»
Хорошо: «Ты неправильно используешь функцию abc(). Вот ее описание: ссылка, и как видишь ей надо передать строку, а не массив»
Не придирайся к знанию английского языка.
Объясняй
Не очень хорошо: «сделай как в этом коде»
Хорошо: «если ты вставляешь текст от пользователя в SQL запрос, то получается SQl-инъекция, которая позволяет взломать твой сервер (ссылки). Чтобы этого избежать, надо вставлять данные с помощью плейсхолдеров (ссылки)»
Хорошо: «Помни, что код пишется для людей. Если писать такие большие функции, то в них становится трудно разобраться...»
Не проповедуй
Мы учим использованию самых распространненных подходов, стандартов, библиотеки фреймворков. Если ты не любишь ООП, пробелы в коде, jQuery, сам PHP, то рассказать об этом стоит в каком-нибудь другом треде.
Не придирайся к знанию английского языка, анон пишет как умеет.
Ах да. Если тебе кажется, что что-то в учебнике или задачах можно сделать лучше — пиши, обратная связь всегда очень полезна.
Третий и четвёртый результат в гугле по запросу "pdo"
https://habrahabr.ru/post/137664/
http://phpfaq.ru/pdo
Хорошо ли книга? Начал заниматься по ней.
3е издание.
Итоговая цель фулстэк разработка (не по этой книге, а вообще). Эта книга как база.
Если нюфак, то норм. У самого такая
ОП её забракует (не без оснований), но таки рекомендую её прочитать, так как на работе всё равно будешь поддерживать легаси и знать как делали диды тоже иногда полезно. Не то, чтобы книга ужасно устарела, но знать оттуда ты должен всё.
>>848830
Никаких книг по работе с PDO нет и не будет, так как писать там по сути нечего. Читай о PDO на phptherightway, потом опять попробуй мануал.
> ничего не работает
Вот ты бы лучше описал что конкретно не работает. И тебе тяжело придётся на работе, если не можешь в документацию и нуждаешься в разжёвываниях даже для таких простых в использовании вещей как PDO.
{
return User::fromState($row);
}
Что значит одиночное двоеточие после параметра функции (перед User)?
>>>Также, у тебя в контроллере стоит 4 вызова render. Ты выносишь знание о структуре страницы в контроллер, но удобнее просто подключить один шаблон, а он уже пусть подключает что ему нужно.
Перенес рендеры из контроллера в шаблоны:
https://github.com/someApprentice/Students/commit/6b1fb52461786f9fe0966562c73b9f6f99968d5c
Зачем тебе приходилось парсить?
Извиняюсь за сагу.
Он же написал "одиночное" двоеточие.
>>849191
В твоём случае это значит, что метод должен возвращать тип данных User.
Подробнее: https://wiki.php.net/rfc/return_types
Доступно только в PHP 7+
Поищи ещё статьи на хабре по особенностям PHP 7.
>>848419
Как выкидывать стандартную страницу 404 понял, спасибо.
Теперь вопрос. На стандартной странице всё по английски, а я хочу сделать свою, на русском. Нашел, где прописан body: https://github.com/slimphp/Slim/blob/3.x/Slim/Handlers/NotFound.php
Но не знаю, как реализовать по уму. В голову пришли такие идеи:
Сделать свой class NotFoundRus extends AbstractHandler
Сделать клон NotFound и там переопределить renderHtmlNotFoundOutput()
Спасибо, понял
разобрался в ПДО таки, там структура схожа с mysql_
>Сделать клон NotFound и там переопределить renderHtmlNotFoundOutput()
Да, легче всего будет унаследовать класс NotFound и переопределить этот метод.
<div class="header">
<div class="logo">Logo</div>
<ul class="Menu">...</ul>
</div>
.logo {
float: left;
}
.menu {
float: right;
}
Лого и меню разных размеров. Как их обоих выровнять по вертикали чтобы они оба по середине были?
Много не значит хорошо.
Они питушатся со своим ебанутым языком с хуилионом ньюансови псевто технологий. А еще дохуя хепсторов "дай-ка я напишу свою книгу", которые просто копируют(хуево) профи или друг-друга.
ребята, объсните пожалуйста почему, не смотря на то, что строка кода, которая создает файл тест.тхт, заключена в условие, файл создается даже если переменная $t1(textarea в форме) не заполнена и не нажата кнопка сабмит? Насколько я понимаю скрипт же должен работать при isset != null?
<?php
echo "Hello world!";
?>
Но если я его открываю хромом, то вижу сам код, а не результат работы скрипта, Что за херня?
Установил xampp последний, который с поддержкой пхп7, сам файл лежит в папке C:\xampp\htdocs то есть всё по мануалу, что я бля не так делаю?
>>848990
О, анон, я тоже по ней заниматься начал как раз. Ты смог открыть тот сайт с примерами lpmj.net который? У меня почему-то не открывается.
У тебя наверно после .php присутствует .txt , в настройках поставь " показывать расширение файлов".
Не, анон, я не настолько тупой. Есть подозрение что я накосячил с установкой xampp, но вроде там всё отмечено было как надо. Короче хз. Хотел с опреаторами повозиться, всякие уравненьица порешать, а тут такая засада, аж руки опустились.
Бля, я молодец, что сам разобрался, правда, аноны?
А если почитаешь урок https://github.com/codedokode/pasta/blob/master/soft/web-server.md то будешь еще больше молодец.
Не пробовал открывать.
Перепечатываю примеры вручную, полезнее.
Ну точнее планирую перепечатывать.
http://ideone.com/LafiKG
Потому, что сайт не дурак.
http://ideone.com/q0rwrL
http://php.net/manual/ru/control-structures.for.php
В начале каждой итерации оценивается выражение expr2. Если оно принимает значение TRUE, то цикл продолжается
Ок, спасибо, гляну.
>>849543
Ой бля, да просто иди нахуй, ты родился прям неебаться программистом, да?
>>849548
Понял, тоже так собираюсь делать.
fix
Увидел эту статью в шапке, бля ну извините. Всё равно ваш тред дохлый, а так хоть пообщались.
Кидаю файл, скрипт всё загружает, всё ок. шаблон: https://github.com/TheSidSpears/FileHosting/blob/master/templates/upload.html
Он прописывает в <div id="debug"> состояние загрузки как это реализовано: https://github.com/TheSidSpears/FileHosting/blob/master/public/js/uploader-master/src/settings.js#L63
В роутере https://github.com/TheSidSpears/FileHosting/blob/master/src/routes.php#L41 у меня прописано перенаправление на другую страницу, он перенаправляет, но внутри div'а
Раньше у меня перенаправление было прямо в этом js файле, но это не правильно, логику в роутере не видно и потом хер проссыш где это перенаправление находится.
Предполагаю, что надо как-то в onUploadSuccess() сделать выход из div'a и тогда перенаправление может заработать. Хотя ведь сначала выполняется весь код в роутере, а только потом в onUploadSuccess().
В общем, need help
ОП, а сколько у тебя занимает времени проверить одну задачу одного анона уровня студенты-файлхостинг-тестхаб?
http://ideone.com/LafiKG
Получилось. Но как теперь сделать, чтобы он начинал с 1 года и 16 лет, а не со 2 и 17? Не могу додуматься.
Я так понимаю, ты решаешь задачу про банк. Ты в 16 лет ложишь в банк 10000, но говоришь нам об этом в свой следующий день рождения, когда тебе уже 17.
Алсо, подумай, что станет с твоим скриптом, если $q при вычислении будет ровно 100000
Ну и не 100000 а 1000000 (по условию)
> как теперь сделать, чтобы он начинал с 1 года и 16 лет, а не со 2 и 17? Не могу додуматься.
Тоесть ты делаешь сначала 16+1, а потом спрашиваешь вопрос почему получилось 17?
Сейчас по работе нужна такая для составления договоров, что бы подставлять прописью бабло в скобочки по типу:
3500$ (Три тысячи пятьсот долларов США)
В общем скиньте у кого остался хороший код полностью протестированный?
А, извини. Конечно же
echo "Три тысячи пятьсот долларов";
с большой буквы же. Пофиксил, не благодари.
Ну ладно, можно ещё так.
if ($s=3500){
echo "Три тысячи пятьсот долларов";
}
Ну и для каждой суммы пропиши такой if
PSR-IndiaStyle
switch ($i) {
case 3499:
echo "Три тысячи четыреста девяносто девять долларов";
break;
case 3500:
echo "Три тысячи пятьсот долларов";
break;
case 3501:
echo "Три тысячи пятьсот один доллар";
break;
case 3502:
echo "Три тысячи пятьсот два доллара";
break;
case 3503:
echo "Три тысячи пятьсот три доллара";
break;
case 3504:
echo "Три тысячи пятьсот четыре доллара";
break;
}
По вертикали нужно было.
- в строке с временной отметкой заменяю название месяца на английское
- создаю $datetime = \DateTime::createFromFormat('d M Y ...', '06 June 2016 ...')
- В базу сохраняю уже $datetime->format(\DateTime::ATOM)
Может как-то попроще сделать? В гугле советуют трюки с изменением локали, это хорошая практика?
Использую MySQL, PDO (пишу SQL-запросы руками).
2) ОП, можешь, пожалуйста, squash'ить коммиты? Или подсказать, как читать diff'ы разных коммитов как один diff? Сейчас приходится все 5 коммитов по отдельности открывать (пик). Спасибо за полезные обновления!
Внутри PHP есть 2 формата представления дат:
- в виде числа секунд с 1 янв 1970 года (unix timestamp)
- виде объекта DateTime
Урок https://gist.github.com/codedokode/10539805
В базе есть специальные типы колонок, YEAR, DATE, DATETIME, TIMESTAMP, формат '2016-01-01 12:00:00'
> Или подсказать, как читать diff'ы разных коммитов как один diff?
https://github.com/codedokode/pasta/compare/ и тут выбрать даты или коммиты которые надо сравнить.
Полезнее ставить руками, тем более в ОП посте есть советы по теме.
Прежде чем браться за Апач, можно ипользовтаь веб-сервер в составе php.
>>849809
Не флудите
>>849708
Переставить $e++ в другое место. Также, лучше давать более осмысленные имена.
>>849680
> он перенаправляет, но внутри div'а
Скорее всего скрипт закачки создает ифрейм и постит форму с файлом в него, а ифрейм это считай как отдельная вкладка встроенная в страницу.
Ты должен снаружи ифрейма получать событие завершения закачки и яваскриптом делать переход на нужную страницу. посмотри документацию к библиотеке.
Алсо способ это древний, в новых браузерах файлы можно отправлять аякс-запросом и тогда можно ссылку получить в ответе на этот запрос.
Редирект на сервере работал бы только в случае обычной отпарвки формы, а не через ифрейм или аякс.
В случе с ифреймом делали так: выводили туда скрипт вроде
window.parent.callSoeFunction('data')
Но это конечно довльно костыльно. Главная проблема ифрейма в том, что там неудобно отслеживать ошибку при загрузке (а у тебя кстати это обнаруживается?)
я бы советовал в новых браузерах слать аяксом, а старых - обычной отправкой формы с редиректом.
Полезнее ставить руками, тем более в ОП посте есть советы по теме.
Прежде чем браться за Апач, можно ипользовтаь веб-сервер в составе php.
>>849809
Не флудите
>>849708
Переставить $e++ в другое место. Также, лучше давать более осмысленные имена.
>>849680
> он перенаправляет, но внутри div'а
Скорее всего скрипт закачки создает ифрейм и постит форму с файлом в него, а ифрейм это считай как отдельная вкладка встроенная в страницу.
Ты должен снаружи ифрейма получать событие завершения закачки и яваскриптом делать переход на нужную страницу. посмотри документацию к библиотеке.
Алсо способ это древний, в новых браузерах файлы можно отправлять аякс-запросом и тогда можно ссылку получить в ответе на этот запрос.
Редирект на сервере работал бы только в случае обычной отпарвки формы, а не через ифрейм или аякс.
В случе с ифреймом делали так: выводили туда скрипт вроде
window.parent.callSoeFunction('data')
Но это конечно довльно костыльно. Главная проблема ифрейма в том, что там неудобно отслеживать ошибку при загрузке (а у тебя кстати это обнаруживается?)
я бы советовал в новых браузерах слать аяксом, а старых - обычной отправкой формы с редиректом.
В общем тебе надо изучить что такое ифреймы, с точки зрения как они работают, а также яваскриптовые АПИ к ним (parent, frames, contentWindow, contentDocument). И также same origin policy.
Но ифреймы это старый способ отправить форму без аякса и без перезагрузки страницы. У него есть свои недостатки.
>>849420
Да, хром же не умеет выполнять php код. Это делает php в составе веб-сервера.
>>849417
Тебе не нужен xmpp, достаточно php и встроенного в него веб сервера, урок https://github.com/codedokode/pasta/blob/master/soft/web-server.md + урок по установке пхп из ОП поста.
>>849329
Кнопку ты наверно все же нажимаешь, иначе бы isset не сработал.
>>849319
Применяется, если ширина ограничена. Или ты имел в виду по вертикали?
>>849318
Можешь спросить как лучше ту или иную вещь делать.
>>849303
inline-block + vertical-align.
>>849261
Унаследовать можно как вариант. Или написаь свой хендлер как тут http://www.slimframework.com/docs/handlers/not-found.html - это ведь всего лишь 1 простая функция, тут и класс не нужен.
>>848830
Офиц мануал не смотрел?
В общем тебе надо изучить что такое ифреймы, с точки зрения как они работают, а также яваскриптовые АПИ к ним (parent, frames, contentWindow, contentDocument). И также same origin policy.
Но ифреймы это старый способ отправить форму без аякса и без перезагрузки страницы. У него есть свои недостатки.
>>849420
Да, хром же не умеет выполнять php код. Это делает php в составе веб-сервера.
>>849417
Тебе не нужен xmpp, достаточно php и встроенного в него веб сервера, урок https://github.com/codedokode/pasta/blob/master/soft/web-server.md + урок по установке пхп из ОП поста.
>>849329
Кнопку ты наверно все же нажимаешь, иначе бы isset не сработал.
>>849319
Применяется, если ширина ограничена. Или ты имел в виду по вертикали?
>>849318
Можешь спросить как лучше ту или иную вещь делать.
>>849303
inline-block + vertical-align.
>>849261
Унаследовать можно как вариант. Или написаь свой хендлер как тут http://www.slimframework.com/docs/handlers/not-found.html - это ведь всего лишь 1 простая функция, тут и класс не нужен.
>>848830
Офиц мануал не смотрел?
Наркоман что ли? Если сделать
.classname {
width:40%;
margin:0 auto;
}
То элемент будет по центру
Поставь open server и не парься
ты все 270к сразу выводишь?)
У тебя не бд тормозит, а браузер от такого
Запрашивай и выводи данные частями
- >>850072 https://github.com/enotocode/Studentslist 03/10/16
- >>850070 задачки на JS 11|12
- >>849044 JSON и ErrorObject
- >>849012 отличия TDG и DM
- >>848567 ООО Вектор + антиризисные меры
- >>848545 калкулятор, навигатор от 10 сент.
- >>848461 https://github.com/never3ver/studentslist
- >>848462 https://github.com/never3ver/fileshare/ 29/09/16
- >>848419 w5_1 - w5_6
- >>847780 https://github.com/anotherCodeMunkey/studentsList/ 26/09/16
- >>847779 публикация статики из композера
- >>847778 https://github.com/Phrlog/StudentList/ 26/09/16
- >>846554 https://github.com/TheSidSpears/FileHosting 23/09/16
- >>846553 https://github.com/TheSidSpears 23/09/16
В общем, разгребаем потихоньку.
Если ответа долго нет, можно напомнить о себе тут.
Запасной тред на случай проблем с этим форумом: http://dobrochan.org/s/res/23225.xhtml#i46467
устроился на удаленку 0.7$ в час на начальном этапе, куда двигаться дальше?
Расскажи поподробнее, интересно послушать как устроен твой день в итоге. Сколько по факту часов приходится работать вместо 8?
>>849812
Я гуглил, нагуглил вроде бы две вменяемых функции со хабры и ру_стаковерфло. Но сразу же задетектил ошибку в одной, прогоняя в ней числа кратные 100, хотя там блядь гора лайков у неё. Жалею теперь что свою не схоронил.
Встаю где то часов в 8-9, занимаюсь своими делами, график занятости у меня на текущей момент 7 дней рабочих, 2 выходных
Начинаю с 10-11 работать, все зависит от задач, которые решаю, если легкие, то обычно 3-4 часа уходит в день на работу, если задача тяжелая, обьемная, могу делать целый день и чуть дорабатывать на следующий.
Сейчас обычно несколько задач на день выходит. Рабочий график с 10 утра до 22 вечера. В среднем 5-6 часов, где то доходило и до 8-9 часов за день.
Оплата каждые 7 дней, 2 выходных
Самому 20 лет, съехал от родителей, живу в хостеле в Киеве, пыху и js учил пол года в целом(до этого еще 2 года на питоне писал) без вышки
То есть у тебя неделя как бы 9 дней, и при этом тебе платят именно за часы? То есть если поработал 4 часа, то и платят 3 бакса за этот день? А если 10, то и 7 уже? Это по вашим меркам вообще норм?
Неделя у меня 7 дней
По оплате вообще так, но я же говорю, на начальном этапе, в дальнейшем буду повышать ставку. За неделю выходит где то баксов 30
>живу в хостеле в Киеве
Проясни этот момент пожалуйста. Сколько денег, условия. А то, я тут тоже уже половиной жопы на чемодане сижу.
Надо повышать свой уровень, чтобы переходить от простых, но времязатратных задач к сложным. Тогда и оплата будет выше.
Если ты делаешь работу с которой каждый второй школьник справится, то да, условия будут не очень выгодные.
Для этого надо выделять время на самообразование.
То есть учить MVC, ООП, фреймворки (Symfony например), HTML/CSS/JS до нормального уровня, SQL в детялях и оптимизацию запросов. Автоматизированное тестирование. Алгоритмы.
Читай также хабр для развития кругозора.
С такими знаниями я думаю будут и варианты удаленки, и оффлайновой работы.
Вот у нас есть задача про тестхаб (в ОП посте) - ты можешь ее сделать? Предыдущие, про файлообменник или студентов - можешь?
820 в месяц стоит, жить если то только недолго, если дольше, то поедешь от постоянного количества людей вокруг, я то уже привык.
Все есть, душ общий, жильцы разные есть, кто то бухает постоянно, кто то спокойно себе живет.
Но лучше жить тогда уж в комнате, хотя я хз
Нуу, я занимался месяца 4 CRM-системой волонтерской, со всеми задачами справлялся, простыми и сложными и ей сейчас успешно пользуется не одна сотня людей
Файлообменник и студентов могу, а тестхаб не смотрел еще, что за задача
с Yii1/Yii2/Laravel знаком, сейчас проектом на Yii2 занимаюсь на этой удаленке
Даже какое то время проработал MSSQL разработчиком, пока не надоело.
> Скорее всего скрипт закачки создает ифрейм
Если в моём проекте не встречается в поиске слово iframe, значит ли, что я могу с увереностью утверждать, что он не используется?
Вообще вот описание с гитхаба: jQuery Ajax File uploader with progress bar and drag and drop https://github.com/danielm/uploader
Можно открыть отладчик в браузере (Ctrl + SHift + I) и им посмотреть, и есть ли там ифрейм, и что куда отправляется, и даже яваскрипт по шагам отладить.
куда он из шапки пропал?
в пхп.мануал как-то не очень совсем
Друзья, такой вопрос: пишу в пхпшторме простой скрипт. Запускаю на опенсервере - кириллицу отображает без проблем. Но стоит мне прочитать строку русского текста из txt файла - выводятся черные ромбики со знаками вопроса внутри. Уже пробовал менять кодировку файла в notepad++ на utf(без BOM) и в .htaccess сетил дефолтную кодировку utf-8 короче перепробовал весь гугл. Подскажите что это и как с этим справиться
Проверь через отладчик браузера с какой кодировкой тебе отдает сервер, .htaccess не всегда подхватывает кодировку, наверное лучше её устанавливать через мета-тег или заголовок.
А это не то?
> Чтобы делать эти задания, тебе надо установить Апач + PHP (можно заодно сразу и MySQL) на компьютер. Вот полезные инструкции:
> https://github.com/codedokode/pasta/blob/master/soft/php-install.md
> https://github.com/codedokode/pasta/blob/master/soft/apache-install.md
>>850289
Надо делать header с content-type и charset.
И вот я потею и гуглю как чумачечий, хотя задания, как я понимаю, на полчаса более-менее разбирающемуся человеку. Понимаю что тяну еле-еле, если вообще тяну, но мб в коллективе и с заданиями прогресс пойдет быстрее.
В общем суть вопроса: мне заливать свои поделия на github или куда, чтоб показать свои корчи и не опозориться отправкой txt файликов? Как они там отнесутся если я попрошу еще времени, а то с дуру ляпнул что сделаю завтра (уже сегодня) к вечеру, а там вопросики по всему:html,css,php,sql,js.
И посмотрите тестовое задание, пожалуйста:
https://github.com/Daikon5/test-php/blob/master/1/test.php
Именовать переменные транслитом - дурной тон. Почитай >>848552, оп там дело написал.
И да, оформление важно.
И еще: хотя к комментариям у разных людей отношение разное, но коммент к каждой строчке - это явное излишество. Особенно что то вроде этого: $max = 999; // максимальное число
Комментарии нужны, но это не должны быть комментарии капитана очевидность, то есть не надо пересказывать учебник по php и объяснять что делает строчка.
> $random = rand($min, $max); // генерим случайное число
Это не нужно так как зачем нужна функция можно прочесть в мануале.
> $max = 10000; // максимальное число
Это допустимо, но лучше называть переменные так чтобы комментарий даже не требовался.
Надо объяснять, почему ты сделал так или иначе, зачем нужна эта функция, какой используется алгоритм итд.
Также, советую оформить код в соответствие с PSR. Например имена переменных не пишут с большой буквы.
Также, написать пару строчек в ридми так как человек который откроет твой гитхаб, первым делом его увидит.
Сам код не комментирую так как задача проверяет твои знания, а не наши.
Если ты захочешь лучше изучить php/html/js/sql, у нас есть задачи по ним в ОП посте.
1. Как настроить апач чтобы мой сайтик можно было смотреть из глобала?
2. Старый оп покинул этот тред?
Да, ещё можно об увлечениях, например аниме любимое.
Пару слов о программе которую ты пишешь.
Про пхп htmk css ответил где-то половину, sql написал базовый селект, по js вообще ничего, кароч пиздец.
Мне чувак сказал, что хоть я и хуево ответил но тип норм, что я же на стажировку претендую.
Потом спрашивали про то сколько я программирую, сказал, что год. Мне сказали, что я поздно начал и все такое, но тип ничего страшного опять же.
Спросили про зарплату какую ожидаю, сказал средне-маленькую сумму. Спрашивали не сьебу ли я от них после того как они меня обучат, я сказал что нет, что планирую оставаться в этом мухосранске, они сказали, что все так говорят и спросили "Что тебя здесь держит?" и тут я обосрался опять и начал мямлить.
Спрашивали когда я свободен и когда могу приходить и все такое.
Сказали, что позвонят на этой неделе точно.
Как думаете, аноны? Меня возьмут? Почему мне дали какие-то ебучие тесты с вопросами аля
Чему равно $a?
$a = false ?? 10 ?? 20
Понятно, что стажер не шарит в таких конструкциях да и нахуй они не нужны, про ООП вообще 0 вопросов
> Двач лежит? Есть запасной тред: http://dobrochan.org/s/res/23225.xhtml#i46467
13 июля 2012
Вот это выдержка!
>я поздно начал и все такое, но тип ничего страшного опять же.
Не волнуйся насчёт этог бро. Сам боялся адово когда такие истории ходили. Сейчас понимаю что вкатываться после 27 - это норма. Просто много кому нужен именно молодой, именно из-зи низких зарплат. Мол студента наймём, он будет нам за 200$ сайтики пилить и норм.
Мне вообще 32, образование и работа никак не связаны с программированием, а я мечтаю о собственном проекте в Интернете и иду к нему уже второй год.
Некоторые сайты проводят розыгрыши призов среди своих подпсичиков. Предположим у нас
есть id 1000 пользователей (вам нужно сгенерировать их самостоятельно). Призов
разыгрывается только 50. Выберите этих 50 счастливчиков случайным образом (естественно,
один подарок - в одни руки)
Это задание на стажёра, серьёзно? Или ещё что-то есть?
Еще нет, доделываю.
>>850493
Написал же: типа этого по html, css, php, js, sql.
Сильно простое?
Вкатился в 23 с нулем знаний, полет нормальный.
Чот толи я туплю, толи PHPstorm. Поигрался немного, отредактировал 4 строки кода и прекрасно закомитил. Затем изменил код ещё в 20 файлах, решил несколько задачек, и коммитить не получается, говорит пикчу. Что я делаю не так?
Возможно что файлы, в которые ты вносил изменения, не добавлены в VCS. У тебя гит? В идее можно сделать alt+9 -> Local Changes -> Unversioned files и посмотреть, что не добавлено в гит. Там же и изменения лежат.
Да, гит. Щас проверю, спасибо.
Заработало! Спасибо!
Это ведь означает что если мы туда переберемся в случае каких-то проблем, наши посты не исчезнут через неделю, а останутся надолго.
>>850463
Я бы не очень расчитывал на "обучение". Цель компании зарабатывать деньги, так что думаю что если они тебя и обучат, то только каким-то простым вещам, которые им нужны. Если ты сам будешь учиться по 8 часов в день дома, то ты гораздо больше выучишь.
>>850499
Я думаю что простое. Я не уверен, но думаю, что его легко решат аноны которые прошли первые 4-5 уроков в моем учебнике. То есть которые 2 недели назад учиться начали.
>>850506
В гите по моему прежде чем коммитить, надо "добавить" файлы (точнее изменения в них) в "индекс" (то есть в будущий коммит).
В командной строке проверить можно командой git status, в IDE - не знаю, как.
Клиент гита в IDE - не для начинающих, а для опытных пользователей. Если ты начинающий, то ты должен открыть git book, зайти в командную строку и писать все команды вручную. И только когда ты все это изучишь, переходить к клиенту в IDE. Тогда бы ты такие вопросы и не задавал.
Мое мнение - я бы тех, кто не умеет пользоваться git в командной строке считал не умеющими пользоваться гитом вообще. Кнопки нажимать по видеоурокам много ума ведь не надо, но это тебе не поможет когда что-то пойдет не так. А поможет знание того, как устроен и работает гит.
>Клиент гита в IDE - не для начинающих, а для опытных пользователей. Если ты начинающий, то ты должен открыть git book, зайти в командную строку и писать все команды вручную. И только когда ты все это изучишь, переходить к клиенту в IDE. Тогда бы ты такие вопросы и не задавал.
Не согласен. Проще сначала научиться с ним работать в IDE(или любой гуй), а потом лезть в кишки.
Добавлять файлы в консоли - боль.
>А поможет знание того, как устроен и работает гит.
А поможет гугл и тот же самый git book. Знания надо получать по мере необходимости, имо.
вот именно, что сам я по 8 часов дома учиться не буду, а учиться получая деньги уже совсем другое
Я посмотрю на тебя и git add ., когда тебе надо будет закоммитить лишь часть изменений.
Почему ты не будешь учиться дома по 8 часов? Тебе не интересно программирование что ли?
не на столько
>>849860
Да вообще, вроде задания норм выполнял, ну в процедурном стиле, конечно, да и не в ООП легко могу такое написать (студентом), но это все бесполезно, конечно. Именно в ОО анализе и проектирование трудности испытываю: какие классы должны быть, как взаимодействовать им, нужен ли отдельный класс для сессий/куки или это будет заложено в методах класса авторизации. Про паттерны читал, вроде понятно, но как самому делать, так сразу куча вопросов, сомнений и неясность
>нужен ли отдельный класс для сессий/куки или это будет заложено в методах класса авторизации
Одно слово: фреймворк.
это все хорошо, но не нужно ли сначала самому с таким повозиться, а потом уже на них переходить?
В чем боль? Одна команда. У тебя по моему просто боязнь консоли, и это плохо (и кстати у нас в ОП посте есть небольшой гайд по консоли).
Просто ты по факту не хочешь изучить даже основы гита, а хочеь их проскочить, и это приведет к тому что ты например потом не сможешь разобраться с конфликтами или мерджами или еще чем-то.
> Знания надо получать по мере необходимости, имо.
Если тебе нужно решить какую-то сложную систему уравнений то конечно лучше нагуглить решение. Но основы вроде сложения, умножения или правил преобразования выражений надо выучить заранее.
>>850568
Эффективность обучения будет ниже, у тебя будет меньше знаний.
>>850570
1) это мало когда нужно
2) если все же нужно, добавить несколько файлов не так и трудно.
Ну и ты привел пример ситуации явно не для начинащего. Я сколько лет пользуюсь системами контроля версий и не припомню чтобы мне это было нужно (скорее всего в твоей ситуации могли бы помочь ветки).
>>850577
Паттерны сами по себе не понять. Надо смотреть код который их исопльзует (например поковырять исходники Симфони), а также понимать почему они тут исопльзованы.
Люди, которые не поняли паттерны, а просто заучили их определения, используют их не к месту и только усложняют код.
Насчет ООП такая вещь: надо решать задачки на ООП (задачки вроде смоделируйте что-нибудь в виде классов), а также смотреть готовый код. В случае с вебом, все давно уже придумано и надо просто смотреть как то или иное сделано например в симфони.
> какие классы должны быть, как взаимодействовать им,
Ну главный принцип что у каждого класса своя зона ответвенности, своя задача. В веб-приложениях это обычно: контроллеры, модели, формы, классы работы с БД, сервисы.
Разбивать код на классы надо для того, чтобы класс можно было рассматривать отдельно от остального кода. Так как кода обычно много и без разделения на классы в нем легко запутаться. Это в задаче про студентов у нас обычно 5-15 классов, а в реальных приложениях их будут сотни и тысячи, а строк будут десятки и стони тысяч. И без четкого разделения на модули разобраться там будет нереально. Именно потому ООП с 80-х годов активно используется в коммерческой разработке - как только компьютеры стали мощнее, программы стали больше и понадобился способ разбивать их на отдельные части.
Надо найти золотую середину между "весь код в одном большом классе" и "куча маленьких классов из 1 функции".
Если ты делаешь какую-то из наших задач и затрудняешься с проектированием классов, ты можешь придумать схему, вбросить в тред и попросить советов. Сам код не нужен, для начала можно просто описать какие есть классы, за что каждый отвечает и какие у них публичные методы, вроде такого:
class IndexController {
function showPageAction();
}
class Student {
public $name;
public $surname;
...
}
class StudentTableGateway {
public function getStudentById($id): Student
public function addStudent(Student)
...
}
То есть чтобы из схемы было видно что куда передается и за что отвечает. Если ты напишешь такую схему, я или кто-то еще сможет посмотреть и дать советы.
Хорошая идея в ООП начинать именно с такой схемы. Не спеши писать код. Для начала:
- реши, за что отвечает класс и выбери название класса
- реши, что он должен делать, и напиши методы, опиши что они получают и возвращают
- реши что классу нужно для работы и напиши конструктор (к примеру: классу StudentTableGateway нужен объект PDO потому мы передадим его в конструктор)
- затем реши как классы взаимодействуют друг с другом (например: контроллер вызывает валидатор чтобы проверить правильно ли введена информация для регистрации студента)
По такой схеме уже можно судить о том, правильно ли спроектированы классы или нет. Видеть код для этого не требуется.
Там еще есть специальные языки (вроде UML), чтобы рисовать диаграммы классов, но я думаю, написать текстом может быть проще. Хотя если тебе хочется изучить UML, почему бы и нет.
В чем боль? Одна команда. У тебя по моему просто боязнь консоли, и это плохо (и кстати у нас в ОП посте есть небольшой гайд по консоли).
Просто ты по факту не хочешь изучить даже основы гита, а хочеь их проскочить, и это приведет к тому что ты например потом не сможешь разобраться с конфликтами или мерджами или еще чем-то.
> Знания надо получать по мере необходимости, имо.
Если тебе нужно решить какую-то сложную систему уравнений то конечно лучше нагуглить решение. Но основы вроде сложения, умножения или правил преобразования выражений надо выучить заранее.
>>850568
Эффективность обучения будет ниже, у тебя будет меньше знаний.
>>850570
1) это мало когда нужно
2) если все же нужно, добавить несколько файлов не так и трудно.
Ну и ты привел пример ситуации явно не для начинащего. Я сколько лет пользуюсь системами контроля версий и не припомню чтобы мне это было нужно (скорее всего в твоей ситуации могли бы помочь ветки).
>>850577
Паттерны сами по себе не понять. Надо смотреть код который их исопльзует (например поковырять исходники Симфони), а также понимать почему они тут исопльзованы.
Люди, которые не поняли паттерны, а просто заучили их определения, используют их не к месту и только усложняют код.
Насчет ООП такая вещь: надо решать задачки на ООП (задачки вроде смоделируйте что-нибудь в виде классов), а также смотреть готовый код. В случае с вебом, все давно уже придумано и надо просто смотреть как то или иное сделано например в симфони.
> какие классы должны быть, как взаимодействовать им,
Ну главный принцип что у каждого класса своя зона ответвенности, своя задача. В веб-приложениях это обычно: контроллеры, модели, формы, классы работы с БД, сервисы.
Разбивать код на классы надо для того, чтобы класс можно было рассматривать отдельно от остального кода. Так как кода обычно много и без разделения на классы в нем легко запутаться. Это в задаче про студентов у нас обычно 5-15 классов, а в реальных приложениях их будут сотни и тысячи, а строк будут десятки и стони тысяч. И без четкого разделения на модули разобраться там будет нереально. Именно потому ООП с 80-х годов активно используется в коммерческой разработке - как только компьютеры стали мощнее, программы стали больше и понадобился способ разбивать их на отдельные части.
Надо найти золотую середину между "весь код в одном большом классе" и "куча маленьких классов из 1 функции".
Если ты делаешь какую-то из наших задач и затрудняешься с проектированием классов, ты можешь придумать схему, вбросить в тред и попросить советов. Сам код не нужен, для начала можно просто описать какие есть классы, за что каждый отвечает и какие у них публичные методы, вроде такого:
class IndexController {
function showPageAction();
}
class Student {
public $name;
public $surname;
...
}
class StudentTableGateway {
public function getStudentById($id): Student
public function addStudent(Student)
...
}
То есть чтобы из схемы было видно что куда передается и за что отвечает. Если ты напишешь такую схему, я или кто-то еще сможет посмотреть и дать советы.
Хорошая идея в ООП начинать именно с такой схемы. Не спеши писать код. Для начала:
- реши, за что отвечает класс и выбери название класса
- реши, что он должен делать, и напиши методы, опиши что они получают и возвращают
- реши что классу нужно для работы и напиши конструктор (к примеру: классу StudentTableGateway нужен объект PDO потому мы передадим его в конструктор)
- затем реши как классы взаимодействуют друг с другом (например: контроллер вызывает валидатор чтобы проверить правильно ли введена информация для регистрации студента)
По такой схеме уже можно судить о том, правильно ли спроектированы классы или нет. Видеть код для этого не требуется.
Там еще есть специальные языки (вроде UML), чтобы рисовать диаграммы классов, но я думаю, написать текстом может быть проще. Хотя если тебе хочется изучить UML, почему бы и нет.
Я на такую подозрительную ссылку не то что кликать, даже мышь наводить бы не стал. slink это сокращалка ссылок.
Тебя все равно сейчас удалят, можешь не спамить своими конференциями на этой доске.
>У тебя по моему просто боязнь консоли, и это плохо
Нет, у меня все хорошо с консолью и я осознаю, что консольный гит - потеря времени. Хотя иногда приходится залазить и в это, да.
>потом не сможешь разобраться с конфликтами или мерджами или еще чем-то.
Вот именно потому и не хочу. Конфликты при мерже в консоли - беда, а в иде/гуе для гита - все приятно и понятно. Зачем тратить больше усилий, если можно достичь того же результата, но с удобством?
>Если тебе нужно решить какую-то сложную систему уравнений то конечно лучше нагуглить решение. Но основы вроде сложения, умножения или правил преобразования выражений надо выучить заранее.
Гит - это не основа. Гит - это вспомогательные технологии. Он вообще прямо к программированию не относится. Да и осваивается на раз-два, если его не бояться.
>Ну и ты привел пример ситуации явно не для начинащего. Я сколько лет пользуюсь системами контроля версий и не припомню чтобы мне это было нужно (скорее всего в твоей ситуации могли бы помочь ветки).
Ну как. Делаешь свой сервис, по пути какой-то мелкий баг фиксанул в чужом и сразу закоммитил-отправил. Вполне себе обыкновенная ситуация.
>2) если все же нужно, добавить несколько файлов не так и трудно.
Опять же: зачем пердолиться в консоли, если можно не пердолиться в консоли? Особенно если работаешь на винде.
>Насчет ООП такая вещь
Мне кажется, что у всех проблема с объяснением применения ооп. Лучше пояснить за архитектуру приложения: слой доступа к данным, слой сервисов, туда-сюда, чем играться с кошками-мышками. Потому все и боятся ооп, что не понимают профитов от него. Оно и ясно: как понять профиты, когда все примеры про бургеры, а в реальном приложении у тебя ехал абстракт дао через сервис контроллером погоняя.
Не ОП.
Мне кажется, что ты объясняешь ООП для будущих слесарей, которым нужно просто стоять возле станка всю жизнь, а если возникнет необходимость в другом станке, то переучиваться такие слесари будут со скрипом, ввиду непонимания базовых концепций работы станков. Что по моему мнению "базовые концепции" в ООП?
- Разделение ответственности, самая главная концепция, придерживаясь которой можно писать хороший код и без шаблонов из GoF;
- Инкапсуляция - возможность выставить наружу лишь интерфейс, а детали реализации скрыть;
- Слабая связанность;
Как результат этих трёх пунктов - легко тестируемый код.
И таки после бургеров и кошек-мышек понимать ООП гораздо проще.
Вот у меня есть знакомый Yii/CodeIgniter-разраб с 3-х летним опытом, хорошо оплачиваемый, не знает про DI и держит логику в контроллерах, от Symfony плюётся (для него слишком сложно). Очевидно, что человек сел за фреймворки раньше, чем за основательное изучение ООП. Хотя здесь можно поднять вопрос, кто важнее работодателю, человек-практик, который умеет быстро совладать разными с API, не вникая в механизмы их функционирования, или человек с фундаментом, но который привык основательно во всём разбираться, соответственно затрачивая больше времени на выполнение работы.
Поизучав код, решил что всё-таки делать перенаправдение в settings.js - это нормально. По сути, его задача и есть сконфигурировать, как будет работать скрипт автозагрузчика при той или иной ситуации.
Почему перенаправление происходило в div - тоже разобрался. Там строчка в settings.js в onUploadSuccess: add_log('Server Response for file #' + id + ': ' + JSON.stringify(data));
Так вот эта data хранит содержимое return'a, а у меня там рендер страницы был.
В итоге return'ится у меня теперь строка (Success/Failed), а перенаправление в конфиге скрипта
Вопрос: актуально ли сейчас делать два загрузчика, один на js, другой стандартный? На случай, если в каком-то браузере будет отключён JS (и прописывать его в <noscript>)
Ну я собственно о том же.
Расслоение приложения, пояснение почему это хорошо и все такое - это как раз таки все те вещи, что ты указал, только на живых примерах.
И да, я бы пояснял как слесарям. Но в случае программирования станок=стек, вот и всё. А твой знакомый - просто лентяй и пхп макака, без обид.
>Хотя здесь можно поднять вопрос, кто важнее работодателю, человек-практик, который умеет быстро совладать разными с API, не вникая в механизмы их функционирования, или человек с фундаментом, но который привык основательно во всём разбираться, соответственно затрачивая больше времени на выполнение работы.
Важнее тот, кто делает свою работу. Быстро, качественно. Если ты основательно будешь разбираться в типовом приложении пару месяцев - то нафиг ты такой нужен?
Ну у меня сложилось ощущение что ты не понимаешь гит. Консоль хороша тем что это самый прямой интерфейс к гиту без лишних посредников. ты например можешь сделать git status и увидеть текущее состояние рабочей области. Соответственно если ты понимаешь как гит работает, консоль не представляет никакой сложности так как там ты отдаешь нужные команды напрямую.
А чтобы работать с гитом в IDE тебе надо знать и сам гит, и особенности реализации интерфейса к нему, что за каким пунктом спрятано. Я не понимаю, как это "проще". Изучать же больше приходится.
Ну вот пример из мануала: https://www.jetbrains.com/help/phpstorm/2016.2/merging-deleting-and-comparing-branches.html
Я бы не сказал что он такой простой и понятный. Без понимания гита понять то, что там написано, нельзя.
У меня есть ощущение что некоторые люди вместо изучения принципов
работы гита смотрят видеоурок и запоминают, какой пункт в меню надо нажать. И потому им кажется что это "проще" чем непонятная консоль без кнопок и менюшек. И что в графическом интерфейсе можно разобраться интуитивно без чтения мануалов. Но факт в том что они лишь научились повторять действия в видео, а сам гит так и не изучили. И статью выше про ветки они вряд ли осилят.
От таких людей в команде проблемы. Они избегают веток, мерджей, тем более конфликтов (и например предпочитают вместо этого вручную копировать файлы) и это влияет и на их производительность, и способность разбираться в сложных ситуациях. Или они могут закоммитить что-то лишнее, так как не очень понимают, что происходит. Не умеют сравнить разные ветки и увидеть кто, что и где поменял.
Чтобы участвовать в командной разработке, надо полноценно владеть гитом. И чтобы пользоваться гитом в IDE, надо все равно его изучить сначала на примере командной строки.
Конфликты руками я не предлагаю разрешать, удобнее конечно использовать GUI программу для просмотра и выбора изменений. Но опять же, человек, не знающий гит, в ней не разберется.
> Ну как. Делаешь свой сервис, по пути какой-то мелкий баг фиксанул в чужом и сразу закоммитил-отправил. Вполне себе обыкновенная ситуация.
Если это разные репозитории то проблем никаких нет и нет нужды коммитить только часть файлов. Гит-репозитории можно вкладывать друг в друга и все должно корректно работать.
> Опять же: зачем пердолиться в консоли,
Это надо делать на этапе изучения гита чтобы работать с гитом напрямую, не изучая как представляет информацию из гита GUI. Если ты уже изучил гит то это не требуется. Но проблема в том, что люди просто не хотят изучать гит и думают что раз там GUI, то можно разобраться "интуитивно". Будь моя воля, я бы таких отправлял учиться прежде чем приступать к работе (но тут встает другая проблема, с нынешним качеством разработчиков придется кучу кандидатов отсеять. Мы все-таки должны решать задачи бизнеса, и не знающий гита разработчик решает их лучше, чем отсутствующий разработчик).
> Лучше пояснить за архитектуру приложения: слой доступа к данным, слой сервисов, туда-сюда, чем играться с кошками-мышками.
Сначала надо научиться создавать и работать с объектами, а потом к слоям переходить. И кошки-мышки тут хорошо подходят, так как сразу не очевидно как там правильно код разбить на классы.
А перейти от класса-кошки к модели или сервису не так и сложно. По идее этим люди занимаются в задаче про студентов.
>>850742
В программировании подход "смотри как делают другие и делай так же" не работает. И "объяснения для слесарей" тоже.
В твоем списке концепций, к сожалению, много непонятных для начинающего слов. И я не думаю что цель ООП в первую очередь в тестировании кода, а в разделении на слабосвязанные части, которые можно читать/править независимо от других, что позволяет бороться со сложностью в большиз программах.
Знакомый твой (судя по описанию) ООП не знает, а только умеет писать классы "по аналогии".
>>850744
Я думаю с сервера надо возвращать id или ссылку на файл, а то как ты сделаешь перенаправление на нужную страницу?
> Вопрос: актуально ли сейчас делать два загрузчика, один на js, другой стандартный? На случай, если в каком-то браузере будет отключён JS (и прописывать его в <noscript>)
Как начинающему, да, надо бы сделать. Во-первых, во время обучения надо ставить себе задачи сложнее, а не проще, во-вторых, безяваскриптовый код поможет тебе если например в JS будет ошибка.
noscript там не нужен, надо просто при отсутствии JS/отсутствии в браузере нужных фич отправлять обычную форму с файлом. Ну например, можно показывать обычный файловый инпут в таком случае. А при наличии поддержки - превращать этот инпут в поверхность для приема перетаскиваемых файлов и кнопку выбора файла.
2 загрузчика не нужны, я думаю, что можно серверный скрипт написать так, чтобы он принимал и обычные, и аякс загрузки. Тут вообще много усилий для фоллбека на обычную загрузку, на мой взгляд, не требуется.
Не используй билиотеку как черный ящик. Ты должен понимать как она устроена внутри и какие принципы использует. И соответственно, какие особенности и ограничения из этого вытекают. Какие браузеры и в каких условиях поддерживаются. И ты должен уметь при необходимости уметь разобарться в ее коде, чтобы найти причину бага, или способ как-то нестандартно ее подключить.
Соответственно, если например что-то не работает и файл не загружается - ты должен знать все нужные инструменты и способы для поиска причин проблемы. Не менять опции наугад.
Чтобы скрипт скопировать с гитхаба - ума много не надо, этим пусть верстальщики занимаются, а программист должен знать больше.
Ну у меня сложилось ощущение что ты не понимаешь гит. Консоль хороша тем что это самый прямой интерфейс к гиту без лишних посредников. ты например можешь сделать git status и увидеть текущее состояние рабочей области. Соответственно если ты понимаешь как гит работает, консоль не представляет никакой сложности так как там ты отдаешь нужные команды напрямую.
А чтобы работать с гитом в IDE тебе надо знать и сам гит, и особенности реализации интерфейса к нему, что за каким пунктом спрятано. Я не понимаю, как это "проще". Изучать же больше приходится.
Ну вот пример из мануала: https://www.jetbrains.com/help/phpstorm/2016.2/merging-deleting-and-comparing-branches.html
Я бы не сказал что он такой простой и понятный. Без понимания гита понять то, что там написано, нельзя.
У меня есть ощущение что некоторые люди вместо изучения принципов
работы гита смотрят видеоурок и запоминают, какой пункт в меню надо нажать. И потому им кажется что это "проще" чем непонятная консоль без кнопок и менюшек. И что в графическом интерфейсе можно разобраться интуитивно без чтения мануалов. Но факт в том что они лишь научились повторять действия в видео, а сам гит так и не изучили. И статью выше про ветки они вряд ли осилят.
От таких людей в команде проблемы. Они избегают веток, мерджей, тем более конфликтов (и например предпочитают вместо этого вручную копировать файлы) и это влияет и на их производительность, и способность разбираться в сложных ситуациях. Или они могут закоммитить что-то лишнее, так как не очень понимают, что происходит. Не умеют сравнить разные ветки и увидеть кто, что и где поменял.
Чтобы участвовать в командной разработке, надо полноценно владеть гитом. И чтобы пользоваться гитом в IDE, надо все равно его изучить сначала на примере командной строки.
Конфликты руками я не предлагаю разрешать, удобнее конечно использовать GUI программу для просмотра и выбора изменений. Но опять же, человек, не знающий гит, в ней не разберется.
> Ну как. Делаешь свой сервис, по пути какой-то мелкий баг фиксанул в чужом и сразу закоммитил-отправил. Вполне себе обыкновенная ситуация.
Если это разные репозитории то проблем никаких нет и нет нужды коммитить только часть файлов. Гит-репозитории можно вкладывать друг в друга и все должно корректно работать.
> Опять же: зачем пердолиться в консоли,
Это надо делать на этапе изучения гита чтобы работать с гитом напрямую, не изучая как представляет информацию из гита GUI. Если ты уже изучил гит то это не требуется. Но проблема в том, что люди просто не хотят изучать гит и думают что раз там GUI, то можно разобраться "интуитивно". Будь моя воля, я бы таких отправлял учиться прежде чем приступать к работе (но тут встает другая проблема, с нынешним качеством разработчиков придется кучу кандидатов отсеять. Мы все-таки должны решать задачи бизнеса, и не знающий гита разработчик решает их лучше, чем отсутствующий разработчик).
> Лучше пояснить за архитектуру приложения: слой доступа к данным, слой сервисов, туда-сюда, чем играться с кошками-мышками.
Сначала надо научиться создавать и работать с объектами, а потом к слоям переходить. И кошки-мышки тут хорошо подходят, так как сразу не очевидно как там правильно код разбить на классы.
А перейти от класса-кошки к модели или сервису не так и сложно. По идее этим люди занимаются в задаче про студентов.
>>850742
В программировании подход "смотри как делают другие и делай так же" не работает. И "объяснения для слесарей" тоже.
В твоем списке концепций, к сожалению, много непонятных для начинающего слов. И я не думаю что цель ООП в первую очередь в тестировании кода, а в разделении на слабосвязанные части, которые можно читать/править независимо от других, что позволяет бороться со сложностью в большиз программах.
Знакомый твой (судя по описанию) ООП не знает, а только умеет писать классы "по аналогии".
>>850744
Я думаю с сервера надо возвращать id или ссылку на файл, а то как ты сделаешь перенаправление на нужную страницу?
> Вопрос: актуально ли сейчас делать два загрузчика, один на js, другой стандартный? На случай, если в каком-то браузере будет отключён JS (и прописывать его в <noscript>)
Как начинающему, да, надо бы сделать. Во-первых, во время обучения надо ставить себе задачи сложнее, а не проще, во-вторых, безяваскриптовый код поможет тебе если например в JS будет ошибка.
noscript там не нужен, надо просто при отсутствии JS/отсутствии в браузере нужных фич отправлять обычную форму с файлом. Ну например, можно показывать обычный файловый инпут в таком случае. А при наличии поддержки - превращать этот инпут в поверхность для приема перетаскиваемых файлов и кнопку выбора файла.
2 загрузчика не нужны, я думаю, что можно серверный скрипт написать так, чтобы он принимал и обычные, и аякс загрузки. Тут вообще много усилий для фоллбека на обычную загрузку, на мой взгляд, не требуется.
Не используй билиотеку как черный ящик. Ты должен понимать как она устроена внутри и какие принципы использует. И соответственно, какие особенности и ограничения из этого вытекают. Какие браузеры и в каких условиях поддерживаются. И ты должен уметь при необходимости уметь разобарться в ее коде, чтобы найти причину бага, или способ как-то нестандартно ее подключить.
Соответственно, если например что-то не работает и файл не загружается - ты должен знать все нужные инструменты и способы для поиска причин проблемы. Не менять опции наугад.
Чтобы скрипт скопировать с гитхаба - ума много не надо, этим пусть верстальщики занимаются, а программист должен знать больше.
Я думаю что работодателю больше всего бы понравится человек, который основательно во всем разбирается, но в нерабочее время. У многих анонов все равно пока работы нет - пользуйтесь возможностью.
Я тут мельком глянул библиотеку и мне она не очень нравится. Вот например:
https://github.com/danielm/uploader/blob/master/src/dmuploader.js#L286
$(document).on('dragenter', function (e) { e.stopPropagation(); e.preventDefault(); });
Ты видишь, в чем тут проблема? Ну-ка подумай (подсказка: проблема не в самой строчке, а в месте, где она стоит).
Также, глянь конструктор и скажи - не видишь ли чего странного?
https://github.com/danielm/uploader/blob/master/src/dmuploader.js#L38
https://github.com/never3ver/students_list
Ты просил напомнить, что почти все готово и оставалось только несколько мелких багов.
> noscript там не нужен, надо просто при отсутствии JS/отсутствии в браузере нужных фич отправлять обычную форму с файлом. Ну например, можно показывать обычный файловый инпут в таком случае. А при наличии поддержки - превращать этот инпут в поверхность для приема перетаскиваемых файлов и кнопку выбора файла.
А как проверить отсутствие JS, кроме как не noscript'ом?
Есть вероятность попасть в одну аутсорс-компанию из области IT на собеседование на должность PHP-разработчика.
Единственное что сказали: "Посмотри в сторону DOM и подобного", однако, я так и не понял что именно надо посмотреть.
Базовые навыки есть, с MySQL работать умею, с гуглом могу решить кучу задач.
Что могут спрашивать на собеседовании? Какие ресурсы почитать, на что сделать упор? Помогайте, аноны.
https://gist.github.com/codedokode/ce30e7a036f18f416ae0
// почле чего объект выкилдывается
>>851248
Про вот этот дом: https://ru.wikipedia.org/wiki/Document_Object_Model
А тут есть задачки от ОП'а сам только начал читать: https://gist.github.com/codedokode/ce30e7a036f18f416ae0
http://ideone.com/2L6mxQ
12
>$random = array_rand($word1);
>$randomText = $word1[$random];
>$a[] = $randomText;
И эта копипаста повторяется раз шесть, Карл!
И тут лишнее телодвижение:
>$random = array_rand($word1);
>$a[] = $word1[$random];
Используй цикл, тут иначе и нельзя, ведь задача на закрепление циклов.
Всё то, что отличается лишь цифрами на концах переменных, может быть помещено в цикл, в котором при итерации будет изменяться $i, подставляясь в нужные места.
?
Спасибо. Немного не могу понять какой цикл использовать, подскажи пожалуйста
Все разобрался. Изначально использовал этот цикл но у меня почему то брало слова из одного массива
Я сам еще не сделал, отходил от компа. Просто увидел твой ответ
Ананасики, а у вас телеграмооконфа есть?
>Можно ли запомнить весь код одного из современных фреймворков?
Да.
>Или понять и запомнить принципы построения всей системы?
Да.
>Насколько это возможно для средне-статистического программиста?
Дело в том, что никто этого не делает. Есть задача, есть фрэймворк. Берёшь и ищешь как решить задачу. Ты не учишь весь фрэймворк. Ты даже для задачи ничего не учишь. Сделал, забыл, надо снова - вспоминай. Сейчас фрэймворков очень много, трабования к программисту - вагон. Запоминать всё не нудно и физзически невозможно. Но этого и не требуется!
https://ideone.com/0XIC91
В общем, я начал проситься в кому-то на стажировку и мне предложили бесплатный стаж 3 месяца, меня будут обучать, а потом возьмут на работу.
В принципе угнетает, то, что придется работать бесплатно и юзают не популярные фреймворки, так еще и в жопе находятся, но есть один плюс, что у них, вроде как, интересные проекты есть и фирма довольно таки популярная, на практику буду устроен официально.
Что думаете?
Там в принципе убирать особо нечего, только запутаннее будет.
>>851349
Он имеет в виду, что первые 2 строки формируются одинаково, и, значит, код, который их выводит, можно засунуть в цикл из 2 шагов.
>>851455
Нет
>>851464
Зазубривать не надо. Надо разобраться, по каким принципам он построен, почему сделано так, какая архитектура. Чтобы понимать, что с ним можно сделать, а что нет.
Если ты понимаешь ООП и архитектуру то и сам при желании сможешь написать что то похожее. Если нет - сиди, ковыряй, изучай, рисуй схемы и связи классов. Со временем, я думаю, разберешься. Если что-то будет непонятно - задавай вопросы.
>Там в принципе убирать особо нечего, только запутаннее будет.
Ну вот так можно: http://ideone.com/zzIp8I
Я немного увяз в фреймворке, кажется, стал забывать.
да не буду я, блять, учиться по 8 часов, даже если себя заставлю, мой мозг расплавится просто от такой нагрузки, имеется ввиду именно продуктивное обучение, а не когда ты через силу и лень сидишь все время
Никто никогда 8 часов не высидит. 3-4 часа, да и то если есть знания и просто реализуешь что нужно, а не бьешься башкой об стену, стараясь вникнуть в какую-нибудь хуйню.
Штоэто? Зачем?
есть такое , но оно всё равно синхит по фтп или сфтп , проще написать скрипт который будет тянуть каждые 15 мин git pull на сервере , а с пеки будешь делать пуши
Погоди, погоди. Синхить по фтп или сфтп - не проблема. Проблема именно в том, что надо эти фтп вручную подключать. Было бы прекрасно делать это прямо из PHPstorm...
>написать скрипт который будет тянуть каждые 15 мин git pull на сервере
git pull можно настроить на ftp? Елси да, бугу в этом направлении идти.
25
Написал недавно трекер по отслеживанию этого дела, выходит от 4-до 6 часов в день. Но я ньюфаггет.
А что, сложного? Написал простенькую страничку с кнопочками (Начал кодить, закончил кодить). Ну и статистику прикрутил. Всё это на MySQL крутится. Просто, зато функционально. Очень хорошо показывает сколько времени я груши околачиваю.
Задачка про доллары
http://ideone.com/86CmmQ
Игра в кубики
http://ideone.com/OjJpCM
Миллион в банке
http://ideone.com/93sy0B
Школьник и кредит на айфон
http://ideone.com/AuZYfX
в последнем много выводимой информации. Но надеюсь что это не будет проблемой.
>А что, сложного?
Зарыдал в голос с тебя...
(То есть там у тебя что-то вроде блокнота, куда сам записываешь, сколько времени на что потратил?)
>>852056
>Задачка про доллары
Хорошо.
>//(если одинаковая — победила дружба)
>elseif ($sumManThrow = $sumAIThrow)
Что означает один символ равенства, и сколько символов равенства должно быть, когда нужно сравнить одну переменную с другой?
>Миллион в банке
>строки с конкатенацией
Ну, вроде не новичок, хорошо.
>Школьник и кредит на айфон
>$worthMoney= $worthMoney+$mounthlyPayment;
Вот это повторяется, можно избежать. А так задача решена верно.
>функция округления
Не новичок не палится! Хорошо, молодая кровь.
>простенькую страничку с кнопочками
Ты что каждый раз сам нажимал на копочки когда приступ\заканчивал работать?
>Что означает один символ равенства, и сколько символов равенства должно быть, когда нужно сравнить одну переменную с другой?
Два. Но там видно выше что всё правильно, тут просто опечатка.
>строки с конкатенацией
>Ну, вроде не новичок, хорошо.
Я на делфи немного умею ещё.
>Вот это повторяется, можно избежать. А так задача решена верно.
А как? Неужели можно просто
>$worthMoney= +$mounthlyPayment;
>функция округления
Я погуглил как округлять числа.
Мне больший функционал пока никчему. К тому-же ньюфаг больше и не умеет писать. Но с задачей справляюсь. Раньше писал от силы 20-40 строк кода в день вообще.
>А как? Неужели можно просто
>>$worthMoney= +$mounthlyPayment;
Можно так - просто вынести эту строку за пределы условий, оставив в цикле, и в этом случае в одном из условий $mounthlyPayment при последнем платеже просто должна становиться равной $oversum.
>$mounthlyPayment при последнем платеже просто должна становиться равной $oversum.
Не совсем понимаю тебя. Она и так при последнем платеже равна $oversum.
Можно строку $worthMoney= +$mounthlyPayment; вынести за пределы условий в цикле, а при последней итерации в условии с ($oversum < 5000) внутри условия делать $mounthlyPayment равной $oversum.
Так сократится код и мои параноидальные стремления будут удовлетворены.
>Можно строку $worthMoney= +$mounthlyPayment; вынести за пределы условий в цикле,
13 месяцев же получится просто 5000 * 13 если выводить из условия...
> при последней итерации в условии с ($oversum < 5000) внутри условия делать $mounthlyPayment равной $oversum.
Это уже было сделано до того как ты предложил. Прочитай же внимательнее.
Ну, там и в верхней строке с подчёркнутой $oversum можно сократить многое.
Ну ладно, задача правильно решена, хотя и неудовлетворёнными остаются параноидальные стремления: я бы сократил вдвое там всё.
Средняя оценка.
http://ideone.com/1ELpFU
Сколько выше анона человек
http://ideone.com/I9STv2
Ответ на любой вопрос
http://ideone.com/885RFf
Когда нужно сравнить строку по какому-то шаблону нужно применять регулярные выражения
нет пулл на фтп не настроить , я думал в 2016 у всех есть VPS как мин , ок вот инфа по синху
https://confluence.jetbrains.com/display/PhpStorm/Sync+changes+and+automatic+upload+to+a+deployment+server+in+PhpStorm
>Есть ли статья, в которой собраны случаи когда можно применять регулярки, и когда лучше обойтись без них?
Всегда лучше обходиться без них. До HTML5 например 99.9% сайтов неправильно валидоровали почту (по стандарту можно в мэйле иметь кучу всего что те отсеивали).
И вообще
Сперва у нас была проблема. Мы решили её решить при помощи регулярных выражений.
Теперь у нас 2 проблемы.
Спасибо няша.
Интересно кстати решить эту задачу на PHP.
да , но в большинстве фреймворков оно ешё обмазывается патерном роутер и считай это входная точка когда например ты вводишь в браузере site.io/controller/action
Спасибо. А я этот момент упустил, и хуй знает сколько мучаюсь. Еще вопрос - а можно ли делать шаблонизацию по простому просто передавая в шаблон переменные, или это дурной тон? А то много всяких дополнений, какие-то твиги и прочее, не хочется еще и с ними возиться.
Где можно толково про роутер почитать?
Везде какая-то перда.
Я правильно понимаю: какой controller и action ты ввёл в URL - то и получил?
>А то много всяких дополнений, какие-то твиги и прочее, не хочется еще и с ними возиться.
Так это же удобнее на порядок.
>>852297
>Где можно толково про роутер почитать?
Конкретные реализации зависят от используемого фреймворка. Но суть приблизительно такое: ты задаешь маппинг путей на методы и всё.
"projectFolder":"/students/public"
или
"projectFolder":"/students/public/"
Просто в консолях пишется "D:/path/to/folder", а в браузере "http://site.ru/path/to/public/"
и я не знаю, что взять за стандарт, а от этого зависит, как будет написан Router
Удваиваю вопрос, но знаю что это нужно настраивать в своей ide, чтобы на tab был отступ пробелами.
Хочу сказать, что я начал замечать отступы пробелами когда начал учить js. Поэтому у меня появляться вопрос: А стоит ли нам идти на поводу у js-господ\блядей?
>можно передать в качестве свойств класса по факту сколько хочешь свойств внутри массива
Напиши пример кода плз, ничего не понял что ты написал
есть стандарты , юзайте их и не забивайте голову хернёй
катите в WP если вас это интересуют , там и рост по более , и вакансий
имхо мне проще напилить с нуля
Связать свой заработок с популярностью одной единственной цмс и решениями левых пяток её разработчиков? Нет, спасибо, это как в 1С пойти.
Как я понимаю, период написания модулей для цмсок проходят многие программисты, либо в начале, либо в кризисе своей карьеры. Ну как музыканты, которые в кабаках играют. Собственно, о каком профессиональном росте может идти речь?
Например дата рождения 1990-02-06 хранится в поле Date. И таких юзеров в таблице много. Тогда чтобы получить всех юзеров с нужным возрастом нужно произвести некие манипуляции над каждой строчкой, а потом выбрать подходящих юзеров. А если таких строк в таблице очень много. Долго же будет.
Может надо хранить дату рождения как то по другому, чтобы выполнять выборку быстрее? Было бы хорошо наверное хранить возраст юзеров, но это не вариант, их возраст каждый год увеличивается.
Хранить количество лет в поле, сортировать по этому полю, в цикле обходить сортировкой всех юзеров, прибавляя/отнимая один год.
Оптимизация скорости работы.
При этом менять возраст выражением тогда, когда наступает день рождения, ну ты понял.
Мне каждый год придется увеличивать количество лет у юзеров. И не у всех разом, а каждый день рождение каждого.
Да. А как ещё?
Текущая дата минус год рождения. Активировать при условии, что сегодня его день рождения.
Костыль. Мне нужно правильное решение, оптимизированное под большие объемы.
Разумеется хранить как дату, то есть как тип DATE (не DATETIME!). Выгоднее хранить всегда исходные данные, а не вычисленные.
Выборка делается по birthday BETWEEN, с индексом.
Конкретно твой случай разбирают в учебнике:
http://www.mysql.ru/docs/man/Date_calculations.html
>>852526
Он прав. Изучайте само программирование, а не умение настроить инструмент.
>>852373
Отображается по-разному а разных программах, ьяжело отличит от пробела. А чем хороши табы? Менять вид кода по идее можно и бех них.
Стандарта нет, но обысно слеш это разделитель имен каталогов, соответственно в конце его не должно быть как и после имеги файла.
Можно сделать, чтобы поддерживались оба варианта, с помощью trim().
>>852374
Вообще нет. Надо сделать несколько отдельных свойств, так как ты только усложняешь код не получая выгоды. Хранить массивом можно олько если они всегда вмесие передаются и обрабатываются. Но в этом случае стоит подумать, не замегить ли их на объект.
Between в монй версии позволяет задействовать индекс. Если надо из миллиарда отобрать десять, будет быстро.
Там проблема была не в регулярках, а в неправильном алгортитме. Регулярки это спецтальный язык (DSL) для поиска и замены строк, и он эффективнее обычного кода.
>>852205
Скорее всего надо делать либо скрипт либо поискать в пхпсторм опцию ввгрузки по требованию. Также, не используйте фтп так как он передает все, включая пароли, в открытом виде. NSA радо.
Хочу понять как собственно работает весь шаблон, а нем есть две среды разработки и два приложения backend, frontend и папка common с общими моделями, mail-ом и виджетами.
также большое количество конфигов, которые унаследуются друг от друга.
Знаете ли какие-то туториалы, пусть и на англ, но что бы я смог почитать и разобраться во всем этом?
буду рад любым ссылкам и советам по этой теме.
$rand = rand(1,2);
$var1 = "...";
$var1 = "...";
$var1 = "...";
$var2 = "...";
$var2 = "...";
$var3 = "...";
etc...
Исходники + документация. Не осиливаешь - рано полез во фреймворки.
У начальства появилась идея создать клон сайта, но с немного отличающимся контентом.
То есть одинаковая (или одна и та же?) база, одинаковая структура кода и верстка.
Но в отдельных таблицах в отдельных полях разные данные. (Да, правильно было бы переделать структуру базы и тонны завязанного на ней кода, но на это не дадут времени)
Какие есть варианты? Продублировать поля в таблицах не очень хорошо, потому что если взлетит, клонов наклепается больше одного, соответственно будут сотни полей в таблицах.
Если использовать разные бд с одной схемой, то нужно следить за их согласованностью (большая часть данных одинаковая).
Как здесь лучше поступить?
Таб отображается в каждом редакторе по разному, если отображается вообще. 4 пробела - это везде 4 пробела.
Произошло что-то прикольное, но я не понимаю почему.
Раньше <a href=''></a> не содержал в себе ничего, а <a href='main'></a> перенаправлял на 'edit'
Я делал <a href='<?=$router->makeUrl('main')?>'>Редактировать</a> который брал из конфига путь к public и добавлял к нему экшн
И ссылка становилась 'localhost/students/public/main'
Теперь
<a href=''></a> направляет на текущую страницу если мы на localhost/students/public/main?page=1&sortBy=name&orderBy=desc? то на неё и направляет
А <a href='main'></a> направляет на 'localhost/students/public/main'
И получается makeUrl больше не нужен. И вообще всё лаконично и классно.
Я не понимаю с чего такая перемена, т.к. какой код в Router'е не пиши, это ни как не может повлиять на <a href=''></a>
"Ознакомился с массивами" это уровень человека, который только-только научился в циклы и функции, ты ему предлагаешь сразу объекты юзать?
>>852729
Ты, видимо, хочешь применить Active Record. Почитай у ОПа что такое модель, у тебя это будет не один класс. В пасте по студентов всё же написано.
>>852725
В БД у него хранится дата рождения, а не возраст.
Вообще, как я понял, на php один дебагер - xdebug?
И какой бы я редактор или иде я не использовал, мне придётся ставить его?
В пхпшторм его тоже нет из коробки?
Как вы дебажете?
Надо различать бекенд и фронтенд (интерфейс) дебаггера. xdebug - это бекенд. Это модуль, который встраивается внутрь php на сервере, и при поступлении запроса при включенной отладке он открывает порт и ждет подсоединения от клиента. После чего предоставляет клиенту возможность управлять выполнением скрипта.
Для подсоединения к xdebug используют программу-клиент. Можно конечно и без него, в консоли вручную подсоединится и писать команды, но это будет очень неудобно.
К sublime3 вроде бы есть плагин который может быть клиентом, но, когда я его тестировал, он был крайне глючный.
Поискать клиенты можно по словам xdebug client, xdebug GUI client.
Например в phpstorm встроен клиент.
> И какой бы я редактор или иде я не использовал, мне придётся ставить его?
Да, на сервере надо установить xdebug. В дебиане это делается например 1 строчкой с apt-get install php5-xdebug если я не путаю + может что-то в конфиге подправить.
>>852724
Это если он пропускает ООП и берется сразу за XML (чему увы учат некоторые учебники). Я тоже на эту тему думал, разделить урок про ООП, выделить из него ту часть где объекты используются как структуры, и переставить сразу после массивов. Чтобы люди успели познакомиться с объектами раньше чем услышат что ООП - это сложно.
Массивы правда имеют преимущество, что код быстрее пшется, не надо класс писать. Но зато код менее понятный и хуже поддерживаемый.
>>852729
А читал ли ты урок про ООП? Наследовать можно только однотипные классы. Класс с методами работы с БД нельзя наследовать от PDO. От PDO можно унаследовать разве что "улучшенный PDO", с какими-то дополнительными методами.
И модель (как часть MVC) состоит не только из работы с БД. Там еще скорее всего будет класс, представляющий 1 студента (который тоже называют моделью студента, что добавляет путаницы), и класс-валидатор для проверки данных студента.
>>852730
Запрос BETWEEN там пишется элементарно и с датой рождения.
>>852726
Читал урок про относ. ссылки? https://github.com/codedokode/pasta/blob/master/network/urls.md
Пустая ссылка ведет на ту же страницу, где она размещена.
>>852721
Лучше избегать дублирования, как огня. Ты потом озвереешь от необходимости вносить изменения в 2 копии кода, особенно когда они слегка различаются.
Так что лучше придумать как-нибудь, как избежать дублирования и в базе и в коде, добавить функцию или переменную например для выбора таблицы или колонки или названия БД или еще чего-нибудь.
>>852710
В Слиме - это код, который вызывается до и после обработки запроса. Он может что-то делать с запросом и ответом, например:
- логгирование (какой запрос пришел, код ответа, число байтов в ответе)
- авторизация (например HTTP-авторизация с HTTP кодом 401)
- шифрование/подпись кук прозрачно для самого приложения (оно видит уже расшифрованные куки)
- какую-то обработку URL, напримепр редиректы или замены или выбор языка в зависимости от URL
- какая-то обработка ответа. Ну например, можно сделать ссылку, при нажатии которой весь текст страницы становится транслитом, с помощью middleware.
Если хочешь, можешь сделать например middleware, делающее прозрачное шифрование-расшифровывание кук или транслит (при добавлении в ссылку ?translit страница выводится транслитом. При этом выбор запоминается в куках)
Надо различать бекенд и фронтенд (интерфейс) дебаггера. xdebug - это бекенд. Это модуль, который встраивается внутрь php на сервере, и при поступлении запроса при включенной отладке он открывает порт и ждет подсоединения от клиента. После чего предоставляет клиенту возможность управлять выполнением скрипта.
Для подсоединения к xdebug используют программу-клиент. Можно конечно и без него, в консоли вручную подсоединится и писать команды, но это будет очень неудобно.
К sublime3 вроде бы есть плагин который может быть клиентом, но, когда я его тестировал, он был крайне глючный.
Поискать клиенты можно по словам xdebug client, xdebug GUI client.
Например в phpstorm встроен клиент.
> И какой бы я редактор или иде я не использовал, мне придётся ставить его?
Да, на сервере надо установить xdebug. В дебиане это делается например 1 строчкой с apt-get install php5-xdebug если я не путаю + может что-то в конфиге подправить.
>>852724
Это если он пропускает ООП и берется сразу за XML (чему увы учат некоторые учебники). Я тоже на эту тему думал, разделить урок про ООП, выделить из него ту часть где объекты используются как структуры, и переставить сразу после массивов. Чтобы люди успели познакомиться с объектами раньше чем услышат что ООП - это сложно.
Массивы правда имеют преимущество, что код быстрее пшется, не надо класс писать. Но зато код менее понятный и хуже поддерживаемый.
>>852729
А читал ли ты урок про ООП? Наследовать можно только однотипные классы. Класс с методами работы с БД нельзя наследовать от PDO. От PDO можно унаследовать разве что "улучшенный PDO", с какими-то дополнительными методами.
И модель (как часть MVC) состоит не только из работы с БД. Там еще скорее всего будет класс, представляющий 1 студента (который тоже называют моделью студента, что добавляет путаницы), и класс-валидатор для проверки данных студента.
>>852730
Запрос BETWEEN там пишется элементарно и с датой рождения.
>>852726
Читал урок про относ. ссылки? https://github.com/codedokode/pasta/blob/master/network/urls.md
Пустая ссылка ведет на ту же страницу, где она размещена.
>>852721
Лучше избегать дублирования, как огня. Ты потом озвереешь от необходимости вносить изменения в 2 копии кода, особенно когда они слегка различаются.
Так что лучше придумать как-нибудь, как избежать дублирования и в базе и в коде, добавить функцию или переменную например для выбора таблицы или колонки или названия БД или еще чего-нибудь.
>>852710
В Слиме - это код, который вызывается до и после обработки запроса. Он может что-то делать с запросом и ответом, например:
- логгирование (какой запрос пришел, код ответа, число байтов в ответе)
- авторизация (например HTTP-авторизация с HTTP кодом 401)
- шифрование/подпись кук прозрачно для самого приложения (оно видит уже расшифрованные куки)
- какую-то обработку URL, напримепр редиректы или замены или выбор языка в зависимости от URL
- какая-то обработка ответа. Ну например, можно сделать ссылку, при нажатии которой весь текст страницы становится транслитом, с помощью middleware.
Если хочешь, можешь сделать например middleware, делающее прозрачное шифрование-расшифровывание кук или транслит (при добавлении в ссылку ?translit страница выводится транслитом. При этом выбор запоминается в куках)
Вообще, для этого есть массивы, а динамические имена переменных только добавляют головную боль при попытке разоьрать код.
>>852657
массив либо if
>>852650
Есть же официальная документация, в тч на русском. Перед ее чтением желательно разобраться с ООП, MVC, и разными подходами, применяемыми в фреймворках (например для YII это ActiveRecord).
По иронии я как раз работаю в компании, которая использует самописный движок. Но для моего уровня джуниора разбраться в этой системе (довольно недурно написанной) будет как раз профессиональным ростом. А вообще нельзя узкоспециализироваться.
Ты о чём вообще, Date разве не в виде unix timestamp хранится? Если нет, то храни unix timestamp, базарю, это лучше всего. Целое число, легко провести арифметические операции. Вон даже вконтактик таймстэмп хранит, а у них оптимизация ого-го.
Модель - хранит данные(например студента, книгу, прочий товар), записывает/удаляет/изменяет информацию о них в БД, возвращает объекты оных.
Представление - сохраняет шаблон, вписывает в него информацию для вывода(т.е. объекты от модели), выводит шаблон. Не создает данные как таковые, только получает их.
Контроллер - скрипт, который оперирует моделью и представлением. Т.е. в нем создаются объекты, вызываются их методы и по факту запускается приложения.
Я правильно понял суть MVC?
В базе данных есть спенцмальный тип для хранения дат/времени и операции для работы с ним. Не занимайся велосипедостроением.
unix timestamp имеет немало своих недостатков, например, не хранит часовой пояс и плохо годится для исторических дат, когда были разные календари и смещения.
Модель - это классы, отвечающие за логику работы с данными. Без отображения или взаимодействия с пользвоателем.
Вью - отображает данные (это обычно шаблон)
Контроллер - принимает запрос пользователя и вызывает нужные ему для обработки модели и вью для вывода.
К одной модели можно приделать несколько интерфейсов для работы с данными, и соответственно несколько контроллеров/вью.
>Контроллер - принимает запрос пользователя и вызывает нужные ему для обработки модели и вью для вывода.
Имеется ввиду ссылка, пост-запрос? Типа в контроллере ссылка/запрос разбирается и вызывается нужный метод модели, потом эти данные передаются в представление и выводится нужный шаблон?
Спасибо, анонасец за разъяснение.
А теперь проясни мне, как сделать так, чтобы хdebug заработал?
В phpinfo(); его нет
Вот настройки, что в них поменять надо?
[Xdebug]
;zend_extension="%sprogdir%/modules/php/%phpdriver%/ext/php_xdebug.dll"
;xdebug.default_enable = 1
xdebug.auto_trace = 0
xdebug.collect_includes = 1
;xdebug.collect_params = 4
;xdebug.collect_return = 1
;xdebug.collect_assignments = 1
;xdebug.collect_vars = 1
xdebug.dump.REQUEST =
xdebug.dump.SESSION =
xdebug.dump.SERVER = REMOTE_ADDR,REQUEST_METHOD
;xdebug.dump.COOKIE =
;xdebug.dump.FILES =
;xdebug.dump.GET =
;xdebug.dump.POST =
xdebug.dump_globals = 1
xdebug.dump_once = 1
xdebug.dump_undefined = 1
xdebug.extended_info = 1
;xdebug.file_link_format = ""
;xdebug.idekey = ""
;xdebug.manual_url = "http://www.php.net"
xdebug.max_nesting_level = 256
xdebug.overload_var_dump = 1
;xdebug.profiler_append = 1
xdebug.profiler_enable = 0
xdebug.profiler_enable_trigger = 0
xdebug.profiler_output_dir="%sprogdir%/userdata/temp/xdebug/"
xdebug.profiler_output_name = "cachegrind.out.%H%R"
;xdebug.remote_autostart = 0
;xdebug.remote_enable = 1
;xdebug.remote_handler = "dbgp"
;xdebug.remote_host = "localhost"
;xdebug.remote_log = "none"
;xdebug.remote_mode = "req"
;xdebug.remote_port = 9000
;xdebug.scream = 1
;xdebug.show_exception_trace = 0
;xdebug.show_local_vars = 1
;xdebug.show_mem_delta = 1
;xdebug.trace_format = 1
;xdebug.trace_options = 1
xdebug.trace_output_dir = "%sprogdir%/userdata/temp/xdebug/"
;xdebug.trace_output_name = "trace.%H%R"
xdebug.var_display_max_children = 256
;xdebug.var_display_max_data = 1024
xdebug.var_display_max_depth = 16
;xdebug.remote_cookie_expire_time = 3600
Спасибо, анонасец за разъяснение.
А теперь проясни мне, как сделать так, чтобы хdebug заработал?
В phpinfo(); его нет
Вот настройки, что в них поменять надо?
[Xdebug]
;zend_extension="%sprogdir%/modules/php/%phpdriver%/ext/php_xdebug.dll"
;xdebug.default_enable = 1
xdebug.auto_trace = 0
xdebug.collect_includes = 1
;xdebug.collect_params = 4
;xdebug.collect_return = 1
;xdebug.collect_assignments = 1
;xdebug.collect_vars = 1
xdebug.dump.REQUEST =
xdebug.dump.SESSION =
xdebug.dump.SERVER = REMOTE_ADDR,REQUEST_METHOD
;xdebug.dump.COOKIE =
;xdebug.dump.FILES =
;xdebug.dump.GET =
;xdebug.dump.POST =
xdebug.dump_globals = 1
xdebug.dump_once = 1
xdebug.dump_undefined = 1
xdebug.extended_info = 1
;xdebug.file_link_format = ""
;xdebug.idekey = ""
;xdebug.manual_url = "http://www.php.net"
xdebug.max_nesting_level = 256
xdebug.overload_var_dump = 1
;xdebug.profiler_append = 1
xdebug.profiler_enable = 0
xdebug.profiler_enable_trigger = 0
xdebug.profiler_output_dir="%sprogdir%/userdata/temp/xdebug/"
xdebug.profiler_output_name = "cachegrind.out.%H%R"
;xdebug.remote_autostart = 0
;xdebug.remote_enable = 1
;xdebug.remote_handler = "dbgp"
;xdebug.remote_host = "localhost"
;xdebug.remote_log = "none"
;xdebug.remote_mode = "req"
;xdebug.remote_port = 9000
;xdebug.scream = 1
;xdebug.show_exception_trace = 0
;xdebug.show_local_vars = 1
;xdebug.show_mem_delta = 1
;xdebug.trace_format = 1
;xdebug.trace_options = 1
xdebug.trace_output_dir = "%sprogdir%/userdata/temp/xdebug/"
;xdebug.trace_output_name = "trace.%H%R"
xdebug.var_display_max_children = 256
;xdebug.var_display_max_data = 1024
xdebug.var_display_max_depth = 16
;xdebug.remote_cookie_expire_time = 3600
пиздец у меня голова распухла, в пхпинфо теперь есть хдебаг, а как его блять в сабайме настроить - это же пиздец
"folders":
[
{
"path": "..."
}
],
"settings":
{
"xdebug": {
"path_mapping": {
"/absolute/path/to/file/on/server" : "/absolute/path/to/file/on/computer",
},
"url": "http://your.web.server/index.php",
"super_globals": true,
"close_on_stop": true
}
}
}
нашёл вот такую инструкцию, только я нихуя не понимаю, что в пути писать
Вот у меня есть файл 1.php, который я хочу отлаживать, который находится в D:\Folder
В качестве сервера установлен Open Server
>D:\Folder
>В качестве сервера установлен Open Server
кидай в папку openserver. У него это папка domains там создай папку со своим проектом, ребутай опенсервер, выбирай в его меню проект, и браузер запустит твой 1.php
<?= "Имя не должно быть длиннее 90 символов, а вы ввели {htmlspecialchars($errors->get('nameLength'), ENT_QUOTES)}"; ?>
выдает ошибку
Notice: Undefined property: app\Errors::$get in
ЗАРАБОТАЛО БЛЯТЬ, СПАСИБО ТЕБЕ АНОНЧИЙ!!!!!!!!111111111
А можно ли как-то запускать дебаг без браузера?
Если я просто нажму стар дебагинг - ничего не происходит, если нажму с лаунч браузер, то откроется браузер с
http://myproject/2.php?XDEBUG_SESSION_START=sublime.xdebug
и дебаг работает
Для начала дай определение слова дебаг, а то я понять не могу чего ты хочешь получить в результате. Я понимаю когда C++ дебажишь. Но тут то он вообще зачем?
Класс app\Errors покажи, тут экстрасенсы собрались по-твоему?
Ты обращаешься к несуществующему свойству. МБ из-за магии в классе.
> Читал урок про относ. ссылки?
В своё время пропустил, теперь всё стало понятно
Я готов:
https://github.com/TheSidSpears/Students/
Единственное, ОП, прошу посмотри лично, почему у меня проблема с вызовом ConfigExeption для этого нужно, например, переименовать router.json. А то я уже отупел, что то на уровне "я думаю что x+y=4, а выдаёт 5". Хоть скажешь, в какую сторону смотреть
>Для начала дай определение слова дебаг
Возможность просмотра состояния переменных в определённом участке кода на этапе выполнения.
Я писал на C++, С#, делать даже что-то совсем простое без дебага немыслимо, если что-то работает не так, приходится искать где это, на каком этапе. А если проект большой, и ты с ним плохо знаком, и вообще не знаешь, что там в каком классе содержится, и что с ними происходит, то только отладкой это можно проследить.
В php в этом нет необходимости что ли?
>не могу чего ты хочешь получить в результате
Я привык, что в visual studio, когда я писал на C++, С#, у меня была проверка синтаксиса и отладка.
С проверкой синтаксиса - у тебя не будет глупых ошибок, компилятор при сборке проекта тоже может показать ошибки, уже не просто синтаксические, ну и в конце концов есть отладка, свои и чужие ошибки всегда можно найти и избежать.
Я привык к этому, тоже самое хотел сделать и в саблайме, я накатил сюда проверку синтаксиса и вот этот дебагер.
Но я не совсем понимаю, почему для волнения отладки нужно обязательно запускать браузер, по-другому скрипты не запускаются что ли?
>Возможность просмотра состояния переменных в определённом участке кода на этапе выполнения.
Ну я использую var_dump ($peremennaya);
>В php в этом нет необходимости что ли?
Просто в большинстве случаев без дебага справляюсь.
>Но я не совсем понимаю, почему для волнения отладки нужно обязательно запускать браузер, по-другому скрипты не запускаются что ли?
На этот вопрос пусть лучше ОП ответит. Я об этом даже не задумывался.
>Какие перспективы, возможности профессионального роста у разработчика модулей?
MVC потеряет популярность и ты тоже.
Но ведь get это метод а не свойство.
вот эта строчка не вызывает такой ошибки
($errors->get('nameForbidden')
Код класса Errors на пикриле
>private $errors = array();
Хочешь получить код который ты потом никогда не захочешь редактировать и вообще трогать?
Потому-что именно так он и получается.
Не ленись, раскрывай свою мысль полностью.
Не вижу ошибок. Ты скорее всего где-то при использовании объекта Errors забыл поставить круглые скобки при вызове метода get, вызывая метод как свойство, потому и Undefined property. Как-то так: $errors->get, то есть без скобок. Предлагаю выложить класс Errors на ideone и там уже изолированно протестировать методы get и add.
const DESC = 'DESC';
Снаружи я обращаюсь к ней $order = ClassName::DESC
затем передаю в класс переменную $order, и пытаюсь выяснить ее значение if ($order == DESC)
PHP выдает ошибку
Notice: Use of undefined constant DESC - assumed 'DESC'
Но условие работает, т.е. $order таки равен DESC.
Вопрос, ЧЯДНТ?
Внутри класса сравнивать нужно так $order == 'DESC'
или так $order == ClassName::DESC ?
Ошибка получается если я вызываю метод в таком выражении
<?= "текст {htmlspecialchars($errors->get('nameLength'), ENT_QUOTES)}"; ?>
А вот так ошибки нет:
<?= "текст" . htmlspecialchars($errors->get('nameLength'), ENT_QUOTES); ?>
Сам себе отвечаю - в мануале внутри класса к константе обращаются с помощью self::
Нельзя использовать интерполяцию для функций. При выводе строки через echo скобки {} работают только для переменных (для функций только конкатенация)
Ответьте вот этому, пожалуйста, а то мне тоже интересно.
Ответьте вот этому, пожалуйста, а то мне тоже интересно.
Спасибо
Потому что this is because ternary expressions are evaluated from left to right
http://www.php.net/ternary
мимо сеньёр-девелопер
Первое что нагуглил - симпл хтмл дом, но метод парсинга с ней мне показался несколько странным. Она создаёт объект всего дом, он же пиздец какой здоровый и это пиздец сколько памяти
ссылка обычно разбирается либо в роутером (если это красивые УРЛ) либо веб-сервером (если она вида /register.php).
После этого вызsвается нужный контроллер - его задача - обработать запрос пользователя и выдать ответ.
>>852812
не думаю.
>>852813
Там есть несколько режимов работы. Есть режим, когда xdebug при запуске php скрипт соединяется с указанным в конфиге IP и портом (где его соединение должен ждать GUI клиент). В этом случае IP с клиентом жестко прописвается в конфиге.
Есть другой режим, когда xdebug смотрит, с какого IP пришел запрос, и соединяетя с этим IP, но с указанным в конфиге портом.
Разумеется в настройках IDE должно быть выставлено, чтобы она ждала соединения на том же порту.
Но тут надо понимать, что не всегда один узел может соединиться с другим. Если у тебя "серый IP" и ты выходишь в сеть через NAT провайдера, то соединиться с твоим компьютером снаружи невозможно. В этом случае надо "пробрасывать" порт с сервера на твой компьютер, например, с помощью ssh. В этом случае xdebug коннектится сам к своему же серверу, а ssh перенаправляет данные к тебе и соединяетя с IDE у тебя (для IDE это выглядит, как будто запрос пришел со своего компьютера).
Если у тебя php запущен на том же компьютере что и IDE, то проблем конечно нет.
Тебе надо понимать основы TCP/IP (например что такое порт) и прочитать мануал https://xdebug.org/docs/remote . Увы, на англ.
> А теперь проясни мне, как сделать так, чтобы хdebug заработал?
Почитай мануал по всем директивам в конфиге и выбери нужные значения
ссылка обычно разбирается либо в роутером (если это красивые УРЛ) либо веб-сервером (если она вида /register.php).
После этого вызsвается нужный контроллер - его задача - обработать запрос пользователя и выдать ответ.
>>852812
не думаю.
>>852813
Там есть несколько режимов работы. Есть режим, когда xdebug при запуске php скрипт соединяется с указанным в конфиге IP и портом (где его соединение должен ждать GUI клиент). В этом случае IP с клиентом жестко прописвается в конфиге.
Есть другой режим, когда xdebug смотрит, с какого IP пришел запрос, и соединяетя с этим IP, но с указанным в конфиге портом.
Разумеется в настройках IDE должно быть выставлено, чтобы она ждала соединения на том же порту.
Но тут надо понимать, что не всегда один узел может соединиться с другим. Если у тебя "серый IP" и ты выходишь в сеть через NAT провайдера, то соединиться с твоим компьютером снаружи невозможно. В этом случае надо "пробрасывать" порт с сервера на твой компьютер, например, с помощью ssh. В этом случае xdebug коннектится сам к своему же серверу, а ssh перенаправляет данные к тебе и соединяетя с IDE у тебя (для IDE это выглядит, как будто запрос пришел со своего компьютера).
Если у тебя php запущен на том же компьютере что и IDE, то проблем конечно нет.
Тебе надо понимать основы TCP/IP (например что такое порт) и прочитать мануал https://xdebug.org/docs/remote . Увы, на англ.
> А теперь проясни мне, как сделать так, чтобы хdebug заработал?
Почитай мануал по всем директивам в конфиге и выбери нужные значения
Лучше бы ты не использовал сборку, а ставил все руками так как мануалы рассчитаны именно на стандартную установку. Но можно конечно и в опенсервере разобраться.
Что такое path_mapping, можно прочесть в мануале https://github.com/martomo/SublimeTextXdebug
>>852858
Судя по всему ошибка из-за того что при подстановке в строку нельзя использовать сложные выражения и вызов функций. Твой код интерпретироовался как
текст + $error->get + текст
Отсюда и ошибка.
>>852861
Чтобы отлаживать скрипт, его надо запустить - либо отправив из браузера запрос к серверу, либо запустив его в консоли.
>>852865
Затем же зачем и в си.
>>852868
Ты там exCeption и exeption не перепутал? Проверь написание названий и в правильном ли они неймспейсе.
И приведи текст ошибки.
>>852872
Из консоли можно запускать. При этом не будет значений у переменных типа $_POST['x']. параметры xdebug передаются через переменные оружения:
http://php.net/manual/ru/features.commandline.php
https://xdebug.org/docs/remote
Это допустимо для кода, который не использует параметры запроса, POST/GET, куки (так как в команной строке нет HTTP запроса - потому и всего этого нет) итд.
>>852960
Некоторые операции вполняются справа налево, наерно. Почитай мануал. И за такой код конечно руки отрывать стоит.
>>852980
Без self это не константа класса, а глобальная.
>>853130
Оптимизируй.
Лучше бы ты не использовал сборку, а ставил все руками так как мануалы рассчитаны именно на стандартную установку. Но можно конечно и в опенсервере разобраться.
Что такое path_mapping, можно прочесть в мануале https://github.com/martomo/SublimeTextXdebug
>>852858
Судя по всему ошибка из-за того что при подстановке в строку нельзя использовать сложные выражения и вызов функций. Твой код интерпретироовался как
текст + $error->get + текст
Отсюда и ошибка.
>>852861
Чтобы отлаживать скрипт, его надо запустить - либо отправив из браузера запрос к серверу, либо запустив его в консоли.
>>852865
Затем же зачем и в си.
>>852868
Ты там exCeption и exeption не перепутал? Проверь написание названий и в правильном ли они неймспейсе.
И приведи текст ошибки.
>>852872
Из консоли можно запускать. При этом не будет значений у переменных типа $_POST['x']. параметры xdebug передаются через переменные оружения:
http://php.net/manual/ru/features.commandline.php
https://xdebug.org/docs/remote
Это допустимо для кода, который не использует параметры запроса, POST/GET, куки (так как в команной строке нет HTTP запроса - потому и всего этого нет) итд.
>>852960
Некоторые операции вполняются справа налево, наерно. Почитай мануал. И за такой код конечно руки отрывать стоит.
>>852980
Без self это не константа класса, а глобальная.
>>853130
Оптимизируй.
>>848941 | http://arhivach.org/thread/197740/#848941
> А можно подсказку как решать эту задачу?
Надо просто очень тшательно обрабатывать список аргументов, чтобы в нем не было ничего лишнего.
> должна подставлять лишние аргументы в конец списка: partialAny(fn, 1)(2, 3) -> [1, 2, 3] //(2, 3) - что это?
partialAny(fn, 1)(2, 3) - это запись такого кода одним выражением:
var t = partialAny(fn, 1);
t(2, 3);
То есть функция возвращает функцию, и мы ее вызываем.
Ответ полностью тут http://pastebin.ru/yLh80hF8 (спам лист)
если я вас пропустил - напомните о себе.
>>849015 | http://arhivach.org/thread/197740/#849015
> arg.join === undefined
правильнее было бы join in arg. Хотя мне не нравится такой способ определения массива - метод join может быть у псевдомассива тоже.
Псевдомассив - это не массив, а объект у которого есть свойства length >= 0 и 0 .. N. Например: { 0: true, 1: true, length: 2 }
> for (var [expected, test] of testcases) {
Мой хромиум отказывается интерпретировать. Видимо нужен очень уж новый JS с декомпозицией значений.
В общем, выглдяит верно, только проверку на array-like надо допилить без проверки на join. Отсеять настоящий массив можно по [object Array]
в остальном, все правильно.
>>851568 | http://arhivach.org/thread/197740/#851568
Ну теперь ты точно задачу про кредит с первого раза должен решить с такой то удачей.
Но ведь буквы T нет в слове horse. Или он срабатывает потому-что там feet?
>>853158
> Некоторые операции вполняются справа налево, наерно. Почитай мануал. И за такой код конечно руки отрывать стоит.
Если ты про форматирование - это PHPstorm отказался по другому. Если про исходник - писал не я, у меня такое-же мнение. Просто сложность кода которая возникла изниоткуда, в результате и читать тяжело и понять что он должен делать трудно. Автор сам на свои же грабли наступил.
Я не про форматирование, а про то что код тяжело читать. тут однозначно должен быть блок if/esleif.
Ничего. Продолжай рассылать резюме.
На собеседовании тебя будут хуесосить, чтоб твои зарплатные ожидания сбить, потому хуесось их в ответ. Поспрашивай как их наебизнес поживает, может они концы с концами еле сводят. Как с текучкой кадров в конторе - почему вакансия висит, что с прежним разработчиком и если он уволился, то почему. Бывают ли задержки зп, как сверхурочки оплачиваются, че там с индексацией зарплат. Если оформление не по тк, то спроси когда на тк перейдут - мол солидной фирмой тебе показались, а тут на тебе.
Цени себя. Если зовут, то нужен.
У тебя таких собеседований будут ещё сотни.
Во всём так, Люк, поступай, чтобы не было мучительно больно за упущенные возможности потроллить.
Ну а вообще смотри просто на людей, тебе же с ними работать, у них учиться.
>Возможно ли обазмазать тот же саблас или нотепад++ плагинами что бы они не уступали IDE, или же лучше терпеть тормоза?
Саблайм ставь. И будет тебе счастье. По большому счёту всякие плагины на него - это тоже не очень обязательное дело.
Я саблаймом и ползуюсь. Но хотелось бы и побольше возможностей. Например, автодополнение работает непонятно как. Не подсказывает какие аргументы ожидает функция, например. Оче хотелось бы что бы он мог видеть функции и классы с методами из моих подключенных скриптов, как делают IDE. Еще мне не хватает автоформатирования кода.
Чот не верю что PHPstorm тупит пеку. Там вроде у них гайд был, как его покрутить чтобы не тормозил. Поищи.
Ну он кстати еще и платный, лол. А я не люблю возиться с кряками. Кстати что характерно - ради сравнения запустил консольный проект C# на визуал студии 2015 - работает вполне шустро. А пека у меня ну оче некро - одноядерный проц на 2800ггц, 2гб рам и встроенная видуха, лол.
Пальцаны, качнул вот эту библиотеку и сразу же обосрался.
Для установки DiDOM выполните команду:
composer require imangazaliev/didom
Нельзя её как-то подключить без всяких композеров?
> Нельзя её как-то подключить без всяких композеров?
Обычным require'ом класса. Не забудь свой автолоадер классов навелосипедить, раз композер нинужен.
Оказывается у меня на сервере есть композер, а что такое автолоадер -я не знаю, наверное лучше действительно через композер установить?
а перевести по словам , авто это авто , а лоудер это загрузчик , наверно авто загрузчик
я всё равно не понимаю, ибо тупой, вот на примере моей библиотеки DiDOM как им пользоваться?
вот в visual studio, когда я писал на C# я просто подключал что угодно в ресурсы, писал в своём файле инклюде пизда джигурда и всё
точнее юзинг
Счастья и здоровья твоей маме.
Лучше композер. Насчёт автозагрузчика: https://github.com/codedokode/pasta/blob/master/php/autoload.md
>>853630
C композером так же просто, когда понимаешь, что он делает.
http://ideone.com/WVEw8V
Изучи командную строку (есть гайд в ОП посте) и композер. Судя по твоим ответам, у тебя пока плоховато с теорией.
>>853619
УК почитай.
>>853636
Самый известный учебник по сетям это Олифер (книга под 1000 стр). Разбирает все последовательно с нуля.
Если неохота, то можно поискать статьи по конкретным словам. Для начала можешь взять модель OSI:
https://ru.wikipedia.org/wiki/Сетевая_модель_OSI
Затем гугли конкретные технологии:
- Ethernet
- IP
- ARP
- ICMP
- UDP, TCP
- DNS
- HTTP
- php функции socket_... и stream...
Также, у меня есть кое-что по теме:
---------------
http://pastebin.ru/KO4E1mB4
http://pastebin.ru/dnO7PZfq
http://pastebin.ru/8aEdIFeO
https://github.com/codedokode/pasta/blob/master/network/http.md
https://gist.github.com/codedokode/1af26d3a64748f05ba8b870b273edfc6
Куски из моих ответов на вопросы про сокеты и сети: https://gist.github.com/codedokode/21a432321fe7bc435dab
------------------
Ну и практические задания:
1) установи Wireshark (программа перехвата пакетов на сетевой карте), закрой все лишние программы, кроме браузера. запусти wireshark, открой в браузере любую страницу, посмотри какие пакеты будут пойманы. Учти что там обычно еще идет куча мусора от соседних узлов сети и от других запущенных программ
Если ты под линуксом, то еще можно использовать tcpdump
2) с помощью команды nslookup запроси IP сервера yandex.ru у DNS-сервера 8.8.8.8
3) с помощью tracert/traceroute и whois узнай, через какие узлы и города идут пакеты, отправляемые на адреса google.com, twitter.com, vk.com, yandex.ru (или другие сайты)
4) С помощью telnet или putty соединись с сервером yandex.ru и отправь HTTP-запрос GET / HTTP/1.0
5) Напиши на php простой echo-сервер, который слушает порт, принимает соединение и отсылает каждую принятую строчку обратно.
6) Напиши простой HTTP-клиент на php, скачивающий файл по указанной ссылке
7) Напиши простой HTTP-сервер на php, отдающий какую-то простую страницу, и протестируй его с помощью браузера. В случае затруднений можно использовать wireshark (только ловить пакеты на 127.0.0.1 скорее всего не получится, используй IP на сетевой карте, узнать его можно через ifconfig)
8) Простые программы выше были однопоточными. Напиши многопоточный сервер. Его суть такая: он принимает соединения от клиентов, и все, что напишет клиент, пересылает всем остальным (что-то вроде чата). Тебе понадобится socket_select или strea_select для этого. Тупо сделать синхронный алгоритм вроде "отправить сообщение клиенту 1, затем клиенту 2" не получится, так как при зависании одного из клентов (если он перестанет принимать пакеты) зависнет и сервер до истечения таймаута.
9) перепиши свой сервер на reactphp
10) Напиши простой многопоточный HTTP сервер на reactPHP
11) Сделай чат на вебсокетах и reactPHP
Изучи командную строку (есть гайд в ОП посте) и композер. Судя по твоим ответам, у тебя пока плоховато с теорией.
>>853619
УК почитай.
>>853636
Самый известный учебник по сетям это Олифер (книга под 1000 стр). Разбирает все последовательно с нуля.
Если неохота, то можно поискать статьи по конкретным словам. Для начала можешь взять модель OSI:
https://ru.wikipedia.org/wiki/Сетевая_модель_OSI
Затем гугли конкретные технологии:
- Ethernet
- IP
- ARP
- ICMP
- UDP, TCP
- DNS
- HTTP
- php функции socket_... и stream...
Также, у меня есть кое-что по теме:
---------------
http://pastebin.ru/KO4E1mB4
http://pastebin.ru/dnO7PZfq
http://pastebin.ru/8aEdIFeO
https://github.com/codedokode/pasta/blob/master/network/http.md
https://gist.github.com/codedokode/1af26d3a64748f05ba8b870b273edfc6
Куски из моих ответов на вопросы про сокеты и сети: https://gist.github.com/codedokode/21a432321fe7bc435dab
------------------
Ну и практические задания:
1) установи Wireshark (программа перехвата пакетов на сетевой карте), закрой все лишние программы, кроме браузера. запусти wireshark, открой в браузере любую страницу, посмотри какие пакеты будут пойманы. Учти что там обычно еще идет куча мусора от соседних узлов сети и от других запущенных программ
Если ты под линуксом, то еще можно использовать tcpdump
2) с помощью команды nslookup запроси IP сервера yandex.ru у DNS-сервера 8.8.8.8
3) с помощью tracert/traceroute и whois узнай, через какие узлы и города идут пакеты, отправляемые на адреса google.com, twitter.com, vk.com, yandex.ru (или другие сайты)
4) С помощью telnet или putty соединись с сервером yandex.ru и отправь HTTP-запрос GET / HTTP/1.0
5) Напиши на php простой echo-сервер, который слушает порт, принимает соединение и отсылает каждую принятую строчку обратно.
6) Напиши простой HTTP-клиент на php, скачивающий файл по указанной ссылке
7) Напиши простой HTTP-сервер на php, отдающий какую-то простую страницу, и протестируй его с помощью браузера. В случае затруднений можно использовать wireshark (только ловить пакеты на 127.0.0.1 скорее всего не получится, используй IP на сетевой карте, узнать его можно через ifconfig)
8) Простые программы выше были однопоточными. Напиши многопоточный сервер. Его суть такая: он принимает соединения от клиентов, и все, что напишет клиент, пересылает всем остальным (что-то вроде чата). Тебе понадобится socket_select или strea_select для этого. Тупо сделать синхронный алгоритм вроде "отправить сообщение клиенту 1, затем клиенту 2" не получится, так как при зависании одного из клентов (если он перестанет принимать пакеты) зависнет и сервер до истечения таймаута.
9) перепиши свой сервер на reactphp
10) Напиши простой многопоточный HTTP сервер на reactPHP
11) Сделай чат на вебсокетах и reactPHP
Тебе надо подучить теорию, например перечитать мой урок или мануал http://php.net/manual/ru/pcre.pattern.php
\W?\W?\W? - это можно записать короче, и мне не нравится использование \W так как она пропускает очень много символов
[7|8] - тут вертикальная черта не имеет специального смысла и обозначает саму себя.
Само выражение слишком длинное.
Советую написать так:
- в начале + 7 или 8
- за ним ровно 10 цифр, между которыми идет любое число скобок, пробелов, минусов
Ок, спасибо, завтра попробую сделать по нормальному
Вот пример кода, в котором есть перечисление свойств, которое хотелось бы избежать:
if (!empty($_POST)) {
// Необходимые значения формы для создания объекта Abiturient
$abiturientValues = array(
"name",
"lastName",
"gender",
"groupNum",
"email",
"egePoints",
"dateOfBirth",
"registry"
);
// Выбираем из $_POST нужные параметры
$values = array_intersect_key($_POST, array_flip($abiturientValues));
Как пример решения, думаю создать метод getValuesName(), получающий массив с названиями всех св-в объекта c помощью get_object_vars().
Что практикуете, что посоветуете?
Почему нет? Тут полно примеров, успешных, анонов, трудоустроившихся после выполнения задач опа.
Это не так просто, как кажется, - заниматься по 5 часов в день.
Если бы ты так смог, то ты бы на работу мидлом мог бы претендовать к лету.
А так за джуна вполне сойдёшь к этому времени, если по паре часов стабильно будешь заниматься в день.
Двачую. Одно дело учиться в универе, когда тебя гонят палками. грозят отчислением и армией. Другое дело сидеть дома и заставлять себя самому. Это тяжело в общем.
>>853817
>>853820
Спасибо за ответы
Я очень сильно постараюсь. Думаю, спокойно смогу час или два с помощью смартфона в своей шараге что-то выполнять, ну и вечер у меня весь свободен, три часа постараюсь посвятить обучению. Удачи вам всем
Можно использовать либо динамическое обращение к свойствам:
foreach ($properties as $property) {
$s->$property = ...
}
Либо метод, который это делает:
$s->setProperty($name, $value)
Или, что еще лучше, можно сделать метод, принимающий массив с данными:
$s->updateProperties(['name' => ..., 'birthyear' => ...]);
В любом случае, надо проверять, что в классе есть такое свойство. В третьем случае наверно удобнее всего это сделать, так как можно просто сделать
$formData = $_POST;
// array_map + trim
$s->updateProperties($formData);
Что-то читал недавно про Курсеру - даже у них всего лишь 15% заканчивают курсы из всех тех, кто подписывается и начинает учиться.
Нужна мотивация и выработка привычки что-то делать каждый день.
>>853832
И тебе удачи.
Начинай прямо сегодня.
На смартфоне можешь через ideone.com бОльшую часть учебника ОПа пройти, я на планшете кое-что делал так.
То, что исключение выбрасывается при отсутсвии конфига - это правильно. Только вот плохо, что оно не сохраняет причину ошибки. Это из-за того, что у тебя там написано:
parent::__construct( $message = "" , $code = 0 , $previous = NULL);
Спасибо, действительно, объекту можно передать массив с любым набором. А внутри уже реализовать метод отбора только тех значений, которые есть в самом объекте.
Также, если не хочется смотреть рекламу и зависеть от интернета, можно установить php на смартфон, но придется заморочиться. Нужны будут (их надо либо ставить по отдельности либо покупать программы, где все уже собрано):
- редактор кода
- клавиатура со спецсимволами
- php, он по моему ставится через scripting layer 4 android и его по моему нет в google play
- сервер apache (в начале не требуется, достаточно только php, тем более что в нем есть встроенный сервер)
Вообще, аноны, я наверно когда будет время попробую на своем телефоне все это поставить и написать гайд, если это кому-то нужно.
Немножко не понимаю 13ую задачу опа.
> Напиши программу, рассчитывющую, сколько электричества необходимо закупить (или можно продать) днем и ночью для обеспечения баланса и сколько это будет стоить (или принесет прибыли).
в условии задачи не указано сколько стоит мегаватт своей электростанции и батареи, а так же сколько стоит импортный мегаватт из других городов. И вообще условия какие-то расплывчатые, мало конкретики (не понятно сколько домов, например). Какой-то матанализ вообщем.
Но у тебя же есть наш тред ^^
В конфиге PHP какой memory_limit стоит?
Покажи ещё вывод функции json_last_error: https://secure.php.net/manual/ru/function.json-last-error.php
Из адекватных аналогов только обёртки над этими же json_* функциями. Зачём они такие нужны? Потому что умеют бросать исключения.
>>854119
"Более опытным товарищем" вполне может быть и книга с гуглом.
>>854027
Всё что надо новичку описано в шапке.
Так вот, к чему я: добавляйтесь в ко мне в телеграмм @oo1o1 если у кого есть желание осваивать PHP вместе. Типа как тупые телки из вк, которые совместно начинают голодание или жёсткую диету.
>телеграмм
сразуй нахуй, нужен какой-нибудт анонимный чат или форум, этот тред, думаю, вполне подойдёт
А у тебя какие скиллы?
Генерируемое и потребляемое локально электричнство как бы бесплатно (то есть потребитель платит электростанции и мы это не учитываем). Оплачивается только внешнее электричество, приходящее через ЛЭП. При этом у каждой линии своя цена и пропускная способность.
Насчет цены и количества домов - они могут быть любыми, код должен быть универсальным.
>>854039
Нулл значит ошибка, читай мануал.
Трекер заданий. Ты незнаешь значения? Маше даётся задание.
09,00 "Маша, сделай кофе".
09,15 "Кофий сделон".
Только трекер для программистов. В компании в которой программистов человек например 5, и каждый из них должен выполнять 20-30 заданий в день. Каким образом гитхаб то?
Если ты за свою розовую попку боишься, то ресурс от мылру, по дефолту нельзя называть анонимным форумом, дружок.
Одно дело логин по телефону, другое дело когда каждый член конфы палит твой номер.
Дя, может быть вопрос ньюфажный, заранее извиняюсь если что.
Привет, внес исправления в задачу про студентов.
https://github.com/enotocode/Studentslist
>> Requirements:
>> SLQ 5.6.17 or above
>Что-то ты опечатался. И еще, у тебя разметка кривая получилась в README, почитай про маркдаун-разметку.
Переименовал в MySQL. Добавил заголовки и изменил булеты списков.
>> `egePoints` varchar(3)
>Число баллов на ЕГЭ - это все-таки число, а не строка. Вот телефон или номер паспорта - это строка,
>а число баллов - это число. Потому что их можно считать, складывать, и тд.
Заменил на SMALLINT(3) UNSIGNED
https://github.com/enotocode/Studentslist/blob/master/abiturients.sql#L37
>> require_once '/../app/init.php';
>Вот тут путь странный, это путь от корня диска или относительно текущего файла? Лучше использовать
>абсолютные пути, например на основе __DIR__, так как они гарантированно укажут на нужный файл.
>А относительный путь может например зависеть от того, какой текущий каталог, чему равен include_path и тд.
Использовал такое решение: require_once (__DIR__ . '/../app/init.php');
Это абсолютный путь или относительный? Ведь __DIR__ отдает путь относительно выполняемого скрипта?
Можно ли использовать такое решение require_once ($_SERVER['DOCUMENT_ROOT'] . '/app/init.php')?
https://github.com/enotocode/Studentslist/blob/master/app/init.php
>а как же зайти на страницу с таблицей студентов?
>Мне кажется, это неудобно, если она не открывается напрямую.
Ты имеешь ввиду добавить адрес вроде /list, который бы вел на список?
Как я понял условия задачи, доступ к списку студентов пользователь получает по ссылке
в уведомлении, после регистрации или редактирования профиля студента.
Изменил: сейчас при заходе по адресу / или /index.php открывается страница с ссылкой на редактирование и список.
Также в список можно попасть по ссылке /index.php?page=1.
https://github.com/enotocode/Studentslist/blob/master/public/index.php
>> // Подгружаем страницу сообщения
>> require("../templates/message.html");
>Вот это неправильно. Ты тут фактически делаешь вывод части страницы,
>а это не задача контроллера - выводить страницу по частям.
>Это должно делать представление, то есть основной шаблон страницы подключает что ему нужно.
Это сообщение часть страницы формы или списка? Я переделал немного, сейчас message.html это самостоятельная страница, и контроллер вызывает страницу полностью.
https://github.com/enotocode/Studentslist/blob/master/public/register.php#L37
>> echo 'Class "'. $fullFileName .'" does not exist.';
>Автозагрузчик не должен выводить ошибок. Если класса нет, он его просто не загружает.
>перечитай урок про автозагрузку.
>Имя файла в автозагрузчике лучше формировать абсолютное, а не начинающееся с '..'
Можно ли использовать в автозагрузчике вот такие пути __DIR__ . '/../' . $className . ".php" ?
https://github.com/enotocode/Studentslist/blob/master/app/autoloader.php#L7
>Магические методы надо всегда использовать с осторожностью.
>Так как они затрудняют понимание кода, требуют в нем разбираться.
>Для свойств студента наверно удобнее было использовать магические метод __get, __isset и __set
>(хотя тогда возникает вопрос, не проще ли сделать публичные свойства).
Сделал публичные свойства и добавил метод апдейт, который принимает массив.
https://github.com/enotocode/Studentslist/blob/master/app/Abiturient.php
>> foreach ($values as $valueName => $value) {
>> $sql = "UPDATE abiturients SET " . $valueName . " = '" . $value . "' WHERE id = " . $id;
>Неэффективно обновлять по 1 полю. Надо сформировать большой запрос и обновить все разом.
>Можно например собирать SQL код в один массив, а значения плейсхолдеров - в другой.
>Такой метод даже можно вынести отдельно, так как часто есть задача обновить сущность по id.
>Примерно так:
>$sqlParts[] = ' name = :name ';
>$placeholders[':name'] = $name;
>Только с подстановкой имен полей из переменной.
Переделал. Добавил метод собирающий запрос;
https://github.com/enotocode/Studentslist/blob/master/app/AbiturientDataGateway.php#L67
>> $email = filter_var ($value, FILTER_VALIDATE_EMAIL);
>Имей в виду, что емайлы вроде $ZCivanANUSиванzFwовPUNCTUMZDMрф не проходят через эту функцию, по крайней мере в PHP5.
>Там по моему даже в мануале это упомянуто для проверки URL.
Но ведь HTML валидация тоже не пропускает русские символы?
Я решил проверять только на наличие следующих опечаток - отсутствие @ или точки перед доменом или самого домена.
https://github.com/enotocode/Studentslist/blob/master/app/AbiturientValidator.php#L15
>> $this->errors["name"][0] = $this->findForbiddenSymbols('/[^a-zа-яё]/ui', $name);
>Тут наверно логичнее в качестве ключей использовать строки, то есть $errors['name']['forbidden'],
>так как используются они потом в другом месте кода и надо помнить какой номер чему соответствует.
>Более того, возможно тут стоит упростить код, сделав удобный класс для представления ошибки или
>списка ошибок. Чтобы было вроде
Переделал
https://github.com/enotocode/Studentslist/blob/master/app/AbiturientValidator.php#L49
>$error = new ValidationError(...);
>или
>$errors->add(['x' => .., 'y' => ...]);
>Сама идея хранить отдельно параметры ошибки от шаблона сообщения хорошая
>(это позволяет например делать перевод сообщения на другой язык), но вот реализация немного запутанная.
Добавил класс Errors, с методами add/get и isError.
https://github.com/enotocode/Studentslist/blob/master/app/Errors.php
>> date_default_timezone_set('UTC');
>Вот это нехорошо, твоя функция как побочный эффект меняет глобально часовой пояс
>Это может вызвать ошибки в другом месте кода. Посмотри, нельзя ли указать часовой пояс локально
>для одной функции, может передать в date, может использовать класс DateTime который вроде их поддерживает.
Вообще убрал установку часовой зоны, т.к. date возвращает по-умолчанию время для часовой зоны 'UTC'.
В данном случае не будет проблем, т.к. год рождения всегда меньше текущего года.
В другой ситуации, думаю можно устанавливать часовой пояс клиента в объекте DateTime::setTimezone(), гадая по IP и на JS?
https://github.com/enotocode/Studentslist/blob/master/app/AbiturientValidator.php#L78
>> placeholder="Иван"
>Лучше наверно "Например, Иван"
Если в каждом поле формы плеэйсхолдер будет начинаться с "Например, ...",
то воспринимать такую форму будет сложнее из-за повторений?
https://github.com/enotocode/Studentslist/blob/master/templates/form.html
>> <input type="radio" name="registry"
>> <label for="REGISTRY_LOCAL">Местная</label>
>Можно засунуть input внутрь label и тогда id/for не нужны.
В Bootstrap отступы другие получаются, не так красиво выглядит.
>И еще, ты подключаешь шаблон через include. Но это имеет недостаток:
>не видно, какие переменные передаются в него. Возможно лучше передавать их явно как-то так:
>$view->render('index.phtml', [
>'x' => $x,
>'y' => $y
>]);
Сделал класс View. Переменные из массива превращаю в переменные с помощью ф-ии extract.
Чтобы обращаться к ним $abiturient->name вместо $values['$abiturient']->name.
Нужен ли префикс в именах переменных при экстракции, например form_abiturient?
https://github.com/enotocode/Studentslist/blob/master/app/View.php
>У тебя класс авторизации по сути просто ищет юзера по куке.
>А рассмотри еще такой вариант, чтобы класс авторизации отвечал
>и за простановку/ проверку/очистку авторизационных кук. Может так будет лучше?
Дополнил функционалом класс авторизации.
https://github.com/enotocode/Studentslist/blob/master/app/Authorization.php
>Обновление студента лучше делать так: загрузить студента из БД, затем обновить в нем данные из POST.
>Иначе если у тебя в модели есть поле, которого нет в форме, оно потеряется.
>Ты по сути пересоздаешь студента заново.
То есть нужно каждый раз пересоздавать студента заново или я сейчас так и делаю?
Ты имеешь ввиду алгоритм в методе updateAbiturient в Gateway или в контроллере ?
Но ведь я и так загружаю студента из бд, затем заполняю его свойствами поля формы. Пользователь
изменяет или не изменяет эти свойства. Затем обновляю только те свойства студента, которые есть в форме.
Сейчас в форме нет id и пароля. Как и какое поле может потеряться?
И поле в форме не может быть пустым, т.к. в форме все поля обязательные.
https://github.com/enotocode/Studentslist/blob/master/public/register.php#L30
https://github.com/enotocode/Studentslist/blob/master/app/AbiturientDataGateway.php#L54
Привет, внес исправления в задачу про студентов.
https://github.com/enotocode/Studentslist
>> Requirements:
>> SLQ 5.6.17 or above
>Что-то ты опечатался. И еще, у тебя разметка кривая получилась в README, почитай про маркдаун-разметку.
Переименовал в MySQL. Добавил заголовки и изменил булеты списков.
>> `egePoints` varchar(3)
>Число баллов на ЕГЭ - это все-таки число, а не строка. Вот телефон или номер паспорта - это строка,
>а число баллов - это число. Потому что их можно считать, складывать, и тд.
Заменил на SMALLINT(3) UNSIGNED
https://github.com/enotocode/Studentslist/blob/master/abiturients.sql#L37
>> require_once '/../app/init.php';
>Вот тут путь странный, это путь от корня диска или относительно текущего файла? Лучше использовать
>абсолютные пути, например на основе __DIR__, так как они гарантированно укажут на нужный файл.
>А относительный путь может например зависеть от того, какой текущий каталог, чему равен include_path и тд.
Использовал такое решение: require_once (__DIR__ . '/../app/init.php');
Это абсолютный путь или относительный? Ведь __DIR__ отдает путь относительно выполняемого скрипта?
Можно ли использовать такое решение require_once ($_SERVER['DOCUMENT_ROOT'] . '/app/init.php')?
https://github.com/enotocode/Studentslist/blob/master/app/init.php
>а как же зайти на страницу с таблицей студентов?
>Мне кажется, это неудобно, если она не открывается напрямую.
Ты имеешь ввиду добавить адрес вроде /list, который бы вел на список?
Как я понял условия задачи, доступ к списку студентов пользователь получает по ссылке
в уведомлении, после регистрации или редактирования профиля студента.
Изменил: сейчас при заходе по адресу / или /index.php открывается страница с ссылкой на редактирование и список.
Также в список можно попасть по ссылке /index.php?page=1.
https://github.com/enotocode/Studentslist/blob/master/public/index.php
>> // Подгружаем страницу сообщения
>> require("../templates/message.html");
>Вот это неправильно. Ты тут фактически делаешь вывод части страницы,
>а это не задача контроллера - выводить страницу по частям.
>Это должно делать представление, то есть основной шаблон страницы подключает что ему нужно.
Это сообщение часть страницы формы или списка? Я переделал немного, сейчас message.html это самостоятельная страница, и контроллер вызывает страницу полностью.
https://github.com/enotocode/Studentslist/blob/master/public/register.php#L37
>> echo 'Class "'. $fullFileName .'" does not exist.';
>Автозагрузчик не должен выводить ошибок. Если класса нет, он его просто не загружает.
>перечитай урок про автозагрузку.
>Имя файла в автозагрузчике лучше формировать абсолютное, а не начинающееся с '..'
Можно ли использовать в автозагрузчике вот такие пути __DIR__ . '/../' . $className . ".php" ?
https://github.com/enotocode/Studentslist/blob/master/app/autoloader.php#L7
>Магические методы надо всегда использовать с осторожностью.
>Так как они затрудняют понимание кода, требуют в нем разбираться.
>Для свойств студента наверно удобнее было использовать магические метод __get, __isset и __set
>(хотя тогда возникает вопрос, не проще ли сделать публичные свойства).
Сделал публичные свойства и добавил метод апдейт, который принимает массив.
https://github.com/enotocode/Studentslist/blob/master/app/Abiturient.php
>> foreach ($values as $valueName => $value) {
>> $sql = "UPDATE abiturients SET " . $valueName . " = '" . $value . "' WHERE id = " . $id;
>Неэффективно обновлять по 1 полю. Надо сформировать большой запрос и обновить все разом.
>Можно например собирать SQL код в один массив, а значения плейсхолдеров - в другой.
>Такой метод даже можно вынести отдельно, так как часто есть задача обновить сущность по id.
>Примерно так:
>$sqlParts[] = ' name = :name ';
>$placeholders[':name'] = $name;
>Только с подстановкой имен полей из переменной.
Переделал. Добавил метод собирающий запрос;
https://github.com/enotocode/Studentslist/blob/master/app/AbiturientDataGateway.php#L67
>> $email = filter_var ($value, FILTER_VALIDATE_EMAIL);
>Имей в виду, что емайлы вроде $ZCivanANUSиванzFwовPUNCTUMZDMрф не проходят через эту функцию, по крайней мере в PHP5.
>Там по моему даже в мануале это упомянуто для проверки URL.
Но ведь HTML валидация тоже не пропускает русские символы?
Я решил проверять только на наличие следующих опечаток - отсутствие @ или точки перед доменом или самого домена.
https://github.com/enotocode/Studentslist/blob/master/app/AbiturientValidator.php#L15
>> $this->errors["name"][0] = $this->findForbiddenSymbols('/[^a-zа-яё]/ui', $name);
>Тут наверно логичнее в качестве ключей использовать строки, то есть $errors['name']['forbidden'],
>так как используются они потом в другом месте кода и надо помнить какой номер чему соответствует.
>Более того, возможно тут стоит упростить код, сделав удобный класс для представления ошибки или
>списка ошибок. Чтобы было вроде
Переделал
https://github.com/enotocode/Studentslist/blob/master/app/AbiturientValidator.php#L49
>$error = new ValidationError(...);
>или
>$errors->add(['x' => .., 'y' => ...]);
>Сама идея хранить отдельно параметры ошибки от шаблона сообщения хорошая
>(это позволяет например делать перевод сообщения на другой язык), но вот реализация немного запутанная.
Добавил класс Errors, с методами add/get и isError.
https://github.com/enotocode/Studentslist/blob/master/app/Errors.php
>> date_default_timezone_set('UTC');
>Вот это нехорошо, твоя функция как побочный эффект меняет глобально часовой пояс
>Это может вызвать ошибки в другом месте кода. Посмотри, нельзя ли указать часовой пояс локально
>для одной функции, может передать в date, может использовать класс DateTime который вроде их поддерживает.
Вообще убрал установку часовой зоны, т.к. date возвращает по-умолчанию время для часовой зоны 'UTC'.
В данном случае не будет проблем, т.к. год рождения всегда меньше текущего года.
В другой ситуации, думаю можно устанавливать часовой пояс клиента в объекте DateTime::setTimezone(), гадая по IP и на JS?
https://github.com/enotocode/Studentslist/blob/master/app/AbiturientValidator.php#L78
>> placeholder="Иван"
>Лучше наверно "Например, Иван"
Если в каждом поле формы плеэйсхолдер будет начинаться с "Например, ...",
то воспринимать такую форму будет сложнее из-за повторений?
https://github.com/enotocode/Studentslist/blob/master/templates/form.html
>> <input type="radio" name="registry"
>> <label for="REGISTRY_LOCAL">Местная</label>
>Можно засунуть input внутрь label и тогда id/for не нужны.
В Bootstrap отступы другие получаются, не так красиво выглядит.
>И еще, ты подключаешь шаблон через include. Но это имеет недостаток:
>не видно, какие переменные передаются в него. Возможно лучше передавать их явно как-то так:
>$view->render('index.phtml', [
>'x' => $x,
>'y' => $y
>]);
Сделал класс View. Переменные из массива превращаю в переменные с помощью ф-ии extract.
Чтобы обращаться к ним $abiturient->name вместо $values['$abiturient']->name.
Нужен ли префикс в именах переменных при экстракции, например form_abiturient?
https://github.com/enotocode/Studentslist/blob/master/app/View.php
>У тебя класс авторизации по сути просто ищет юзера по куке.
>А рассмотри еще такой вариант, чтобы класс авторизации отвечал
>и за простановку/ проверку/очистку авторизационных кук. Может так будет лучше?
Дополнил функционалом класс авторизации.
https://github.com/enotocode/Studentslist/blob/master/app/Authorization.php
>Обновление студента лучше делать так: загрузить студента из БД, затем обновить в нем данные из POST.
>Иначе если у тебя в модели есть поле, которого нет в форме, оно потеряется.
>Ты по сути пересоздаешь студента заново.
То есть нужно каждый раз пересоздавать студента заново или я сейчас так и делаю?
Ты имеешь ввиду алгоритм в методе updateAbiturient в Gateway или в контроллере ?
Но ведь я и так загружаю студента из бд, затем заполняю его свойствами поля формы. Пользователь
изменяет или не изменяет эти свойства. Затем обновляю только те свойства студента, которые есть в форме.
Сейчас в форме нет id и пароля. Как и какое поле может потеряться?
И поле в форме не может быть пустым, т.к. в форме все поля обязательные.
https://github.com/enotocode/Studentslist/blob/master/public/register.php#L30
https://github.com/enotocode/Studentslist/blob/master/app/AbiturientDataGateway.php#L54
У меня есть ссылки на последние 4, исключая текущий:
https://arhivach.org/thread/204328/ https://arhivach.org/thread/197740/ https://arhivach.org/thread/193343/ https://arhivach.org/thread/191923/
Спасибо анон.
https://jsfiddle.net/xya20s9g/
Я вот как-то так последний раз делал. Соответственно, элементу который выводит превью, задаёшь все стили как у элемента, который на сайте текст выводит.
Убунту и ставь. Она простая для новичка, но даёт и попердолиться. Поставь и делай всё через консоль, короч.
Часто используется на серверах centos и debian ещё, можешь поставить что-то такое, потом попробуй apache+mysql+php поставить вручную, настроить. Короче, попердолиться тебе надо.
Спасибо анон, ты великолепен.
А есть ли какой-нибудь сайт с охуенно-правильным кодом? Чтобы прям смотрел и прозревал.
github.com
Смотри, например, как фреймворки популярные устроены и всё такое. Если тебе нужны отрывки кода с пояснениями, то лучше подписаться на блоги всяких известных программистов. Но там много философии на тему ВАШ ООП НЕ ООП, ВЫ НИЧЕГО НЕ ПОНИМАЕТЕ, ИНДУСТРИЯ ГИБНЕТ, ГОВНОКОДЕРЫ РЯЯЯЯЯЯ
>подписаться на блоги всяких известных программистов.
>Блог известного программиста,
>Сегодня написал пикрил
>Долго думал.
в_тылу_врага http://ideone.com/30Nvg3
l33tspeak http://ideone.com/DJagBh
Лев Толстой http://ideone.com/NkKaTA
Генератор имён.
http://ideone.com/Ltxckh
Шифр
http://ideone.com/ODeVzj
L33t
http://ideone.com/pAeeUC
Лев Толстой (Я сделал зачем то двумя реализацияами, потому-что как по мне, довольно странно иметь функциюкоторая рандомазит массив, когда есть ровно накая-же только просто рандомайщ.)
http://ideone.com/c0UXxS
Палиндром.
http://ideone.com/uRe0gA
Айпады и кредиты
http://ideone.com/sGBReF
Наконец докатился до Регулярок, какие-же они сложные впринципе, ужос. Кстати есть ли что почитать по регуляркам. Прямо моё слабое место.
Ну понятно зачем: его устанавливают на сервера и часто на компьютеры в офисе, явно придется взаимодействовать с ним.
тот анон
>2016
>У фирмы нет денег на VPS или своего линукс админа
Srsly? Они уже стоят по 10$ за пучок.
Есть две таблицы. Одна строк на 200 и столбцов на 50, другая на 200 строк и 2 столбца. Требуется возможность их онлайн редактирования удобным для конечного пользователя образом. Я пока что придумал только следующее:
- Делаем чекбоксы и прочие элементы выбора столбцов/строк и кнопку.
- При нажатии на кнопку срабатывает жабаскрипт и через аякс данные из чекбоксов улетают в пхп-скрипт.
- В пхп скрипте происходит коннект к базам и вытаскивание нужных данных. Затем они оборачиваются в echo json_encode и возвращаются жабаскрипту.
- В жабаскипте данные разворачиваются и происходит отрисовка результирующей таблицы, в которую тут же вставляются данные. Каждая ячейка таблицы - отдельный инпут.
- Пользователь может редактировать данные в инпутах, затем нажимает ещё одну кнопку и ещё один жабаскрипт собирает данные из инпутов в один массив (кстати, я пока ещё не придумал, как вообще это сделать) и передаёт его в другой пхп скрипт, который и прописывает свежие данные в базу.
Это так и должно выглядеть, или я совсем ебанулся? Может есть плагины для удобной работы с таблицами?
>Одна строк на 200 и столбцов на 50, другая на 200 строк и 2 столбца.
Выкидываешь всё, оставляешь 5 столбцов. Даёшь юзеру выбрать что добавить. На деле инфа больше чем по 7 столбцам постоянно и чтобы прямо ваще щас - нинужна.
>- В пхп скрипте происходит коннект к базам и вытаскивание нужных данных. Затем они оборачиваются в echo json_encode и возвращаются жабаскрипту.
Ох, тебе-бы писать 50 оттенков серого для программистов.
Я и написал первым пунктом, что юзер сначала выбирает нужные.
>>854619
Вот и спрашиваю, как правильно-то?
Я непонимаю зачем тут json вообще?
Алсо тебе прямо обязательно возможность редактировать прямо все хаписи разом?
Не разом. Юзер выпадающим списком/чекбоксами определяет, из каких ячеек будет сформирована таблица, отображаемая на экране.
>зачем тут json
Я не знаю, как по другому вернуть массив данных из пхп в вызвавший его аякс.
Я просто пытаюсь понять.
Вот ты выбрал например 5 столбцов, вывел их. Теперь что? Я так понимаю что юзер выбирает строку, и получает возможность её редактировать. Правильно?
>Каждая ячейка таблицы - отдельный инпут.
Как то этодико, ну да ладно. Впринципе и так тоже можно. Хотел бы я увидеть реализацию этого всего.
Сейчас писал подробно, но стёр. Беру тайм-аут. Мне нужно повыть.
Если тебе нужен какой-то конкретный тред, ОП может поискать по сусекам. Также, есть на mediafire архив совсем старых тредов.
Гугли milestones со sprint на Гитхабе или вот: https://guides.github.com/features/issues/.
Создаёшь в спринтах нужные задачи. Один спринт обычно рассчитан на неделю, у кого как.
Несколько спринтов на месяц.
Можно отмечать, когда завершён спринт, там есть прогресс-бар завершения, всякие ярлычки и прочее.
Спасибо няша!
>Наконец докатился до Регулярок, какие-же они сложные впринципе, ужос.
А мне даже доставили регулярки, строки показались сложнее всего остального, слишком уж много ебли из-за отсутствия нормальной поддержки кириллицы.
Вы о чем, есть же архивач..
Задание:
Верстка, дизайн рассматриваться не будет, только качество кода.
Необходимо реализовать веб приложение – чат. Чат должен работать без перезагрузки страниц при отправке/получении сообщений/смене комнаты.
Вход в чат осуществляется свободно, но также должна быть возможность регистрации и авторизации.
Авторизованный пользователь может создавать комнаты. Комнаты могут быть: открытые и закрытые. Войти в закрытые комнаты можно только по приглашению создателя этой комнаты.
Приложение должно иметь панель управления. Права должны быть реализованы с использованием RBAC.
Должно быть две роли: администратор и модератор.
Панель управление должна иметь следующий функционал:
1. Управление пользователями:
a. Добавление (администратор);
b. Изменение данных пользователя (администратор, модератор);
c. Изменение прав (администратор);
d. Удаление (администратор);
e. Блокировка/ разблокировка (администратор, модератор);
2. Управление комнатами:
a. Добавление (администратор, модератор);
b. Изменение (администратор, модератор);
c. Удаление (администратор, модератор);
d. Просмотр переписки (администратор, модератор);
Техническая часть:
∙ Backend – PHP, реализация обязательно с использованием Yii 2;
∙ frontend – JavaScript;
∙ база данных – MySQL / PostgreSQL (При разработке использовать миграции).
Исходные комнаты необходимо предоставить ссылкой на GitHub или аналог.
Скажите - я соснул? Я подписываюсь на рабство уровня фриланс и за такие деньги миддлы не работают? Живу в перди с 300к населения.
Хотелось бы узнать мнение ОП, стоит ли браться, потому что, честно говоря, выглядит не самым простым.
Заранее благодарю.
Задание:
Верстка, дизайн рассматриваться не будет, только качество кода.
Необходимо реализовать веб приложение – чат. Чат должен работать без перезагрузки страниц при отправке/получении сообщений/смене комнаты.
Вход в чат осуществляется свободно, но также должна быть возможность регистрации и авторизации.
Авторизованный пользователь может создавать комнаты. Комнаты могут быть: открытые и закрытые. Войти в закрытые комнаты можно только по приглашению создателя этой комнаты.
Приложение должно иметь панель управления. Права должны быть реализованы с использованием RBAC.
Должно быть две роли: администратор и модератор.
Панель управление должна иметь следующий функционал:
1. Управление пользователями:
a. Добавление (администратор);
b. Изменение данных пользователя (администратор, модератор);
c. Изменение прав (администратор);
d. Удаление (администратор);
e. Блокировка/ разблокировка (администратор, модератор);
2. Управление комнатами:
a. Добавление (администратор, модератор);
b. Изменение (администратор, модератор);
c. Удаление (администратор, модератор);
d. Просмотр переписки (администратор, модератор);
Техническая часть:
∙ Backend – PHP, реализация обязательно с использованием Yii 2;
∙ frontend – JavaScript;
∙ база данных – MySQL / PostgreSQL (При разработке использовать миграции).
Исходные комнаты необходимо предоставить ссылкой на GitHub или аналог.
Скажите - я соснул? Я подписываюсь на рабство уровня фриланс и за такие деньги миддлы не работают? Живу в перди с 300к населения.
Хотелось бы узнать мнение ОП, стоит ли браться, потому что, честно говоря, выглядит не самым простым.
Заранее благодарю.
Спасибо няша, обожаю тебя.
Я даже не до конца понимаю, есть ли смысл пробовать. Боюсь подписать себя на рабство за маленькие деньги. Вот и решил спросить - стоит ли браться за подобное? Не слишком ли много они хотят?
>>854708
Если на задание дают неделю - модно часов за 5 запилить и за 5 ещё отполировать. Ну или часов за 20.
>Права должны быть реализованы с использованием RBAC.
это ведь Yii?
Эта задача решается максимум за неделю. Если ты идешь на мидла то тебе придётся решать более сложные задачи за те же сроки, если не раньше. Никаких пробовать быть не должно, эта задача - это самое элементарное, ты уже должен знать как она решается.
Удваиваю.
Но за это платят 350 баксов в месяц. Нынче на рынке труда всё настолько плохо?
Если можешь в ангельский, то https://regexone.com/lesson/introduction_abcs
Мне понравилось, всё доступным языком описано.
И? Это аргумент тому, что не нужно уважать себя и работать за еду?
бамп
на ходу фикс
preg_match('/\s/', 'Строка с пробелами') // вернёт 1
preg_match('/\s/', 'Строкабезпробелов') // вернёт 0
Аноны, имею 24 лвл и желание перекатиться в макаки из экономистов. Дрочил ваш пхп уже почти полгода и теперь наконец решился поискать работу.
Скажите, какая зп в ДС на первую самую работу норм? Вижу в основном вакансии от 25-35 тысяч, это же пздец как мало, или пока не вкатился соглашаться на любое?
И как qsoft, лайтрумы и прочие конторы котируются? Что делать на собеседовании, ведь у меня никакого опыта нет, даже все мои наработки, что я оповский задачник делал, даже всё это слетело на прошлой неделе к хуям вместе с виндовсом?
Короче, реквестирую ваших советов, так как боязно и вообще
http://ideone.com/XDziGo
https://regex101.com/r/qF7vT8/14
Подскажите, пожалуйста, верно ли я составил регулярку и можно ли ее как-то улучшить?
Блять как меня бесит regex101, сука, я нихуя там не понимаю, аж горит в жопе огонь..
И почему в аббревиатуре такая последовательность, а не MCV, например, вроде же такая логика?
От модели идёт к контроллеру, а потом к виду?
http://ideone.com/UrnxsA - Задачка про рост
http://ideone.com/aFmBWG - Ответ на любой вопрос
http://ideone.com/M16PXX - Генератор имен
http://ideone.com/HiKPCB - В тылу врага
http://ideone.com/0kXt6Z - l33tspeak (не так-то просто оказалось подобрать коды к киррилическим букам, лол)
http://ideone.com/r3hMnI - На словах я Лев Толстой
http://ideone.com/5iH5Lr - Палиндром
Для начала Git, потом Github.
Потом делаешь поделку "для себя", чтобы показать, что ты могешь в ООП, заливаешь на Github.
Профит. Его можнолол, нужно показать на собеседовании. А на гите оно у тебя ближайшие 25 лет точно будет хранится.
\s ведь и табы с переносами засчитывает
Не всё смотрел, но вот:
>{$word1[mt_rand(1, count($word1))]} {$word2[mt_rand(1, count($word2))]} {$word3[mt_rand(1, count($word3))]} \n
Повторяется два раза. Попробуй цикл с for для вывода этой строки два раза.
>Запрещала пробелы
/^[^ ]*$/
не совпадет только при встрече " " пробела в любой части строки.
>matches the character literally (case sensitive)
/[+7]?[8]?([\s]?[\-\( ]?[\s]?)\d{3}([\s]?[\-\) ]?[\s]?)([\s]?[\- ]?[\s]?\d{1}[\s]?[\- ]?[\s]?)([\- ]?\d{1}[\- ]?)([\- ]?\d{1}[\- ]?)([\- ]?\d{1}[\- ]?)([\- ]?\d{1}[\- ]?)([\- ]?\d{1}[\- ]?)/
Я ставил на нокию, плюс sql-сервер. Весьма доставляет, играл в Амулет Дракона один.
Вообще хуета.
Обожаю PHP за то, что он интерпретируемый, а не компилируемый. По своей ошибке запустил бесконечный цикл, который нагенерил мне за 5 минут гигабайт логов. Пыха ван лав :3
>По своей ошибке запустил бесконечный цикл, который нагенерил мне за 5 минут гигабайт логов.
>Щас бы на продакшн машине запускать скрипты
>Щас бы не иметь ограницений на бесконечные циклы в php.ini в 2016
>Щас бы свою собственную глупость выставить как недостаток языка.
Эх, вас бы лет на 20 назад и C++ компилстор без IDE которая за вас 90% работы делает, посмотрел бы я на ваши бесконечные циклы и нытьё.
>запустил бесконечный цикл, который нагенерил мне за 5 минут гигабайт логов.
В трэд джавистов зайди. У них вообще бесконечный цикл - это стандарт для написания демонов.
>запустил бесконечный цикл
>нагенерил мне за 5 минут
Ну так а зачем же ты отключил отграничения на время выполнения скрипта? Сам себе свинью подложил, а PHP ему виноват.
>>855081
Лучше помогите мне разобраться, в чём у меня тут ошибочка получилась - http://pastebin.com/VE7n1M4v
Дело обстоит следующим образом: запрашиваю json-строку, декодирую её в многомерный массив при помощи json_decode и перебираю заглавные ключи(они в каждом массиве разные). Если верить документации, у меня должно быть 10 массивов данных. Перебирающие циклы выводят 10 массивов данных(как и должно быть), но почему-то 9 раз один и тот же. В итоге, у меня 9 дублирующихся одинаковых блоков. Итого, 90 блоков.
>>855081
Я не запаривался особо с настройкой пыхи. Просто сделал apt-get install php и начал учиться кодить на пыхе.
>apache+mysql+php поставить вручную
>Короче, попердолиться тебе надо.
apt-get install apaсhe
apt-get install php
apt-get install mysql
Я охуел, когда первый раз в жизни в убунте устанавливал AMP. Если бы не проклятый Adobe, снёс бы семёрку ко всем чертям.
Спасибо.
А что скажешь про палиндром? Там в подсказке описано какое-то жутко, на мой взгляд, непонятное решение. Сам сперва представил себе алгоритм решения через strrev, точнее я не знал, как эта команда называется, но понял, что она мне нужна.
Потом нагуглил, вспомнил картинку, что через нее решать нельзя, воспользовался тем же самым для массива. Это законно?
Я про GIT.
Есть куча jpeg файлов, которые засунуты в другую кучу по меньше из doc файлов и рассортированы по папкам.
Хочу избавится от doc и перенести это в веб.
т.е. должна быть страничка где будут отображаться папки, в них вложены еще папки, а в них джепеги. Типа интерфейсов для FTP. Но должен быть быстрый поиск по всему этому, чуть больше 14000 позиций. Ну и конечно же, должна быть возможность создавать директории и загружать джипеги.
Как это сделать я таки примерно понимаю, но мне это делать лень. По этому может кто видел уже готовое? Посоветуйте какую-нибудь годноту.
>>854628
Есть таблица. Примерно 60 столбцов на 300 строк. Допустим, в каждой строке стоит отдельный товар, а во втором столбце указан его тип. Пользователь выбирает тип "Утюги" и ему показывается от 1 до 10 (вряд ли больше) строк 20-30 столбцов (допустим, все столбцы, за исключением пустых). И все ячейки должно быть можно редактировать. Так как это сделать с наименьшими потерями крови из глаз?
Думаю, всё правильно и законно.
Вообще одно из самых лаконичных решений на моей памяти.
Насчёт шифровальщика:
>'Ш' => 'III',
>'Щ' => 'III,',
Не вполне верно, потому что если Ш в предложении окажется перед запятой, то потом расшифруется как Щ.
Поищи клипарты на торрентах. А вообще я бы спарсил с гугло-картинок, а потом просмотрел тумбы. И, либо вручную заменил картинки на которых не города, либо внес в список названия городов, и изменил параметры парсинга. И повторил все сначала для нового списка городов.
Я изначально думал парсить картинки с Tumblr, но мясные дырки додумались постить туда свои ёбла, так что на запрос "New York" мне выпадала 1 пикча с городом и 9 и лицами пёзд. Потом додумался перейти на Flickr и там действительно годные фоточки и есть даже фильтр фоток на "города" и "людей". Так что, осталось только придумать, как мне вытащить ссылку на картинку из этого блока: http://pastebin.com/Y9yHntPd
Див и свойство style можно дернуть с помощью xpath. А url вытащить регуляркой например.
Я понимаю как оно работает. Я не понимаю только почему оно приписывает свойства классу, даже если эти свойства в классе не прописаны. Мне это кажется несколько абсурдом, что ли.
Ну это вообще норма? Типа только так и можно генерировать объекты из БД?
Ну, допустим, url у меня есть с нужным городом. А вот когда пытаюсь запарсить аттрибут style, получаю ошибку Notice: undefined offset 1
http://pastebin.com/1NgPkMQC
select 0 + column_name from table;
и
select cast(amount as float) as 'float-value' from amounts
но шото я не понимаю, к чему это вообще и как их прикрутить к mysql_query.
https://github.com/search?l=PHP&q=student+list&ref=searchresults&type=Repositories&utf8=✓
https://github.com/search?l=PHP&q=student+registration&ref=searchresults&type=Repositories&utf8=✓
В PHP обращение к несуществующим свойствам не вызывает ошибок, PHP сгенерирует свойство на ходу. На практике это нигде не используется, так как магия (явное лучше неявного). Как вариант, в твоём случае можно сделать так:
1) Выставить fetch-метод для PDO как FETCH_ASSOC, чтобы результат фетчился в виде массива массивов.
2) Вручную маппить объект на массив. Пример: https://ideone.com/MqQrUx
У ОПа написано про DataMapper в пасте про паттерны для работы с БД.
Советую почитать про XPATH и DOM. Парсить HTML гораздо быстрее и удобнее чем каждый раз придумывать и тестировать регулярки. Путь до элемента можно посмотреть в девтулах в браузере. Вставляешь в запрос и вуаля.
В PHP есть поддержка из коробки.
http://php.net/manual/ru/domxpath.query.php
Про парсинг HTML регуляркой вот тут хорошо написано (англ) http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags?answertab=oldest#tab-top
Скобок лишних в if'е понаставил. Отследи внимательно, должно быть так: if (... && ...) {}, у тебя сейчас вот так: if ((...)) && (...) {}
Спасибо, а то я уже минут 15 ломаю над этим голову, но даже не подумал на скобки в if
Спасиобо, оп, ты охуенен.
Мм, был уверен, что uncaught - это неизвестный. Теперь понял. Исправил
> а как так вообще выходит, что переменные из БД подставляются в качестве свойств объекта?
Так и задумано. Ты ведь сам указываешь соответствующую опцию. Для каждой записи из БД php делает следующее:
- создает объект указанного тобой класса не вызывая конструктор
- проставляет значения полей из БД в поля объекта
- вызывает конструктор объекта
Вообще, это неправильно, сначала проставлять поля, а потом вызывать конструктор и противоречит определению конструктора (метод, который инициализирует объект и подготавливает его к работе), потому там сделали специальную опцию PDO::FETCH_PROPS_LATE, которая вызывает конструктор в правильный момент, но почему-то не сделали это опцией по умолчанию. Видимо разработчики PDO не очень любят ООП.
> А самое странное(по моему мнению) то, что эти переменные будут подставляться даже если класс будет вообще пустым. Это баг или фича?
В PHP есть такая неудачная на мой взгляд особенность, что можно динамически добавлять в объект свойства, которых не было в классе. При присваивании значения несуществующему свойству оно автоматически создается.
Это на мой взгляд, ошибка, так как ООП подразумевает что мы определяем список свойств на этапе определения класса. Ну и в случае, если ты опечатался:
$student->namee = 'Ivan'; // namee вместо name
PHP не выдаст ошибку, а молча создаст свойство. В общем, глупое решение. В других языках вроде Java или C# тут будет ошибка и сразу будет видно, в чем дело.
Есть 2 варианта:
- можно сделать высокоуровневый класс-сервис, который начинает транзакцию, вызывает по очереди оба TDG, коммитит. Это даже у Фаулера описано (хотя и не очень понятно):
http://design-pattern.ru/patterns/service-layer.html
В простом приложении можно чуть-чуть отступить от строгих правил и засунуть вставку в обе таблицы в один TDG.
По идее между таблицами должны быть связи на основе внешних ключей. Хотя, возможно, что их по какой-то причине не сделали.
>>855401
Из твоего описания не ясно, что именно надо сделать. Тебе надо поменять тип данных в таблице или преобразовать данные, выбираемые из таблицы и полученные в приложении?
>>855351
Можно выбирать из БД массив и как-то вручную на его основе создавать объект.
>>855315
В Википедии есть наверно.
>>855176
Как в экселе.
>>855123
Да. strrev нельзя использовать потому, что он не поддерживает кирилицу. Если твой подход поддерживает ее, то можно его использовать.
Регулярка хорошая. Хотя можно еще чуть-чуть ее улучшить, если вынести повторяющиеся ^ за скобки и убрать лишние скобки (справа и слева от вертикальной черты).
>>854770
Вообще, регулярки так не работают. В них нельзя запрещать, можно только разрешать определенные комбинации символов. В том числе "любой символ, кроме пробела".
1) могу предложить свой урок https://github.com/codedokode/pasta/blob/master/arch/mvc.md + погугли
2) не знаю, почему так названо, надо спрашивать авторов
> От модели идёт к контроллеру, а потом к виду?
Нет, неверно. Посмотри схемы в моем уроке.
Найти код, отвечающий за валидацию, и заменить на свой с нуждным функционалом.
В Yii 2 уровня валидации: в процессе ввода на клиенте данные аяксом шлются на сервер для проверки, и при отправке формы данные снова проверяются уже на стороне сервера.
Тебе наверно надо подправить клиентскую валидацию. Изучи встроенный в Юи JS код и напиши свой либо аналогичный либо вызвающий нужные функции из кода Юи. Не правь скрипты самого Юи.
http://ideone.com/AdLoVd (31 строка суть)
В js тред не гоните, это задача опа.
Хотя логично, код думает что я создаю класс name. А как поступить то? Eval приходит на ум. Но его не рекомендуют использовать.
И праивльно, что нельзя, от всех этих динамических вызовов только бардак. Вот когда ты видишь код вроде:
new $class(1)
Может ли в этом месте использоваться класс SomeClass или нет? Это нельзя определить без анализа кода.
В случае JS после new должна идти функция. Логичнее всего в функцию generator передавать не имя, а саму функцию-конструктор. Имя тут - ненужный костыль.
Также, для обозначения типов панелей надо использовать не строки, а константы вроде PowerPanel.TYPE_SOMETHING
Советую тебе потом показать код на проверку, так как выглядит он пока сомнительно.
>>855693
Ищи не во время выполнения скрипта, а заранее. Либо храни данные в БД а не в виде JSON. зачем ты вообще используешь джейсон? есть какая-то веская причина? Это не формат для быстрого поиска данных.
Данные предоставляются в виде json и никак более. http://api.travelpayouts.com/data/cities.json
Спасибо, как-то странно, что я забыл про использование функций таким способом после 13 твоих задачек по js-то и учебника Кантора. Не до конца еще понимаю js. Пожалуй кину задачки в очередь проверок, которые решил на данный момент.
11: http://ideone.com/sbm9XK
12: http://ideone.com/fu1J3t
13: в процессе
14: http://ideone.com/QQnfE5
15: в процессе
Первые 10 успешно проверены ботом.
Источник: https://gist.github.com/codedokode/ce30e7a036f18f416ae0
Проверил свою теорию. В общем, нихуя это не из-за поиска в массиве. Запросы к API обрабатываются за 0.1 секунду, а поиск в массиве за 0.03. Всё дело в том, что PHP не хочет, чтобы я изобретал велосипеды, а хочет, чтобы я учил классы и public-функции наверное. Поскольку данные из функций и получаю следующим образом:
require('php/functions.php');
$geo = LocateUserGeo();
$popular = findPopularDirection();
А должен был бы наверное делать это классами. Тогда бы не пришлось вызывать функции и записывать их в переменные. Переменные были бы доступны из класса и паблик-функций в индексном файле наверное. Am i right?
Понял что я полный нуб в регулярках. Автомобильный номер мсмог за 2 минуты найти, а вот номер мобильника занял у меня 2 дня. Даже не поиск правильного номера стал проблемой, а отметание неправильных. Внезапно так. Сиже теперь листаю Mastering Regular Expressions Jeffrey E.F. Friedl Third Edition...
Задача на автономера. (Кто подскажет как добавить поддержку номеров типа z123df?)
http://ideone.com/xLI6IK
>Хотя можно еще чуть-чуть ее улучшить, если вынести повторяющиеся ^ за скобки и убрать лишние скобки (справа и слева от вертикальной черты).
Вот это скилл, я бы в жизни не смог понять этого!
Вроде всё работает, но буду благодарен если анон посмотрит и подскажет, если что не так.
http://ideone.com/3eB45P
Проблема 1.
Посреди статьи этого сделать нельзя, потому-что текст с фото грузить довольно сложно с точки зрения логики.
Нельзя сразу дать ссылку на фотографию. Нельзя сразу отформатировать фотографию и посмотреть как это будет в итоге выглядеть.
Поэтому я создал отдельную формочку для фоток для статей. И уже во время написания статьи открываю фрэйм и позволяю выбрать фото и воткнуть в статью.
Через неделю выяснилось что уже при 500 фотографиях искать что-то своё нереально.
Вопрос. Как поступить? Есть вариант кидать фотки в папки с датами и таким образом уменьшать выборку фотографий. Так можно, или есть альтернативные варианты?
>Из твоего описания не ясно, что именно надо сделать. Тебе надо поменять тип данных в таблице или преобразовать данные, выбираемые из таблицы и полученные в приложении?
Лучше поменять тип данных прямо в таблице, чтобы дальше работать с ними, как с числами.
https://yadi.sk/d/tr25KO_kwkCfc
Не работает запись в базу данных. А яваскрипт работает прекрасно.
Ну ты понял что должно получиться
>По идее между таблицами должны быть связи на основе внешних ключей. Хотя, возможно, что их по какой-то причине не сделали.
Я сперва тоже так подумал, посмотрел наличие Foreign keys но их нет, там нет ни ничего ни уникальных, ни индексов, ни праймери ключей. Ещё и опечатки в названии колонок, да и вообще я посмотрел на данные - там нет даже похожей колонки на ту которая использовалась бы для связи. Буду разбираться значит с заказчиком.
http://ideone.com/eTXny3 - Лев Толстой.
Здравствуйте. По ходу выполнения палиндрома возник вопрос. Почему не работает доступ к символу через
$char = $text[1].
ни echo $char, ни var_dump($char) - ничего не выводят.
Заранее спасибо за помощь.
Я параллельно с php прохожу задания на freecodecamp, там есть бэк энд, вроде состоит в изучении js. Я так понимаю, раз я учу php, то мне не нужно изучать js?
Ещё раз уточню. У меня есть таблица, в таблице столбец, в столбце данные. Тип - varchar, причём данные в виде цифр "5 876,00", то есть, миллионы от тысяч отделены пробелами. И Тысячи от единиц тоже. Мне нужно скопировать эти данные в другую таблицу, в столбец с типом double(10,2). Как? Я пробовал отдельной командой конвертировать тип данных, но получается какая-то шляпа: от данных остаются только первые цифры, всё, что после первого пробела, исчезает. Но в структуре таблицы этот столбец продолжает быть varchar-ом! Да как так-то?
Запрос для конвертирования делаю такой:
$sql_convert = "UPDATE $table_1c SET `НДФЛ` = CAST(`НДФЛ` AS DOUBLE(10,2));";
А для копирования:
$request_copi_from_1c = "UPDATE `$value[0]` SET `НДФЛ` = ( SELECT `НДФЛ` FROM $table_1c WHERE $table_1c.`Организация` = $value[0].name GROUP BY $value[0].id )";
Задача свелась к замене всех пробелов на ничего, а всех запятых на точки.
$request = "UPDATE $table_1c SET `Оклад по часам` =REPLACE (`Оклад по часам`, ' ', '');";
Я бы в такой ситуации конвертировал данные на стороне PHP, так как там можно сделать например проверку регуляркой и обнаруживать нестандартные значения.
А твой код - вот если будет какое-то нестандартное значение - он же просто его в 0 сконвертирует молча.
Ну и кстати ты тоже выбрал неправильный тип. Тебе нужен не double (неточный тип), а decimal (точный). Изучи, в чем между ними разница.
Почему ты сделал эту ошибку? Потому что вместо последовательного изучения теории торопишься, пропускаешь темы.
>Потому что вместо последовательного изучения теории торопишься, пропускаешь темы
Задача поставлена, сроки оговорены, а знаю я скул или не знаю, никого не волнует. Так что приходится изучать на ходу. Щито поделать. За подсказки спасибо, выписал себе, обратить внимание на тип. Но это потом, сейчас мне главное показать хотя бы минимально работающее приложение.
Если я правильно тебя понял, и проблема в том, что папка в которую загружают картинки общая для всех и в ней сложно найти фото. Сделай как в WP - фото загружается на хостинг в папку с сегодняшней датой.
Тут я беру значения полей из столбца одной таблицы и вставляю во вторую таблицу столбцы с названиями, взятыми из этих полей:
$arr = array();
$q = "SELECT objects FROM $table_objects";
$request = mysql_query($q);
if (mysql_num_rows($request) > 0) {
while ($len = mysql_fetch_array($request)) {
$object_name = $len['objects'];
$sql1 = "ALTER TABLE $value[0] ADD `$object_name` int";
if (mysql_query($sql1)) {
echo "столбец $object_name из таблицы objects успешно добавлен\n";
} else {
echo 'Ошибка при добавлении столбца из таблицы objects: ' . mysql_error() . "\n";
}
}
}
Спасибо, читаю, интересно.
>Представление отображает данные, которые ему передали. В веб-приложении обычно
>Представление обычно состоит из шаблонов страниц, в десктопных или мобильных приложениях Преставление - это код, который отвечает за отображение информации на экране, отрисовку кнопочек и других элементов интерфейса.
Немного запутано и с опечатками.
Конечно, JS это не только бэкенд (сервер-сайд язык), его вовсю используют во фронтэнде: как минимум для анимаций и аякса, как максимум - есть море фронтэнд фреймворков (React, Angular), есть шаблонизаторы на основе JS (JRender и тд). Сейчас ты вряд ли найдешь много интернет-сайтов без JS, то-есть ты должен быть готов к этому.
Могу тебя немного успокоить - после изучения одного языка - второй изучается быстрее По крайней мере JS после PHP для меня прошел проще в разы.
Ну можно и так, только обеспечь между ними взаимодействие, напиши конфигурацию апачу. Поставь несколько версий php. Поставь ngnix. Сделай так, чтобы менялось окружение с полоборота (скриптом). Это что я знаю по поводу линукса для пхп-разработчика.
мимо-джун
git commit -m
Опция после которой указываешь комментарий для комита. Без этой опции в включается vim.
Что это такое?
> Без этой опции в включается vim.
Необязательно vim. Но даже если вим, то что в этом плохого?
Для таких случаев: <div class="message error">
Вместо объекта PdoStatement ты получил false. Проблемы скорее всего нужно искать в методах query/execute объекта PDO, без кода тяжело сказать.
>>856184
.message.error {}
/ rules go here /
}
В Линуксе редактор выбирается переменной окружения EDITOR. Соответственно, если вписать в /etc/profile или ~/.bashrc строку
export EDITOR=nano
То будет вызываться указанный редактор. Ну и в моем дебиане по моему по уолмчанию стоит nano.
>>856194
Надо включать PDO::ERRMODE_EXCEPTION чтобы видеть ошибку сразу.
>848545
>Калькулятор
>Плохо, что switch с операциями скопирован 2 раза. От копипасты надо избавиться.
Перенес switch в функцию, так будет правильней?
http://ideone.com/gVfev9
>848545
>Навигатор
>Попробуй написать решение с рекурсией
Что-то слепил, немного не по предложенному алгоритму. Поэкспериментировал, вроде бы решает верно.
http://ideone.com/fbSU5j
>Также, дам дополнительную задачку на рекурсию, чтобы лучше в ней разобраться
http://ideone.com/yWXwSo
>Надо не добавлять элементы в и без того сложный массив, а сделать отдельные массивы. А так у тебя все вперемешку получилось: тут же и соседние станции, тут же и label которая не является соседней станцией. Как потом разобраться?
Переделал немного.. Добавил отдельные массивы, убрал вызов searchPath, да остальные функции немного переписал и попробовал применить docComment, который ты посоветовал в ответе на «Вектор».
Нормально ли здесь использовать global или нужно всё же передавать через параметры?
http://ideone.com/0SJSa0
>Подозрительно что простановка минимального времени делается 2 раза:
>>if ($pointValue['label'] < $minLabel && (!$pointValue['visited'])) {
>>if ($paths[$point]['label'] > $newLabel) {
В алгоритме сказано:
".. из ещё не посещённых вершин выбирается вершина u, имеющая минимальную метку", для этого я выполняю:
> if ($pointValue['label'] < $minLabel && (!$pointValue['visited'])) {
и далее
"Для каждого соседа вершины u, кроме отмеченных как посещённые, рассмотрим новую длину пути, равную сумме значений текущей метки u и длины ребра, соединяющего u с этим соседом. Если полученное значение длины меньше значения метки соседа, заменим значение метки полученным значением длины", для этого я делаю:
> if ($paths[$point]['label'] > $newLabel) {
вроде бы всё по алгоритму…
>848545
>Числа прописью
>чтобы не мучаться с пробелами, проще было наверно складывать слова в массив, а потом склеивать с помощью implode().
Переделал через implode(),
http://ideone.com/tFv3R1
>848567
>Вектор
Подобавлял тайп-хинты.
Вынес создание отчета в отдельный класс
* Попробовал применить docComment (точнее его подобие)
>Вообще, $rank не может быть равен нулю.
Убрал значения по умолчанию. Убрал имена. Предполагал, что их можно будет указывать в дальнейшем, а в тестовом режиме можно обойтись и без них.
>Тут есть проблема: тот, кто наследует твой класс должен как-то догадаться что надо переопределить поля.
Объявил абстрактные методы setSalary() и так далее, и переопределил их в дочерних классах. Для установки значений вызываю эти методы в конструкторе.. но что-то кажется, что не так делать нужно..
>Тут удобнее анализировать строку регуляркой. Она умеет захватывать части строки.
Переделал через регулярку
http://ideone.com/7J6fES
>>848567
>Антикризисные меры
>Вот это уже нарушение принципа единой ответственности
Перенес антикризисные меры в класс CrisisCommittee. А такие вещи, как количество инженеров/менеджеров можно оставлять в Департаменте?
>Я бы проверял не человеческое название (которое может поменяться), а имя класса.
Поменял, если я правильно тебя понял.
>Она удаляет всех инженеров, не разбирая ранги
Переделал. Сортирую всех сотрудников по рангу, собираю всех инженеров (который не являются инженер-директором), слайсами беру 40% и удаляю..
>Если директора нет, будет ошибка обращения к несуществующей переменной
Создал до цикла. Какое значение при создании будет правильней: NULL, false?
>думаю что неправильно создавать класс только ради смены зарплаты
Убрал класс AnalystImproved. Теперь повышением зарплаты занимается антикризисных комитет.
Здесь можно использовать значение по умолчанию setSalary($salary = 500)? То есть, ставим зарплату по умолчанию, как указано в задании, а в случае чего, антикризисный комитет может поставить свое значение.. Или нужно пересмотреть подход?
>Тут копипаста. Лучше настроить возможность клонирования компании и департаментов.
То есть в классе Компании принудительно клонировать каждый департамент? А для Департамента аналогично для Сотрудника..
Если так, то добавил.
http://ideone.com/wEdkij
Спасибо большое за ответ и советы :-}
>848545
>Калькулятор
>Плохо, что switch с операциями скопирован 2 раза. От копипасты надо избавиться.
Перенес switch в функцию, так будет правильней?
http://ideone.com/gVfev9
>848545
>Навигатор
>Попробуй написать решение с рекурсией
Что-то слепил, немного не по предложенному алгоритму. Поэкспериментировал, вроде бы решает верно.
http://ideone.com/fbSU5j
>Также, дам дополнительную задачку на рекурсию, чтобы лучше в ней разобраться
http://ideone.com/yWXwSo
>Надо не добавлять элементы в и без того сложный массив, а сделать отдельные массивы. А так у тебя все вперемешку получилось: тут же и соседние станции, тут же и label которая не является соседней станцией. Как потом разобраться?
Переделал немного.. Добавил отдельные массивы, убрал вызов searchPath, да остальные функции немного переписал и попробовал применить docComment, который ты посоветовал в ответе на «Вектор».
Нормально ли здесь использовать global или нужно всё же передавать через параметры?
http://ideone.com/0SJSa0
>Подозрительно что простановка минимального времени делается 2 раза:
>>if ($pointValue['label'] < $minLabel && (!$pointValue['visited'])) {
>>if ($paths[$point]['label'] > $newLabel) {
В алгоритме сказано:
".. из ещё не посещённых вершин выбирается вершина u, имеющая минимальную метку", для этого я выполняю:
> if ($pointValue['label'] < $minLabel && (!$pointValue['visited'])) {
и далее
"Для каждого соседа вершины u, кроме отмеченных как посещённые, рассмотрим новую длину пути, равную сумме значений текущей метки u и длины ребра, соединяющего u с этим соседом. Если полученное значение длины меньше значения метки соседа, заменим значение метки полученным значением длины", для этого я делаю:
> if ($paths[$point]['label'] > $newLabel) {
вроде бы всё по алгоритму…
>848545
>Числа прописью
>чтобы не мучаться с пробелами, проще было наверно складывать слова в массив, а потом склеивать с помощью implode().
Переделал через implode(),
http://ideone.com/tFv3R1
>848567
>Вектор
Подобавлял тайп-хинты.
Вынес создание отчета в отдельный класс
* Попробовал применить docComment (точнее его подобие)
>Вообще, $rank не может быть равен нулю.
Убрал значения по умолчанию. Убрал имена. Предполагал, что их можно будет указывать в дальнейшем, а в тестовом режиме можно обойтись и без них.
>Тут есть проблема: тот, кто наследует твой класс должен как-то догадаться что надо переопределить поля.
Объявил абстрактные методы setSalary() и так далее, и переопределил их в дочерних классах. Для установки значений вызываю эти методы в конструкторе.. но что-то кажется, что не так делать нужно..
>Тут удобнее анализировать строку регуляркой. Она умеет захватывать части строки.
Переделал через регулярку
http://ideone.com/7J6fES
>>848567
>Антикризисные меры
>Вот это уже нарушение принципа единой ответственности
Перенес антикризисные меры в класс CrisisCommittee. А такие вещи, как количество инженеров/менеджеров можно оставлять в Департаменте?
>Я бы проверял не человеческое название (которое может поменяться), а имя класса.
Поменял, если я правильно тебя понял.
>Она удаляет всех инженеров, не разбирая ранги
Переделал. Сортирую всех сотрудников по рангу, собираю всех инженеров (который не являются инженер-директором), слайсами беру 40% и удаляю..
>Если директора нет, будет ошибка обращения к несуществующей переменной
Создал до цикла. Какое значение при создании будет правильней: NULL, false?
>думаю что неправильно создавать класс только ради смены зарплаты
Убрал класс AnalystImproved. Теперь повышением зарплаты занимается антикризисных комитет.
Здесь можно использовать значение по умолчанию setSalary($salary = 500)? То есть, ставим зарплату по умолчанию, как указано в задании, а в случае чего, антикризисный комитет может поставить свое значение.. Или нужно пересмотреть подход?
>Тут копипаста. Лучше настроить возможность клонирования компании и департаментов.
То есть в классе Компании принудительно клонировать каждый департамент? А для Департамента аналогично для Сотрудника..
Если так, то добавил.
http://ideone.com/wEdkij
Спасибо большое за ответ и советы :-}
НО не понимаю, как в поля формы на новой странице вставить значения из ПРОШЛОЙ формы. ХЕЛП.
Не знаешь - изучай. Тебе нужен либо JS либо любой серверный язык программирования вроде PHP. Тут не служба бесплатного выполнения чужой работы.
Стояла приватность в ideone, виноват, убрал.
Насколько популярен php и есть ли у него будущее? Правда ли что все перекатываются на python и js? Будет ли php популярен ещё минимум лет 5?
Какую книгу посоветуете? В головном треде пик устаревший донельзя. Что щас народ читает? Желательно чтобы не было разжованно как для даунов типа "переменная, это как спичечный коробок и короче там она имеет название..."
Я лабы сдавал.
Какие лучше выполнить задания для поднятия скилла? В десектопе идей масса, в вебе ни одной. Есть лишь желание поднять ftp, но это пока для меня круто.
Слава Украине!
Какие навыки нужны параллельно? HTML знаю, в CSS смогу походу, делов там. Нужно ли знать wordpress или что-то вроде этого?
Linux или винда? Что лучше, удобнее?
Да, в JS функции - это "граждане первого сорта" в том плане, что их можно сохранять в перемнные, передавать и возвращать из функций. Также, функции в JS являются объектами, конструктором которых является встроенный "класс" Function (я пишу "класс" так как настоящих классов в яваскрипте нет, а Function - это функция-конструктор).
Так как функции - это объекты, можно делать даже такое:
var a = function () {} ;
a.x = 1;
В PHP тоже есть функции высшего порядка. А функцию-объект можно создать, реализовав для класса метод __invoke
Нужна БД, которая будет хранить овердохуя данных и отдавать их максимально быстро. Я одновременно учу PHP делая свой проект, и при этом хочу научиться писать производительный код. Я тот кун, у которого с json проблемесы были. У меня есть json-файл, в котором 10к объектов. Я его декодирую в многомерный массив, а затем 3 раза пробегаюсь по нему рекурсивным поиском через foreach, вынимая 3 разных ключа. В итоге, тот велосипед на основе json и многомерного массива, который я изобрёл - парсит данные по 2-3 секунды. Мне такая хуйня не подходит, по этому я решил хранить данные не в виде JSON, а перенести это дело в базу данных. И надеюсь, что с базой данных это будет работать быстрее(потому, что, сам понимаешь, если в продакшене страницы будут загружаться по 2-3 секунды - это никуда не годится)
Да, PHP может быть не очень в почете у анонимных экспертов с имиджборд или начинающих JS программистов с Хабра, но настоящие разработчики не боятся его использовать.
>>856266
Будет, только тебе нужно время чтобы тщательно изучить нормализацию БД (чтобы правильно проектировать таблицы - у меня даже есть урок по этой теме https://github.com/codedokode/pasta/blob/master/db/normalization.md ), а также индексы и оптимизацию БД (по моему про нее написано где-то в официальном мануале на англ).
Ну быстро изучить это конечно вряд ли получится.
>>856271
php.ini-development это не конфиг, а образец конфига. Настоящий конфиг называется php.ini. увидеть текущие настройки PHP в командной строке можно, набрав команду
php -i
Нетбинс перезапускать вообще смысла нет так как это ничего не меняет.
>только тебе нужно время чтобы тщательно изучить нормализацию БД
Вот именно. А мне нужно просто какое-то решение, чтобы "из коробки" встало как надо, и работало. Вообще, я вести базу данных не планирую. Мне нужно просто из json перенести данные в базу, вот и всё.
Спасибо, я все понял, просто почему-то сам файл php.ini отсутствовал в архиве, а вот те 2 - присутствовали, и я затупил.
Плюсы:
- больше типизации: можно указывать типы для полей класса, возарщаемых значений функции
- генерики: можно делать классы, работающие с объектами определенного класса. Ну например, можно сделать класс универсальный Список объектов (List<T>) и из него получить Список Студентов (List<Student>) или Список Постов (List<Post>).
- Hack поддерживается в HHVM - специальном оптимизированном итерпретаторе PHP и Hack, выполняющем тот же самый код быстрее
- есть специальный синтаксис для HTML-шаблонов XHP, который позволяет проверять правильность кода: закрываются ли теги, правильно ли исопльзуются атрибуты. В отличие от чистого PHP, все данные в XHP автоматически экранируются с помощью htmlspecialchars, что защищает от XSS. И синтаксис HTML можно проверять до выгрузки на продакшен.
- типизированные массивы (для которых задан список полей и типов)
- и многое другое
При этом Hack обратно совместим с PHP, то есть можно взять готовый PHP скрипт и почти без переделки превратить его в скрипт на языке Hack.
Посмотрите, кому интересно.
>>856273
Не разбираясь в базах данных, нормально твою задачу не решить.
По моему ты взялся за задачу не своего уровня. Для начала, надо точно определить, чем вызваны задержки и как можно поменять алгоритм работы, чтобы их избежать. В любом случае это требует определенных навыков и знаний. Просто так, погуглив, ты задачу вряд ли решишь.
Это же не задача из серии "как в jquery скрыть блок при нажатии на кнопку". Я не знаю такой волшебной функции или программы, которая все сделает за тебя.
>PHP может быть не очень в почете у анонимных экспертов с имиджборд или начинающих JS программистов с Хабра, но настоящие разработчики не боятся его использовать.
Ох, я в этой "Тусовке" уже лет 6. И мой вам совет, не слушайте всяких экспертов. Вам язык помогает задачу решить? Используйте. Все эти 'Эксперты' только говном кидаться могут.
C++? нее, слишком небезопасно, с массивами работать сложна, и утечки памяти.
Java? Неее, слишком муторно, и именовать переменные долго, к тому-же мы не знаем как Мавен работает.
Go? - очередная поделка от гугла, через два году придумают Gu и от поддержки откажутся.
Objective C - с ума сошёл, будешь рабом эпла, кроме них никто ведь его не юзает.
Swift - не язык, а лол, купи макбуков себе и программируй, ну уж нет.
C# - майкрософт маст дай, кто его юзает вообще? Да и возможностей маловато. К тому-же он вот вот помрёт. Майкрософт хотят прекратить его поддержку. ( Это мнение слышу вообще с 2008 года )
Учиться нужно как раз на реалистичных задачах, которые могут возникнуть в процессе будущей работы. Я с точностью в 99.9% заявляю, что проблема именно в том, что массив дохуя огромный. У меня задержки начались как раз тогда, когда я этот поиск реализовал. Только тогда страница загружалась где-то полторы секунды и я забил хуй. А потом я добавил ещё парочку запросов к API, парочку foreach и парочку json_decode и в совокупности всё дало такую задержку. Так что, у меня один выход - искать замену json. Выбор невелик. Можно сказать, его нет. Я по этому и спрашиваю на счёт бд. Будет ли поиск в БД быстрее, чем поиск в массиве?
То есть ты даже не мерял, а нашел причину "по ощущениям". Тогда сравни "по ощущениям" алгоритмы, по которым работает твой поиск и поиск в БД, и получишь ответ.
Нет. ты пока не все перенес. Вот тут: https://github.com/someApprentice/Students/commit/6b1fb52461786f9fe0966562c73b9f6f99968d5c#diff-f2d1af9c4ccbbb1fb81e9cd1a194f5e3R22
У тебя метод render() идет посередине.
Обычно вызов render() идет в конце метода контроллера. Мы подготовили все нужные данные, и вызываем View чтобы отобразить страницу. По частям ее отображать неправильно, так как контроллер не должен знать, из каких частей она составлена, это задача View.
То есть типичный метод контроллера выглядит так:
.. подготовка данных ...
$this->render(...);
Иногда вместо render идет редирект (например, при обработке формы), иногда что-то другое (например, выдача страницы ошибки или какого-то нестандартного HTTP-ответа).
Также, путь templates\search.phtml лучше писать через прямой слеш / , так как обратный слеш работает только в Windows.
На самом деле, мне в голову только что пришла гениальная мысль. В одном массиве json-данных содержится 23 ключа со значениями, а использую из них я всего 4. Если бы можно было убрать лишние 19 ключей со значениями, то это ускорило бы загрузку в почти 4 раза. Осталось только придумать, как это сделать в огромном файле.
В том, что это текстовый редактор для которого нужно читать мануал.
> 2016
> использовать mysql_* функции
Их выпилили к чертям из нового PHP, зачем ты учишься по статьям 2012-го года? Вот адекватный подход для работы с БД: http://www.phptherightway.com/#pdo_extension
А mysql-функции просто молчат, когда что-то пошло не так, нужно после каждого вызова делать проверки.
>нужно после каждого вызова делать проверки
Ну приходится. Но работает ведь?
Что полезного даёт это самое PDO, кроме экстеншенов из коробки? Я без сарказма, действительно интересно.
- mysql_* функции не поддерживают подготовленные запросы: http://php.net/manual/ru/mysqli.quickstart.prepared-statements.php
- Нет транзакций
- Нет и не будет поддержки новых фич из MySQL 5, так как расширение разрабатывалось давно
- Нужны костыли для обнаружения ошибок
> Но работает ведь?
Пока что. Ты понимаешь, что его не поддерживают? Его не улучшают, не чинят, его полностью дропнули ради лучших аналогов.
+ PDO поддерживает относительно единообразный интерфейс для работы с разными СУБД (MySQL, SQLite, PostgreSQL), а mysql_* функции и mysqli - только в MySQL.
А ты уверен, что проблема именно в парсинге? Может быть задержка получается, когда ты выводишь данные на экран? Если у тебя там овер 9к строк. Или ьы не выводишь ничего, но все равно тормозит?
Спасибо за внимание.
Помните об этом когда вам будут нахваливать Го. (хотя справедливости ради, в Си такой функции нет, а Го позиционируется как замена Си).
У меня в айпадах и кредитах немного другие суммы получились.
http://ideone.com/48PevG
продолжай писать я по тебе проверяюсь
>А mysql-функции просто молчат, когда что-то пошло не так
PDO между прочим тоже молчит либо говорит что у тебя ошибка. При этом не говорят где. Тоесть отличий никаких.
>- mysql_* функции не поддерживают подготовленные запросы:
Эм, но ведь поддерживает.
>- Нет транзакций
Ненужны.
>- Нет и не будет поддержки новых фич из MySQL 5
Из которых действительно нужных фичь... Что вообще ввели 5 мускулы?
>- Нужны костыли для обнаружения ошибок
Но ты мог сам отследить ошибки, а тут работает вообще непонять как. Тоесть вроде и есть запрос, но всегда возникают сомнения что к чему.
>>856557
> + PDO поддерживает относительно единообразный интерфейс для работы с разными СУБД
Из которых всё равно все юзали только MySQL. А остальное юзали два с половиной зипстера для решения лабораторной.
Сорян, там 14 и 15 строку надо было местами поменять. Сначала считать сколько уже выплатил, а потом прибавлять сколько долга осталось.
http://ideone.com/skKyUm
Локально всё работало, а на идеон залил бажный код. Печально.
Кстати круто что у тебя payout отдельно идёт переменной, можно просчитать для разных возможностей не меняя код. Тоже думал так сделать, но тут постоянно критикуют за лишние переменные и строки.
Сделал задачи по приведению телефона к нормальному виду. Кстати я делал усложнённую версию и добавил в массив кучу того, что предложили в старых тредах. Так что хардкор и нежность.
http://ideone.com/QoBz84
Начал делать коммит и понял почему Ipad вышел неправильно. PHPstorm говорит что код не будет работать и ругается именно на строку где я считаю сколько осталось денег отдать банку. Уж не понимаю почему так.
задачка на дурака
Пришлось писать функцию для функции, интересно как правильно её делать, или другово решения нет?
http://ideone.com/Um19lL
Ты ведь имеешь в вижу mysqli? mysql-расширение уже устарело и не поддерживается.
Одни эксепшены уже фича, ради которой стоит переходить. Так как ты сэкономишь тонну времени на написании if (!$result) после каждого вызова mysql-функций.
Работа с плейсхолдерами в PDO сделана чуть удобней чем в mysqli.
Также, PDO может работать с другими БД кроме mysql.
А в чем, интересно, преимущества mysqli?
>>856882
>>- Нет транзакций
> Ненужны.
Тебе стоит получше изучить SQL наверно.
>>856879
В случае, если ты написал неправильный запрос, база данных вернет ошибку, PDO выбросит исключение с ее текстом, а mysqli - нет. Чтобы в mysqli увидеть причину, надо после каждой операции с БД писать if с проверкой результата. Я подозреваю что ты просто его не пишешь (то есть игнорируешь любые ошибки), потому что если бы ты писал, ты бы вряд ли так хорошо отзывался об mysqli.
Как я понимаю, mysqli не предназначен для использования напрямую. Ты должен сделать свой класс-драйвер, который будет преобразовывать ошибки в исключения, передавать плейсхолдеры в удобном формате и тд. Напрямую с mysqli очень неудобно работать, код громоздкий и много лишней писанины.
С PDO тоже впрочем будет удобнее работать через класс-обертку.
Очень странно что ты это не упоминаешь. Может ты и не работал с mysqli или использовал ее как-то неправильно?
Вот ты пишешь "не говорит, где ошибка", но случае ошибки в запросе mysql сообщает "... before xxx" то есть указывает точное место синтаксической ошибки.
Ты ведь имеешь в вижу mysqli? mysql-расширение уже устарело и не поддерживается.
Одни эксепшены уже фича, ради которой стоит переходить. Так как ты сэкономишь тонну времени на написании if (!$result) после каждого вызова mysql-функций.
Работа с плейсхолдерами в PDO сделана чуть удобней чем в mysqli.
Также, PDO может работать с другими БД кроме mysql.
А в чем, интересно, преимущества mysqli?
>>856882
>>- Нет транзакций
> Ненужны.
Тебе стоит получше изучить SQL наверно.
>>856879
В случае, если ты написал неправильный запрос, база данных вернет ошибку, PDO выбросит исключение с ее текстом, а mysqli - нет. Чтобы в mysqli увидеть причину, надо после каждой операции с БД писать if с проверкой результата. Я подозреваю что ты просто его не пишешь (то есть игнорируешь любые ошибки), потому что если бы ты писал, ты бы вряд ли так хорошо отзывался об mysqli.
Как я понимаю, mysqli не предназначен для использования напрямую. Ты должен сделать свой класс-драйвер, который будет преобразовывать ошибки в исключения, передавать плейсхолдеры в удобном формате и тд. Напрямую с mysqli очень неудобно работать, код громоздкий и много лишней писанины.
С PDO тоже впрочем будет удобнее работать через класс-обертку.
Очень странно что ты это не упоминаешь. Может ты и не работал с mysqli или использовал ее как-то неправильно?
Вот ты пишешь "не говорит, где ошибка", но случае ошибки в запросе mysql сообщает "... before xxx" то есть указывает точное место синтаксической ошибки.
>Тебе стоит получше изучить SQL наверно.
У транзакта слишком неявные.
>PDO выбросит исключение с ее текстом
Чот весь день вчера бился с ним. Не выкидывало вообще ничего! И вообще вёл себя так, будто всё отлично, хотя обычный Select whare выполнял с 0 возврата.
>Чтобы в mysqli увидеть причину, надо после каждой операции с БД писать if с проверкой результата.
Так этож круто. Написал что хочешь выдеть ошибку и она появится. Что делать в PDO я вообще непойму.
>Я подозреваю что ты просто его не пишешь (то есть игнорируешь любые ошибки)
setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
>С PDO тоже впрочем будет удобнее работать через класс-обертку.
Класс надо писать всякий раз как надо к базе обращаться... Странное определение удобства.
> передавать плейсхолдеры в удобном формате
Тут тоже странности, неправильно плэйсхолдер переал, тебе PDO тоже ничего не пишет...
>Может ты и не работал с mysqli или использовал ее как-то неправильно?
Работал, но пол года всего.
>mysql-расширение уже устарело и не поддерживается.
Раньше и сним работал, года 4.
>случае ошибки в запросе mysql сообщает "... before xxx" то есть указывает точное место синтаксической ошибки.
Это круто ведь.
> Написал что хочешь выдеть ошибку и она появится. Что делать в PDO я вообще непойму.
Включить выброс исключений достаточно (если у тебя отключен показ ошибок, то еще смотреть в логи).
Вот в итоге ты не разобрался толком как работает PDO или mysqli, и как включить отображение ошибок в пхп, а споришь.
> Класс надо писать всякий раз как надо к базе обращаться... Странное определение удобства.
Тогда найди готовую библиотеку.
>>случае ошибки в запросе mysql сообщает "... before xxx" то есть указывает точное место синтаксической ошибки.
> Это круто ведь.
Ты даже не понял, что я написал. Сервер MySQL (не расширение mysqli) возвращает ошибку, PDO преобразует ее в исключение, а mysqli сохраняет где-то внутри и надо специально вызвать функцию, чтобы ее получить.
В общем, у меня сложилось впечатление что тебе стоило бы начать с изучения основ PHP, как показать текст ошибки или исключения, как отлаживать код.
Всёравно неявные.
>>857066
>Вот в итоге ты не разобрался толком как работает PDO или mysqli, и как включить отображение ошибок в пхп, а споришь.
Всмысле, я код скинул по которому смотрю ошибки. Явно разобрался же.
>Тогда найди готовую библиотеку.
Это ещё более неудобно. Удобно, это когда берёшь и используешь. А тут костыли какие-то.
>Ты даже не понял, что я написал. Сервер MySQL (не расширение mysqli) возвращает ошибку, PDO преобразует ее в исключение, а mysqli сохраняет где-то внутри и надо специально вызвать функцию, чтобы ее получить.
Что ты такое говоришь? В PDO тоже надо писать PDO::ERRMODE_EXCEPTION иначе ты ничего не получишь! Тоекть профит о котором ты говорил, его просто нет.
>В общем, у меня сложилось впечатление что тебе стоило бы начать с изучения основ PHP, как показать текст ошибки или исключения, как отлаживать код.
Я пытаюсь понять в чём профтиты использования, но пока я вижу только костыли вместо преимуществ.
Выполняю код на пике 1, получаю пик 2.
Хули я неправильно сделал?
Композер вроде стоит с этой библиотекой.
>require "/path/to/autoload.php"
На гитхабе не было написано и я подумал, что большей ничего не нужно.
Что из этих путей туда писать?
А ещё говорят, что пхп для даунов, чтобы обоссоную библу подключить -надо ебаться 7 лет и переспросить 20 человек.
сделал так - заработало
поясните ещё за двойные слеши, когда их пишут?
> надо ебаться 7 лет и переспросить 20 человек.
Проще минут 15 потратить на документацию композера.
Высокоуровневый инструмент - не причина проблем. Ты не понимаешь как работает автозагрузка и ждёшь, что композер заработает, даже не используя его в своём коде. Всё, что тебе нужно сделать, это создать папку, перейти в неё, вбить там в консоли composer install либанейм, и подключить autoload.php из появившейся папки vendor. Это делается за секунд 10-15 без учёта времени установки пакетов.
>>857247
Сделай echo "aa\njj" и echo "aa\\njj", в первом случае PHP увидит \n (перенос строки), а во втором - обратный слеш, который используется в неймспейсах.
Добавляем задачу #13 к тяжелому бремени проверок опа задачек с айфонамирастудентамиобменниками: https://ideone.com/N7bizo .
У меня вопросы.
Правильно ли я поступил, что не делил методы на дневные и ночные, а в борьбе с копипастой соединил их, разделив логику кода через аргумент timesOfDay?
И нужно ли было решать отдельно для разных времен суток. Я вначале решил на все сутки, потом перечитал условие и подумал что ты не с проста акцентировал на ночь у солнечных панелей.
Собственно вот поиск мыла. Долго мучился именно с выводом в нормальном формате, а не в формате массива. Оп сделай пожалуйста задачи на двумерные массивы!
https://ideone.com/I3ZJt9
Тут «Grammar Nazi». Напиши скрипт, проверяющий текст на наличие злостных ошибок:
В общем как всегда 2 варианта.
str_replace
https://ideone.com/IZHbzC
а тут preg_replace
https://ideone.com/BcQcvB
Если вы думаете что я где-то затупил, и можно было избежать повторений - напишите. Сам я этого не вижу. preg_replace отказался работать с большой регуляркой, потому пришлось искать каждую опечатку отдельно.
Если ты сделал задачу про Grammar Nazi, сделай скрипт, которы вместо сообщения об ошибках будет молча их исправлять.
Ах, да. не делаю, потому-что в прошлых достаточно убрать [] и всё будет выводиться.
http://ideone.com/UrnxsA - Задачка про рост
Верно.
http://ideone.com/aFmBWG - Ответ на любой вопрос
Верно.
http://ideone.com/M16PXX - Генератор имен
Верно.
http://ideone.com/HiKPCB - В тылу врага
> Я не совсем понял, что значит доделать шифрование до ок уровня, поэтому просто добавил
шифровальные значения для остальных букв алфавита
Это и требовалось.
Все верно.
http://ideone.com/0kXt6Z - l33tspeak (не так-то просто оказалось подобрать коды к киррилическим букам, лол)
Все правильно.
http://ideone.com/r3hMnI - На словах я Лев Толстой
> echo "{$word1[mt_rand(1, count($word1))]} {$word2[mt_rand(1, count($word2))]} {$word3[mt_rand(1, count($word3))]} \n
Как-то длинно и запутенно, не стоило тут писать такое сложное выражение, а стоило наверо вынести в переменную.
Так как первые 2 строки повторяются, можно было поместить их в цикл из 2 шагов.
http://ideone.com/5iH5Lr - Палиндром
Тут тоже верно.
http://ideone.com/UrnxsA - Задачка про рост
Верно.
http://ideone.com/aFmBWG - Ответ на любой вопрос
Верно.
http://ideone.com/M16PXX - Генератор имен
Верно.
http://ideone.com/HiKPCB - В тылу врага
> Я не совсем понял, что значит доделать шифрование до ок уровня, поэтому просто добавил
шифровальные значения для остальных букв алфавита
Это и требовалось.
Все верно.
http://ideone.com/0kXt6Z - l33tspeak (не так-то просто оказалось подобрать коды к киррилическим букам, лол)
Все правильно.
http://ideone.com/r3hMnI - На словах я Лев Толстой
> echo "{$word1[mt_rand(1, count($word1))]} {$word2[mt_rand(1, count($word2))]} {$word3[mt_rand(1, count($word3))]} \n
Как-то длинно и запутенно, не стоило тут писать такое сложное выражение, а стоило наверо вынести в переменную.
Так как первые 2 строки повторяются, можно было поместить их в цикл из 2 шагов.
http://ideone.com/5iH5Lr - Палиндром
Тут тоже верно.
Ссылку подписывай. К чему кидаешь и зачем.
Если ты про задание, то это на переменные и вычисления.
Меня оп не проверяет ( видимо не любит тех кто подписывается.
>хорошо оплачиваемый
Это сколько в деньгах?
Просто не думаю что [хорошо оплачиваемый] возможно при [не знает про DI] и [держит логику в контроллерах].
мимо Symfony-страдалец за 30k
Я уже целых полгода работаю.
Если ты в Москве\Киеве работаешь за 30к рублей то у меня для тебя плохие новости.
Я работаю в Москве за 30к рублей, и сказанное тобой для меня не новости.
Я просто не знаю, сколько стоит зелёный джун.
...и если поскроллить hh.ru, то там не редкость и цифры в 20-25к для джунов.
А в основном 30-45к.
После ларавела где все легко и просто, это просто пиздец болото какое-то.
Стоит ли работать здесь и тратить свое фремя на изучение зенда или искать что-то получше?
Заебись тебе, меня в джумлу на стажировке окунали...
Мне надо записать в переменную типа строки код пхп страницы с хтмл вместе, как это делается?
А то я не знаю как создать новый файл((пхп)страницу) и что-бы там переменные под себя переписать не в ручную а само все делалось, но если ты не понял что я хочу и горишь желанием помочь, напиши мне на ящик: NN^anon.ananasov.prANUSyfm4andexPUNCTUMr`}Uu
Пишу имиджборд, изучал 3 недели. Мой пост прямо выше этого поста если что. можешь так-же на мыльцо написать, будем вместе думать
У меня проблема с выражением собственной мысли, хекка. Я могу тебе скинуть кусочек проекта, можешь глянуть что да как. может и поймёшь
> записать в переменную типа строки код пхп страницы с хтмл вместе
Вот про шаблоны почитай: http://www.phpinfo.su/articles/practice/shablony_v_php.html
https://gist.github.com/codedokode/a455bde7d0748c0a351a
Я просто слабо представляю, как это тестирование происходит. Например я хочу тестировать поиск файлов. За него отвечает класс SearchGateway и его метод getResults. Мне их нужно тестировать отдельно от всего приложения? Тоесть я создаю папку tests, в ней файл с класом SearchGatewayTest где я через require подключаю исходный клас SearchGateway и делаю что-то вроде:
public function testGetResults(){
$searchGateway = new SearchGateway();
$searchGateway->getResults($someString, $somePageNum, $someFilesPerPage);
}
Опустим здесь логику самого теста. Я все правильно понимаю? Но ведь в тестируемом класе может быть куча зависимостей, которые необходимо как-то эмулировать.
Или мне нужно как-то встроить класс с тестом в приложение и тестировать его в контексте всего проекта? (не знаю хорошо ли я объяснил, но думаю ты понял)
Ну и ещё - зацените змейку на php:
https://github.com/andrewcarteruk/phpsnake
>>852056
>>852104
>>854570
>>856331
>>856946
>>856969
>>856999
>>857445
>>857458
>>857492
Да у тебя нормально там почти всё, не ссы, делай дальше.
>А в чем, интересно, преимущества mysqli?
Фактически в том, что это тот же самый старый добрый mysql только с новыми свистелками. Видимо его прикрутили чтобы олдфагам было удобнее код переписать. Но таки обидно что поддержку старого выпилили. Уж очень быстро на нём всё проектировалось.
Ну очевидно что да, Вот только тогда часть кода [a-zA-Z] - вообще ненужна. Почему и спрашиваю.
Юнит-тесты преимущественно тестируют отдельный метод или класс, в изоляции от остального кода. Для этого либо выбирают такие классы, у которых нет зависимостей, либо делают моки/стабы (то есть классы-пустышки) и подсовывают вместо зависимостей - DI это позволяет, хотя иногда для этого приходится делать еще и интерфейс.
Мне не очень нравится идея с моками, так как это трудоемко и тестирует не всегда то, что нужно.
Если же у класса есть зависимости, то придется тестировать весь слой, зачастую вместе с базой данных. Это осложняет тестирование. Потому нам приходится предусматривать какие-то дополнительные меры, например, вставлять данные в базу перед тестом или использовать специальную тестовую базу с вбитыми тестовыми данными.
Код тестов обычно пишется так же как и реальный код для использования класса. Самый простой тест - просто вызвать метод чтобы убедиться что он хотя бы выполняется (smoke test - так назвали базовые тесты радиоаппаратуры, когда ее включали и смотрели не пойдет ли дым).
В твоем случае поиск файлов - это высокоуровневый сервис, опирающийся на низкоровневые классы и базу данных. Если тестировать его в изоляции (заменив например PDO на мок) то ты тестируешь не сам поиск, а скорее способность SearchGateway делать SQL запросы (иногда именно это и требуется, тестировать класс в изоляции, и тогда и нужны моки). В нашем случае поиск опирается на базу данных и без нее тестировать его бесполезно.
Потому чтобы протестировать интеграционным тестом этот класс, нам надо сделать примерно такой сценарий. Мы сначала проверяем, что поисковик ищет запрошенные данные и не ищет незапрошенные:
- внести в базу заранее подготовленные данные
- поискать слово, которое есть в этих данных и убедиться что результат содержит нужные объекты
- (негативный тест) поискать слово, которого нет в этих данных и убедиться что ни одного тестового объекта не найдено
- при желании почистить базу от тестовых данных
Также там еще при желании можно добавить тесты на обработку разных символов, а именно:
- тесты на регистронезависимость поиска
- тест на случай если поисковая строка содержит спецсимволы
- тест на пустую поисковую строку
Реализовать заполнение базы можно так:
1) начать транзакцию, вставить данные, провести тест, откатить транзакцию
2) сделать отдельную базу (можно для скорости не на реальном а на RAM-диске) и залить в нее заранее подготовленные тестовые данные (fixtures). Есть библиотеки, позволяющие подготавливать такие данные в виде конфигов. Их надо будет поддерживать и обновлять по мере доработки кода.
Вариант 1) проще в реализации, вариант 2) надежнее.
Юнит-тесты преимущественно тестируют отдельный метод или класс, в изоляции от остального кода. Для этого либо выбирают такие классы, у которых нет зависимостей, либо делают моки/стабы (то есть классы-пустышки) и подсовывают вместо зависимостей - DI это позволяет, хотя иногда для этого приходится делать еще и интерфейс.
Мне не очень нравится идея с моками, так как это трудоемко и тестирует не всегда то, что нужно.
Если же у класса есть зависимости, то придется тестировать весь слой, зачастую вместе с базой данных. Это осложняет тестирование. Потому нам приходится предусматривать какие-то дополнительные меры, например, вставлять данные в базу перед тестом или использовать специальную тестовую базу с вбитыми тестовыми данными.
Код тестов обычно пишется так же как и реальный код для использования класса. Самый простой тест - просто вызвать метод чтобы убедиться что он хотя бы выполняется (smoke test - так назвали базовые тесты радиоаппаратуры, когда ее включали и смотрели не пойдет ли дым).
В твоем случае поиск файлов - это высокоуровневый сервис, опирающийся на низкоровневые классы и базу данных. Если тестировать его в изоляции (заменив например PDO на мок) то ты тестируешь не сам поиск, а скорее способность SearchGateway делать SQL запросы (иногда именно это и требуется, тестировать класс в изоляции, и тогда и нужны моки). В нашем случае поиск опирается на базу данных и без нее тестировать его бесполезно.
Потому чтобы протестировать интеграционным тестом этот класс, нам надо сделать примерно такой сценарий. Мы сначала проверяем, что поисковик ищет запрошенные данные и не ищет незапрошенные:
- внести в базу заранее подготовленные данные
- поискать слово, которое есть в этих данных и убедиться что результат содержит нужные объекты
- (негативный тест) поискать слово, которого нет в этих данных и убедиться что ни одного тестового объекта не найдено
- при желании почистить базу от тестовых данных
Также там еще при желании можно добавить тесты на обработку разных символов, а именно:
- тесты на регистронезависимость поиска
- тест на случай если поисковая строка содержит спецсимволы
- тест на пустую поисковую строку
Реализовать заполнение базы можно так:
1) начать транзакцию, вставить данные, провести тест, откатить транзакцию
2) сделать отдельную базу (можно для скорости не на реальном а на RAM-диске) и залить в нее заранее подготовленные тестовые данные (fixtures). Есть библиотеки, позволяющие подготавливать такие данные в виде конфигов. Их надо будет поддерживать и обновлять по мере доработки кода.
Вариант 1) проще в реализации, вариант 2) надежнее.
Пара десятков книг по PHP - это перебор. Хватило бы одной-двух на всю жизнь, дальше всякие статьи в интернете, чтобы не оставать.
В Оп посте есть пара книг, других я не знаю. Из сайтов - php the right way, еженедельный PHP дайджест на хабре.
>В Оп посте есть пара книг,
Да, тут такое дело, что я их уже прочитал.
>еженедельный PHP дайджест на хабре.
Уже год как перестал читать. Там направление пошло в сторону "С ваи Джонни Ноксвиль, и сегодня мы будем писать велосипед для распарсивания массива 19мерной вложенности.", "Я написал функцию с 78 параметрами на вход, а вам слабо?!!!". Ну и какая-то непонятная тусовка там сложилась. В коментариях года три не видел ничего что можно было бы трактовать как обсуждение. Но в любом случае спасибо анон.
Я об этом дайджесте: https://habrahabr.ru/company/zfort/blog/312144/
Там списком даются разные новые вещи.
А, не знал что он так круто развился, спасибо. Буду его читать теперь.
>Об асинхронной обработке сигналов в PHP без тиков, реализованной в PHP 7.1.
То чувство, когда GoDaddy ещё даже 7 не накатил, а уже 7.1 все обсуждают.
<table border=0 align=center width=70%><caption><strong>Отработанные часы</strong></caption><tr><td><strong>name</strong></td><td><strong>Архангельск A572</strong></td></tr><tr><td><input name='name' value='Иванов Александр Викторович'></input></td><td><input name='Архангельск A572' value=''></input></td></tr><tr><td><input name='name' value='Петров Евгений Геннадьевич'></input></td><td><input name='Архангельск A572' value=''></input></td></tr><tr><td><input name='name' value='Сидоров Владимир Борисович'></input></td><td><input name='Архангельск A572' value=''></input></td></tr></table>
Из mysql выкусываются два нужных столбца и столько строк, сколько человек приписано к объекту. Данные можно редактировать. И теперь нужно записать их обратно. Проблема в том, что заранее нельзя сказать, сколько строк будет. Ну и имена тоже нужно как-то узнать. Допустим, я сделаю ещё одну кнопку, по которой данные из инпутов улетят в скрипт. Но я нифига не понимаю, как передать, к каким людям и объектам они относятся.
Просто или path задан или алиас, конечно нормально.
Условия и игра в кубики http://ideone.com/aUuBfw
>$compSum = ($compDice1 + $compDice2) > $anonSum = ($anonDice1 + $anonDice2)
Зачем так городить, когда у тебя уже есть к этому моменту $compSum и $anonSum? Сравнивай только их. А так всё нормально.
Понял, спасибо.
Не надо делать инпуты с одинаковыми именами так как PHP их перезапишет при разборе пришедших POST данных.
То есть если приходят данные вида
name=Иван&name=Петр
то в $_POST['name'] попадет только Петр.
В качестве name не надо использовать имена. Удобнее использовать идентификаторы, то есть name="hours[1349]"
PHP в таком случае при разборе POST данных соберет все значения в один массив.
Советую почитать мануал
- http://php.net/manual/ru/language.variables.external.php
- http://php.net/manual/ru/reserved.variables.post.php
И конечно мой урок по обработке форм https://github.com/codedokode/pasta/blob/master/forms.md
>>858311
> if ($anonSum = ($anonDice1 + $anonDice2) > $compSum = ($compDice1 + $compDice2)) {
Вот так писать не надо. Ты тут фактически совместил несколько действий: создание новых переменных и сравнение. Твой код надо записывать так:
$anonSum = ($anonDice1 + $anonDice2);
$compSum = ($compDice1 + $compDice2);
if ($anonSum > $compSum)
Либо так:
if (($anonDice1 + $anonDice2) > ($compDice1 + $compDice2))
В твоем варианте, где ты засунул в одну строку 3 действия, читаемость получается хуже, а у меня сразу видно сколько тут действий и в каком порядке они выполняются.
Хуже того, ты еще в каждой ветке ифа заново эти переменные вычисляешь.
Не надо делать инпуты с одинаковыми именами так как PHP их перезапишет при разборе пришедших POST данных.
То есть если приходят данные вида
name=Иван&name=Петр
то в $_POST['name'] попадет только Петр.
В качестве name не надо использовать имена. Удобнее использовать идентификаторы, то есть name="hours[1349]"
PHP в таком случае при разборе POST данных соберет все значения в один массив.
Советую почитать мануал
- http://php.net/manual/ru/language.variables.external.php
- http://php.net/manual/ru/reserved.variables.post.php
И конечно мой урок по обработке форм https://github.com/codedokode/pasta/blob/master/forms.md
>>858311
> if ($anonSum = ($anonDice1 + $anonDice2) > $compSum = ($compDice1 + $compDice2)) {
Вот так писать не надо. Ты тут фактически совместил несколько действий: создание новых переменных и сравнение. Твой код надо записывать так:
$anonSum = ($anonDice1 + $anonDice2);
$compSum = ($compDice1 + $compDice2);
if ($anonSum > $compSum)
Либо так:
if (($anonDice1 + $anonDice2) > ($compDice1 + $compDice2))
В твоем варианте, где ты засунул в одну строку 3 действия, читаемость получается хуже, а у меня сразу видно сколько тут действий и в каком порядке они выполняются.
Хуже того, ты еще в каждой ветке ифа заново эти переменные вычисляешь.
>Не надо делать инпуты с одинаковыми именами
Знаю, просто не стал возиться с именованием того, что потом всё равно переделывать.
Тут проблема, как это впихнуть в аякс. Ведь если просто поставить кнопку, то в пхп-скрипт улетят все данные из инпутов и страница перезагрузится. А мне хочется, чтобы не перезагружалась.
http://ideone.com/rBzEQW
После вопросительного знака не делает букву прописной, также почему-то два пробела между предложениями. Это неправильно.
>($offers) as $offer
Можно просто: $offers as $offer.
Почему у тебя "предложение" переведено как "offer"? Должно быть "sentence".
Довбрасываю, все что осталось до регулярок и перехожу к ним:
Палиндром http://ideone.com/Wd5fBF
Айпад в кредит http://ideone.com/E90Mea
ничего необычного, увеличение на единичку и изменение знака, ну можно еще вот так для читабельности -(++$i)
нет, именно так, как написал я, а вообще, да, надо будет переписать более очевидным образом, дождусь ОПа
ладна, пусть будут скобочки, я даже по psr то даже еще не заморачивался, набиваю руку, идите ка давайте спать, котики
>>psr
Если у тебя PhpStorm Сtrl+Alt+L -> выравнивает все по стандарту( выбранному ) Я гарантирую это!
Интерфейсы с тобою связаться хотят,
ООП не таков, каким кажется он,
Тестами каждый окружён.
Мне всё вокруг подвластно degug,
Сделать свой выбор должен ты сам,
Встреть свою судьбу.
Быть программистом королём,
Всех программистов королём,
Если дух твой силён,
Программистом королём.
P.S следуй в закреплённый или
www.google.com/spoiler]
>После вопросительного знака не делает букву прописной
Ага, добавил 'или' к регулярке и всё заработало. На самом деле по хорошему надо бы ещё восклицательный знак добавить ну и это вот всё, только хочется побыстрее к MVC перейти выполнив эти задания.
Внезапно выяснилось что хром сам зменяет все двойные пробелы на одинарные. Очень "Удобно." Написал тест с print_r и всё изменилось. Странно.
>($offers) as $offer
Можно просто: $offers as $offer.
>Почему у тебя "предложение" переведено как "offer"? Должно быть "sentence".
Это гугл транслэйт так перевёл. Я понимаю что это скорее предложение что то сделать чем предложение. Но альтернатив исать не стал.
> https://github.com/TheSidSpears/Students/blob/master/httpd.conf
Не надо вставлять целиком конфиг, где 99% никак не относится к задаче. В данном случае стоило бы вставить минимальный пример конфига виртуального хоста, то есть только блок VirtualHost. Например в дебиане/убунту, каждый хост описывается в отдельном файле в /etc/apache2/sites/available/ У тебя правда в конфиге вообще виртуальных хостов нет (ты на каждый проект будешь отдельный Апач запускать?), так что незачем было его вставлять, проще было в ридми вписать пару нужных строк.
https://github.com/TheSidSpears/Students/blob/master/students.sql#L31
К полю hash не помешал бы комментарий (hash VARCHAR NOT NULL COMMENT '...'), что там хранится и зачем.
https://github.com/TheSidSpears/Students/blob/master/.htaccess
Этот htaccess лишний
https://github.com/TheSidSpears/Students/blob/master/public/.htaccess#L3
Тут зачем-то IFModule, хотя ниже директивы уже идут без него
https://github.com/TheSidSpears/Students/blob/master/app/container.php#L18
> $container['json']=function ($c) {
> return new JSONLoader();
> $container['table']=function ($c) {
> return new StudentDataGateway($c['db']);
Тут лучше было назвать сервис аналогично классу, правило https://github.com/codedokode/pasta/blob/master/good-code.md#Не-называй-одну-и-ту-же-вещь-по-разному
https://github.com/TheSidSpears/Students/blob/master/app/Controllers/FrontController.php#L15
> @param array $container
Там не массив, а объект Pimple ведь. Соответственно надо этот класс (с учетом неймспейсов) прописать в тайп-хинте конструктора и в @param
> function Start(){
Имя функции пишется с маленькой буквы
https://github.com/TheSidSpears/Students/blob/master/app/Controllers/FrontController.php#L28
> header("Location: error?code=404");
После редиректа скрипт продолжает работать. Также, ты нарушаешь правила HTTP, при отсутствии страницы надо отдавать код 404, а не редирект. Вообще, я часто вижу такую ошибку, когда вместо отдачи страницы ошибки делается редирект. Это в каком-то учебнике так учат?
В твоем случае получается такое: мы просим страницу, нам говорят, она есть, но переехала. Мы открываем новый УРЛ - а там 404. Выглядит как сломанный сайт.
> $controller=new $controllerPath($this->c,$router);
А зачем мы роутер в контроллер передаем? Выгдядит немного подозрительно.
> $errorCode=$controller->$actionFunc();
> $controller->showView();
Обычно делают так, что экшен контрллера сразу же и страницу рендерит. В чем смысл разбивать одно действие на 2 метода, не очень понятно. Наоборот, это создает сложности, когда надо отдать не HTML страницу.
Насчет main/search - я бы там вообще не делал 2 отдельных УРЛ, а сделал бы один общий.
https://github.com/TheSidSpears/Students/blob/master/app/Controllers/MainController.php#L39
> if (in_array($_GET['sortBy']
> $sortBy=strval($_GET['sortBy']);
Ты проверяешь в массиве значение без strval, а используешь значение с strval. Не может ли из-за этого получиться способ обхода проверки? Или оно все равно в DB gateway еще проверяется?
В случае если зарегистрированный пользователь заходит на страницу регистрации, логичнее делать редирект например на главную с уведомлением. Но ошибка 403 конечно лучше чем ничего.
https://github.com/TheSidSpears/Students/blob/master/app/Controllers/ProfileController.php#L70
> $student=$this->c['table']->getStudentByHash($_COOKIE['hash']);
а почему это делается не через класс авторизации?
https://github.com/TheSidSpears/Students/blob/master/app/Controllers/ProfileController.php#L96
> Удаляет всё, что не 'name','sname','group_num','points','gender','email','b_year','is_resident','hash'
Лучше было написать "фильтрует поля по белому списку" - не надо писать сам список, так как он есть в коде и когда код будут править, список в комментарии могут забыть обновить.
> @param array $post Глобальная переменная $_POST
Лучше писать "данные из формы в виде ассоц. массива"
https://github.com/TheSidSpears/Students/blob/master/app/Controllers/ProfileController.php#L118
> header('Location: main?registerOk');
После редиректа у тебя скрипт продолжает работать
https://github.com/TheSidSpears/Students/blob/master/app/DataBase/StudentDataGateway.php#L22
> if (isset($find)) {
Для проверки на null правильнее использовать is_null() или === null, чтобы не сбивать с толку читателя.
> $rows = $this->db->prepare
Лучше было назвать $stmt, а не $rows, так как это объект подготовленного запроса.
https://github.com/TheSidSpears/Students/blob/master/app/DataBase/StudentDataGateway.php#L55
> if(!in_array($sortBy, $this->getColumns())){
> if ($sortBy=='hash') { //запрещаем сортировать по hash
Этот код все равно разрешает сортировать по hash. Проверка не сработает.
> public function getStudentByHash($hashFromCookie){
Переменную лучше назвать $hash, так как модель в MVC не должна знать, откуда к ней приходят данные, как будет использован этот метод и не должна знать ничего о куках. Она лишь знает что надо найти студента по хешу.
> }
> else{
Это пишется в 1 строку
https://github.com/TheSidSpears/Students/blob/master/app/DataBase/StudentDataGateway.php#L120
Комментарий к checkEmail запутанный. Лучше написать "проверяет, используется ли данный email кем-то, кроме, может быть, указанного в $id студента (если $id не пуст, если пуст - проверяет, используется ли email хоть кем-то)". Хотя тоже немного запутанно вышло.
> @return bool 'is e-mail in DB'
Это намекает тебе, как стоило бы назвать функцию - что-то вроде isEmailUsed
Кавычки в @return не нужны
> if($count>0){
> return true;
return $count > 0;
https://github.com/TheSidSpears/Students/blob/master/app/Exceptions/AuthException.php
Тут бекслеш лишний в начале
https://github.com/TheSidSpears/Students/blob/master/app/Exceptions/ConfigException.php
не уверен, что надо было расшифровывать коды, может быть лучше было вставить исходный идентификатор ошибки. по нему хотя бы гуглить можно.
> parent::__construct($message,$code=0,$previous = NULL);
Что значит $code = 0? Почему не просто 0?
> $fileContent=file_get_contents($filename,FILE_IGNORE_NEW_LINES);
У file_get_contents второй аргумент значит другое: http://php.net/manual/ru/function.file-get-contents.php
https://github.com/TheSidSpears/Students/blob/master/app/Helpers/Util.php#L17
> setToken
Лучше было назвать setCsrfToken, чтобы не гадать, что это за токен.
> $string=preg_replace($find, "<div class='finded_text'>$0</div>", $string);
есть тег mark для этого
https://github.com/TheSidSpears/Students/blob/master/app/Helpers/Util.php#L43
> $find=str_replace("/","\/",$find); //экранируем прямой слеш
preq_quote умеет это делать, если указать второй аргумент, см. мануал
https://github.com/TheSidSpears/Students/blob/master/app/Models/Student.php#L38
> if(isset($value) and ($value!=NULL)){
непонятно, что тут проверяет isset?
Вообще, конечно методы вроде addInfo - это открытый путь к уязвимостям, так как люди забывают делать фильтрацию и передают туда сразу $_POST. Гитхаб так взломали однажды (хоть он и на Руби написан).
https://github.com/TheSidSpears/Students/blob/master/app/Validators/StudentValidator.php#L66
> function __construct($table){
нужен тайп-хинт
Насчет валидатора - у тебя нет желания как-то сделать его более ООП? Например, добавить классы для элементарных валидаторов одного поля или для списка ошибок?
И форматирование страшноватое. Попробуй например этот код https://github.com/TheSidSpears/Students/blob/master/app/Validators/StudentValidator.php пропустить через phpformatter и сравни. Если ты используешь IDE - там есть форматирование одной кнопкой.
https://github.com/TheSidSpears/Students/blob/master/app/Authorization.php#L42
> setcookie('hash','',time()-3600);
тут тоже надо указывать path и httpOnly на всякий случай, а то получится другая кука.
https://github.com/TheSidSpears/Students/blob/master/app/Authorization.php#L5
Комментарий устарел.
> Если пользователь обращается к "site.ru/path/to/public", то браузер автоматически дописывает "/" в конце,
Это не браузер дописывает, а Апач редиректит при попытке открыть папку без слеша в конце. Браузер не может знать, как устроен сервер внутри и соответственно догадаться, что надо дописать слеш, не может.
Игнорировать просто так слеши не стоит, так как это влияет на разрешение (резолвинг) относительных УРЛ:
/page/ + url -> /page/url
/page + url -> /url
если я не путаю ничего (проверь!). У тебя есть такие относительные УРЛ и потому возможен баг.
https://github.com/TheSidSpears/Students/blob/master/app/views/forms/search_form.php#L5
> <input type='text' name='find'
Возможно тут лучше был бы type=search - в нем появляется крестик для очистки, а в андроиде по моему добавляется выпадающий список с историей поиска
> name="gender" value="m" <?= $s->gender ? ' checked ' : '' ?>>
А тут нет ошибки? $s->gender ведь не true/false.
Также, для пола/резидентсва стоит завести константы вроде Student::GENDER_MALE ( https://github.com/codedokode/pasta/blob/master/good-code.md#Используй-константы-когда-есть-выбор-из-нескольких-вариантов ), для резиденства можно использовать true/false либо константы.
> <div class="col-md-12 well">
> Вы успешно зарегистрировались
В бутстрапе есть классы вроде alert-success для сообщений.
> if( (isset($user->email)) and ($user->email==$student->email) ):
Лучше проверять наверно по hash или id как неизменному значению. А если используется правильный дата маппер с Identity Map, то можно просто писать $user === $student.
https://github.com/TheSidSpears/Students/blob/master/app/views/modules/table.php#L62
> <li class="active"><a href='#'><?=$i?>
Тут не должно быть тега ссылки, если она никуда не ведет.
> https://github.com/TheSidSpears/Students/blob/master/httpd.conf
Не надо вставлять целиком конфиг, где 99% никак не относится к задаче. В данном случае стоило бы вставить минимальный пример конфига виртуального хоста, то есть только блок VirtualHost. Например в дебиане/убунту, каждый хост описывается в отдельном файле в /etc/apache2/sites/available/ У тебя правда в конфиге вообще виртуальных хостов нет (ты на каждый проект будешь отдельный Апач запускать?), так что незачем было его вставлять, проще было в ридми вписать пару нужных строк.
https://github.com/TheSidSpears/Students/blob/master/students.sql#L31
К полю hash не помешал бы комментарий (hash VARCHAR NOT NULL COMMENT '...'), что там хранится и зачем.
https://github.com/TheSidSpears/Students/blob/master/.htaccess
Этот htaccess лишний
https://github.com/TheSidSpears/Students/blob/master/public/.htaccess#L3
Тут зачем-то IFModule, хотя ниже директивы уже идут без него
https://github.com/TheSidSpears/Students/blob/master/app/container.php#L18
> $container['json']=function ($c) {
> return new JSONLoader();
> $container['table']=function ($c) {
> return new StudentDataGateway($c['db']);
Тут лучше было назвать сервис аналогично классу, правило https://github.com/codedokode/pasta/blob/master/good-code.md#Не-называй-одну-и-ту-же-вещь-по-разному
https://github.com/TheSidSpears/Students/blob/master/app/Controllers/FrontController.php#L15
> @param array $container
Там не массив, а объект Pimple ведь. Соответственно надо этот класс (с учетом неймспейсов) прописать в тайп-хинте конструктора и в @param
> function Start(){
Имя функции пишется с маленькой буквы
https://github.com/TheSidSpears/Students/blob/master/app/Controllers/FrontController.php#L28
> header("Location: error?code=404");
После редиректа скрипт продолжает работать. Также, ты нарушаешь правила HTTP, при отсутствии страницы надо отдавать код 404, а не редирект. Вообще, я часто вижу такую ошибку, когда вместо отдачи страницы ошибки делается редирект. Это в каком-то учебнике так учат?
В твоем случае получается такое: мы просим страницу, нам говорят, она есть, но переехала. Мы открываем новый УРЛ - а там 404. Выглядит как сломанный сайт.
> $controller=new $controllerPath($this->c,$router);
А зачем мы роутер в контроллер передаем? Выгдядит немного подозрительно.
> $errorCode=$controller->$actionFunc();
> $controller->showView();
Обычно делают так, что экшен контрллера сразу же и страницу рендерит. В чем смысл разбивать одно действие на 2 метода, не очень понятно. Наоборот, это создает сложности, когда надо отдать не HTML страницу.
Насчет main/search - я бы там вообще не делал 2 отдельных УРЛ, а сделал бы один общий.
https://github.com/TheSidSpears/Students/blob/master/app/Controllers/MainController.php#L39
> if (in_array($_GET['sortBy']
> $sortBy=strval($_GET['sortBy']);
Ты проверяешь в массиве значение без strval, а используешь значение с strval. Не может ли из-за этого получиться способ обхода проверки? Или оно все равно в DB gateway еще проверяется?
В случае если зарегистрированный пользователь заходит на страницу регистрации, логичнее делать редирект например на главную с уведомлением. Но ошибка 403 конечно лучше чем ничего.
https://github.com/TheSidSpears/Students/blob/master/app/Controllers/ProfileController.php#L70
> $student=$this->c['table']->getStudentByHash($_COOKIE['hash']);
а почему это делается не через класс авторизации?
https://github.com/TheSidSpears/Students/blob/master/app/Controllers/ProfileController.php#L96
> Удаляет всё, что не 'name','sname','group_num','points','gender','email','b_year','is_resident','hash'
Лучше было написать "фильтрует поля по белому списку" - не надо писать сам список, так как он есть в коде и когда код будут править, список в комментарии могут забыть обновить.
> @param array $post Глобальная переменная $_POST
Лучше писать "данные из формы в виде ассоц. массива"
https://github.com/TheSidSpears/Students/blob/master/app/Controllers/ProfileController.php#L118
> header('Location: main?registerOk');
После редиректа у тебя скрипт продолжает работать
https://github.com/TheSidSpears/Students/blob/master/app/DataBase/StudentDataGateway.php#L22
> if (isset($find)) {
Для проверки на null правильнее использовать is_null() или === null, чтобы не сбивать с толку читателя.
> $rows = $this->db->prepare
Лучше было назвать $stmt, а не $rows, так как это объект подготовленного запроса.
https://github.com/TheSidSpears/Students/blob/master/app/DataBase/StudentDataGateway.php#L55
> if(!in_array($sortBy, $this->getColumns())){
> if ($sortBy=='hash') { //запрещаем сортировать по hash
Этот код все равно разрешает сортировать по hash. Проверка не сработает.
> public function getStudentByHash($hashFromCookie){
Переменную лучше назвать $hash, так как модель в MVC не должна знать, откуда к ней приходят данные, как будет использован этот метод и не должна знать ничего о куках. Она лишь знает что надо найти студента по хешу.
> }
> else{
Это пишется в 1 строку
https://github.com/TheSidSpears/Students/blob/master/app/DataBase/StudentDataGateway.php#L120
Комментарий к checkEmail запутанный. Лучше написать "проверяет, используется ли данный email кем-то, кроме, может быть, указанного в $id студента (если $id не пуст, если пуст - проверяет, используется ли email хоть кем-то)". Хотя тоже немного запутанно вышло.
> @return bool 'is e-mail in DB'
Это намекает тебе, как стоило бы назвать функцию - что-то вроде isEmailUsed
Кавычки в @return не нужны
> if($count>0){
> return true;
return $count > 0;
https://github.com/TheSidSpears/Students/blob/master/app/Exceptions/AuthException.php
Тут бекслеш лишний в начале
https://github.com/TheSidSpears/Students/blob/master/app/Exceptions/ConfigException.php
не уверен, что надо было расшифровывать коды, может быть лучше было вставить исходный идентификатор ошибки. по нему хотя бы гуглить можно.
> parent::__construct($message,$code=0,$previous = NULL);
Что значит $code = 0? Почему не просто 0?
> $fileContent=file_get_contents($filename,FILE_IGNORE_NEW_LINES);
У file_get_contents второй аргумент значит другое: http://php.net/manual/ru/function.file-get-contents.php
https://github.com/TheSidSpears/Students/blob/master/app/Helpers/Util.php#L17
> setToken
Лучше было назвать setCsrfToken, чтобы не гадать, что это за токен.
> $string=preg_replace($find, "<div class='finded_text'>$0</div>", $string);
есть тег mark для этого
https://github.com/TheSidSpears/Students/blob/master/app/Helpers/Util.php#L43
> $find=str_replace("/","\/",$find); //экранируем прямой слеш
preq_quote умеет это делать, если указать второй аргумент, см. мануал
https://github.com/TheSidSpears/Students/blob/master/app/Models/Student.php#L38
> if(isset($value) and ($value!=NULL)){
непонятно, что тут проверяет isset?
Вообще, конечно методы вроде addInfo - это открытый путь к уязвимостям, так как люди забывают делать фильтрацию и передают туда сразу $_POST. Гитхаб так взломали однажды (хоть он и на Руби написан).
https://github.com/TheSidSpears/Students/blob/master/app/Validators/StudentValidator.php#L66
> function __construct($table){
нужен тайп-хинт
Насчет валидатора - у тебя нет желания как-то сделать его более ООП? Например, добавить классы для элементарных валидаторов одного поля или для списка ошибок?
И форматирование страшноватое. Попробуй например этот код https://github.com/TheSidSpears/Students/blob/master/app/Validators/StudentValidator.php пропустить через phpformatter и сравни. Если ты используешь IDE - там есть форматирование одной кнопкой.
https://github.com/TheSidSpears/Students/blob/master/app/Authorization.php#L42
> setcookie('hash','',time()-3600);
тут тоже надо указывать path и httpOnly на всякий случай, а то получится другая кука.
https://github.com/TheSidSpears/Students/blob/master/app/Authorization.php#L5
Комментарий устарел.
> Если пользователь обращается к "site.ru/path/to/public", то браузер автоматически дописывает "/" в конце,
Это не браузер дописывает, а Апач редиректит при попытке открыть папку без слеша в конце. Браузер не может знать, как устроен сервер внутри и соответственно догадаться, что надо дописать слеш, не может.
Игнорировать просто так слеши не стоит, так как это влияет на разрешение (резолвинг) относительных УРЛ:
/page/ + url -> /page/url
/page + url -> /url
если я не путаю ничего (проверь!). У тебя есть такие относительные УРЛ и потому возможен баг.
https://github.com/TheSidSpears/Students/blob/master/app/views/forms/search_form.php#L5
> <input type='text' name='find'
Возможно тут лучше был бы type=search - в нем появляется крестик для очистки, а в андроиде по моему добавляется выпадающий список с историей поиска
> name="gender" value="m" <?= $s->gender ? ' checked ' : '' ?>>
А тут нет ошибки? $s->gender ведь не true/false.
Также, для пола/резидентсва стоит завести константы вроде Student::GENDER_MALE ( https://github.com/codedokode/pasta/blob/master/good-code.md#Используй-константы-когда-есть-выбор-из-нескольких-вариантов ), для резиденства можно использовать true/false либо константы.
> <div class="col-md-12 well">
> Вы успешно зарегистрировались
В бутстрапе есть классы вроде alert-success для сообщений.
> if( (isset($user->email)) and ($user->email==$student->email) ):
Лучше проверять наверно по hash или id как неизменному значению. А если используется правильный дата маппер с Identity Map, то можно просто писать $user === $student.
https://github.com/TheSidSpears/Students/blob/master/app/views/modules/table.php#L62
> <li class="active"><a href='#'><?=$i?>
Тут не должно быть тега ссылки, если она никуда не ведет.
Прошел курс доброанона на http://archive-ipq-co.narod.ru/
Подскажите, пожалуйста, что учить дальше?
Хтмл, цсс прошел тоже на код-академии.
Хочу сделать сайт.
Где понятно написано о создании вэб-сервера и про хттп протокол?
а вот, нашел у него же
http://archive-ipq-co.narod.ru/tsuzuke.html
годные ссылки или что-то другое посоветовали бы?
Ссылки годные, но как видишь много что устарело лет эдак на 6. Спрашивай в трэдик если что, тут помогут. Либо я , либо ОП, либо добрый анон.
ну как я понял нужно сейчас изучить:
1) html checked
2) http протокол нет
3) css, конкретнее bootstrap в процессе
4) js
5) хз что по жс
6) в питоне как создавать htmlсервер, как обрабатывать запросы, формы и куки
7) работа с базами данных в php
В верном направлении иду, или нет?
PDO собственно крутая штука которая позволяет из PHP работать с большинством если не со всеми БД. Ничего особого учить не надо. Выучи как создавать БД, как обновлять\удалять\выбирать записи. Вроде ты должен был это елать когда выполнял список студентов из задачника опа.
>А Yii - это модный Фреймворк?
Yii Yii2 до сих пор востребованны Laravel учить, много кому из работодателей она нужна. Ну и писать на ней легко и просто, как говорят.
основы БД знаю. ER-диаграммы, больше теоретическую часть, так сказать.
а, вообще говоря, есть разница при работе с разными БД? с MySQL и mongodb? или там эта разность меня ебать не должна, т.к. я делаю sql-запросы?
>SET. После этого ключевого слова должен идти список полей таблицы, которые будут обновлены и непосредственно сами новые значения полей в виде:
>имя поля='значение'
>Следующий пример производит обновление поля country у ВСЕХ записей в таблице users:
>UPDATE `users` SET `country`='Russia'
Получается, `country` - это и есть имя поля? Но где оно в таблице?
https://confluence.jetbrains.com/display/PhpStorm/PHP+Code+Sniffer+in+PhpStorm
https://www.jetbrains.com/help/phpstorm/2016.2/configuring-php-namespaces-in-a-project.html
Видел я это всё, как открыть сеттингс? В менюшках его нет. Где искать не написано.
Поля читай как "переменные", они не хранятся в таблице.
И заметь `country` - обрамляются в ОБРАТНЫЕ кавычки, только поля. Можно и без них кстате, через точку - BDname.feeld_name = value
То есть, "поле" эквивалентно "столбцу"/"column"?
>обрамляются в ОБРАТНЫЕ кавычки, только поля
С этими кавычками я уже чуть не поехал. Это как описание самурая без меча, который подобен самураю с мечом, но только без меча.
В Софтобанке тысяча теряется: должно быть 61270р, как и в задаче про Айфон.
>$strawberryBank = countSum(1.02, 0, 39999, 5000) + 7777;
ОП, помнится, говорил, что 7777 надо изначально прибавлять и рассчитывать кредит уже с этой суммой. Ведь у анона нет денег, он, получается, и на эту сумму берёт кредит, лолка.
function send($id , $message)
{
$url = 'https://api.vk.com/method/messages.send';
$params = array(
'user_id' => $id, // Кому отправляем
'message' => $message, // Что отправляем
'access_token' => 'token', // access_token
'v' => '5.37',
);
// В $result вернется id отправленного сообщения
$result = file_get_contents($url, false, stream_context_create(array(
'http' => array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => http_build_query($params)
)
)));
}
send($idx, "проверка");
Латиницу отправляет норм. ЧТо за хуйня?
Дальше уроки на которые стоят ссылки тут http://archive-ipq-co.narod.ru/l1/reading-list.html
То есть потихоньку подходи к задаче про студентов.
> css, конкретнее bootstrap в процессе
Лучше просто CSS изучать, у нас в ОП посте есть задачи по ним.
>>858927
поля - это колонки таблицы.
ЛОлблядь, сам php файл был не в utf 8. Ну пиздец.
У меня друг начал изучать пхп и когда я у него спросил какие там переменные он сказал что она там только одна и это меня очень сильно смутило тип как так ......
Он наверное имел в виду что тип нельзя указать переменной. И она тут у нас такая одна - неявно типизированная
>>859220
Допёр . Прост друг как то так объяснил , что мне показалось что прям вот выделить переменную под что то нельзя и увидел в этом полнейший бред , но подумал что полюбому это не так и есть всему объяснение ...
но конечно эти ваши интернетные коды уххх....
вот не то что нормальные человеческие , ну там всякие джава с с+ рубик )))))))))))))
Толстовато
Ты прав.
У тебя связь многие ко многим. Тут будет 3 таблицы.
User<--User_Room->Room
В User_Room будет хранится id пользователя и комнаты.
>но любой пользователь в любой момент может перезагрузить страницу, и каждый раз будут дополнительные запросы к базе данных ради проверки
Для этого придумали кэширование запросов.
Сколько сидел, думал, а так решить и не смог.
Решить, все делаю как в уроке, но проблемы с командой умножения. Я уже много решений перепробовал.
>echo "( $x $x )\n";
Когда ты выводишь строку, выражение внутри него не выполняется, потому что это уже строка.
Сначала нужно выполнить выражение, а потом его выводить.
//Выполняем выражение
$answer = $x $x;
//Выводим строку. ($x $x) - это строка!
echo "($x $x ) = $answer \n"
Молодец. Ещё добавлю что строка выводиться потому что ты берешь выражение в кавычки. Т.е если бы ты написал без них echo $x ✱ $x; то вывелся бы ответ.
Спасибо за помощь, теперь буду знать.
^_^
В задании про калькулятор есть код кнона, но нет кода опа. Так и должно быть?
Смотрю сейчас код калькулятор куна. И в голове мысль о том, что я кодю уже несколько недель, а даже не понимаю что тут написано.
Что такое abstract class ? Что такое __construct? Что вообще за $this-> ? В итоге из всего кода я понял только паттерн регулярки.
Как-то грустно становится что за 3 недели я узнал так мало, хоть и честно выполнял все задачи опа сам.
Нужно ли использовать классы Symphony, например Request или FileUploaded?
Symfony
> Нужно ли использовать классы Symphony, например Request или FileUploaded?
Не шути, анон, конечно же нужно, зачем тогда фреймворк берёшь если будешь по старинке суперглобальные переменные юзать? В доках по Silex'у всё-равно частенько будут мелькать фразы вроде "Для того, чтобы ознакомится детальнее с этим компонентом, почитайте о нём в документации Symfony".
Зачем тогда тогда нужен микрофреймворк Silex, если я использую функционал Symfony?
Что-то у тебя там с квадрилионами не так - что это и откуда?
Числа переводит неправильно либо просто ты что-то там спутал.
>Что такое __construct? Что вообще за $this-> ?
Это объектно-ориентированное программирование, следующая тема, которая будет. Там и написано, что калькулятор на ООП.
Блииииин. Пойдё исправлять.
>>860591
>можно ли такое показывать на собеседовании
Я бы не стал. Там много чего не так, начиная с сомнительной реализации ActiveRecord заканчивая смешанной с кодом верстки.
>Лень было писать кучу проверок, это скучно и никому по сути не нужно
Вот это не понял, вроде бы валидатор у тебя нормальный.
ActiveRecord я даже не знаю что это?
>смешанной с кодом верстки
Вот это проблема. Так и не придумал куда это деть. С одной стороны в код верстку вставлять нельзя, с другой стороны кто то говорил что логику отображения крайне не желательно вставлять в шаблоны. Что тут делать, не понятно. Ну сейчас посмотрю как другие делали.
>валидатор у тебя нормальный
К нему много чего нужно дописать. Да и в строку поиска можно СКЛ код вставить.
Ты ООП изучал? Если нет, то подожди, когда дойдешь до главы про ООП, тогда и вернись к коду.
>>860375
Silex использует некоторые компоненты из Symfony, потому если и придется читать мануал, то только по ним, а не по всей симфони.
> Нужно ли использовать классы Symphony, например Request или FileUploaded?
Это классы из HttpFoundation и они используются и в slilex и symfony.
>>860461
Sliex это микрофреймворк, созданный на основе нескольких компонентов симфони. Симфони содержит в себе компоненты, которые не привязаны к ней намертво, а которые можно использовать отдельно, что авторы Силекса и делают (и ты кстати при желании тоже можешь их использовать).
Silex намного проще чем сам Симфони.
>>860590
Ну не, надо сделать проверки. К тому же я бы не сказал, что их там так уж много - обычно это 30-40 строчек занимает.
>>860606
> Да и в строку поиска можно СКЛ код вставить.
Тогда тебе рановато сдавать код на проверку. Нельзя
такой код писать.
>>860712
Этот паттерн имеет тот недостаток, что смешивает в одном классе много функциональности:
- хранение информации о студенте
- работа с БД
- валидация
- может еще какие-то вспомогательные функции
Модели в AR получаются громоздкие. В учебном приложении лучше бы учиться разделять функционал на отдельные классы, а не смешивать.
>>860591
> `local` enum('местный','иногородний') NOT NULL,
Лучше использовать латинские идентификаторы. Мы ведь все равно их не выводим пользователю, а используем только как идентификатор.
email в качестве PRIMARY KEY плохая идея так как его можно поменять. Если будут какие-то другие таблицы, ссылающиеся на таблицу студентов - придется как-то менять значения и в них, что неудобно. Вообще, первичный ключ все-таки лучше никогда не менять.
Потому тут стоит использовать либо естественный ключ - хеш либо добавить искуственный id.
В SQL дампе не должно быть команд создания базы данных.
Желательно сделать отдельную папку для публичных файлов, а не вываливать весь код в публичную папку.
Валидировать лучше не массив неизвестной структуры, а модель студета. Иначе твой валидатор заточен только на работу с формой и им нельзя например проверить данные из базы.
> $vld = new Validator();
Зачем так сокращать? Лучше писать $validator. IDE все равно использует автодополнение так что печатать это второй раз не придется.
> $disp->DisplayIndexTop();
> $disp->DisplayTable($abtrList);
> $disp->DisplayIndexBot();
Контроллер не должен разбираться, как вывести страницу и из каких частей она состоит. Вызов для вывода страницы должен быть один.
https://github.com/ghp26/Students/blob/master/src/Abiturient.php#L7
Тут надо использовать DI, а не делать так, что каждая модель подключается к базе сама. Настройки соединения с БД надо вынести в доступный для пользователя конфиг.
> private $name, $surname, $sex, $groupId, $email, $balls, $birth, $local;
Надо писать каждое свойство отдельной строчкой, так требует PSR и в твоем варианте нельзя прокомментировать свойства.
https://github.com/ghp26/Students/blob/master/src/Abiturient.php#L21
Имена методов пишутся с маленькой буквы.
> public function Save(){
> if ($_COOKIE["MuhosranskUniversity"]) {
Модель ничего не должна знать про куки. Перечитай внимательно урок по MVC https://github.com/codedokode/pasta/blob/master/arch/mvc.md
> public function CreateNew($arr) {
У тебя тут расчет что массив содержит все нужные поля. Но вообще, массив POST может и не содержать их или содержать массивы вместо строк например. Нужно сделать чтобы код не выдавал ошибок в такой ситуации.
> public function GetAllAbiturients() {
Наверно удобнее возвращать массив объектов, а не массив массивов непонятной структуры.
Твоя система авторизации никак не защищает от регистрации чужих данных.
https://github.com/ghp26/Students/blob/master/src/Displayer.php
тут не должно быть HTML кода, он должен быть в шаблонах.
> $searchDiv = str_replace("%srcValue%", $_POST["searchValue"], $searchDiv);//вернуть значение поиска обратно в поле
Это XSS уязвимость. Перечитай урок про нее. Также, View не должен обращаться к POST переменным.
Изобретать свой шаблонизатор не требуется. Можно либо использовать имеющийся в PHP функционал, либо подключить готовый шаблонизатор. Урок http://www.phpinfo.su/articles/practice/shablony_v_php.html
Более того, твой код в Displayer - это сплошная копипаста. Ты почему-то даже не попытался оптимизировать его за счет цикла. Это плохо, не надо копипастить однотипный код, надо думать, как без этого обойтись.
> $editorPage = str_replace("%groupId%", $abtrData['3'],
> $abtrData['3'],
Вот это тоже плохо. Как я должен догадываться, под каким номером идет какое поле? Более того, если мы в базу данных добавим поле, эти номера могут поменяться. Такой ненадежный код использовать неправильно.
> if (strlen($valueArray['email'])>100)
strlen считает не число букв, а число байт (буква в utf8 может занимать несколько байт). Неправильно ее тут использовать.
> $errArray[2] = "Фамилия должна быть не больше 100 символов"
Неправильно использовать тут числовые индексы так как непонятно что они обозначают.
CSS код надо вынести в отдельный CSS файл.
В общем, над задачей надо поработать. А именно:
- привести оформление в соответствие с PSR
- лучше сделать разделение на части в соответствие с архитектурой MVC
- сделать защищенную авторизацию, не позволяющую редактировать чужие данные
- сделать лучшее разделение на классы в соответствие с принципами ООП, использовать DI
- сделать защиту от XSS, CSRF
- добавить HTML5 валидацию в форме
- убрать часть данных из публичной папки
Перечитай комментарии к задаче, там много полезной информации.
Ты ООП изучал? Если нет, то подожди, когда дойдешь до главы про ООП, тогда и вернись к коду.
>>860375
Silex использует некоторые компоненты из Symfony, потому если и придется читать мануал, то только по ним, а не по всей симфони.
> Нужно ли использовать классы Symphony, например Request или FileUploaded?
Это классы из HttpFoundation и они используются и в slilex и symfony.
>>860461
Sliex это микрофреймворк, созданный на основе нескольких компонентов симфони. Симфони содержит в себе компоненты, которые не привязаны к ней намертво, а которые можно использовать отдельно, что авторы Силекса и делают (и ты кстати при желании тоже можешь их использовать).
Silex намного проще чем сам Симфони.
>>860590
Ну не, надо сделать проверки. К тому же я бы не сказал, что их там так уж много - обычно это 30-40 строчек занимает.
>>860606
> Да и в строку поиска можно СКЛ код вставить.
Тогда тебе рановато сдавать код на проверку. Нельзя
такой код писать.
>>860712
Этот паттерн имеет тот недостаток, что смешивает в одном классе много функциональности:
- хранение информации о студенте
- работа с БД
- валидация
- может еще какие-то вспомогательные функции
Модели в AR получаются громоздкие. В учебном приложении лучше бы учиться разделять функционал на отдельные классы, а не смешивать.
>>860591
> `local` enum('местный','иногородний') NOT NULL,
Лучше использовать латинские идентификаторы. Мы ведь все равно их не выводим пользователю, а используем только как идентификатор.
email в качестве PRIMARY KEY плохая идея так как его можно поменять. Если будут какие-то другие таблицы, ссылающиеся на таблицу студентов - придется как-то менять значения и в них, что неудобно. Вообще, первичный ключ все-таки лучше никогда не менять.
Потому тут стоит использовать либо естественный ключ - хеш либо добавить искуственный id.
В SQL дампе не должно быть команд создания базы данных.
Желательно сделать отдельную папку для публичных файлов, а не вываливать весь код в публичную папку.
Валидировать лучше не массив неизвестной структуры, а модель студета. Иначе твой валидатор заточен только на работу с формой и им нельзя например проверить данные из базы.
> $vld = new Validator();
Зачем так сокращать? Лучше писать $validator. IDE все равно использует автодополнение так что печатать это второй раз не придется.
> $disp->DisplayIndexTop();
> $disp->DisplayTable($abtrList);
> $disp->DisplayIndexBot();
Контроллер не должен разбираться, как вывести страницу и из каких частей она состоит. Вызов для вывода страницы должен быть один.
https://github.com/ghp26/Students/blob/master/src/Abiturient.php#L7
Тут надо использовать DI, а не делать так, что каждая модель подключается к базе сама. Настройки соединения с БД надо вынести в доступный для пользователя конфиг.
> private $name, $surname, $sex, $groupId, $email, $balls, $birth, $local;
Надо писать каждое свойство отдельной строчкой, так требует PSR и в твоем варианте нельзя прокомментировать свойства.
https://github.com/ghp26/Students/blob/master/src/Abiturient.php#L21
Имена методов пишутся с маленькой буквы.
> public function Save(){
> if ($_COOKIE["MuhosranskUniversity"]) {
Модель ничего не должна знать про куки. Перечитай внимательно урок по MVC https://github.com/codedokode/pasta/blob/master/arch/mvc.md
> public function CreateNew($arr) {
У тебя тут расчет что массив содержит все нужные поля. Но вообще, массив POST может и не содержать их или содержать массивы вместо строк например. Нужно сделать чтобы код не выдавал ошибок в такой ситуации.
> public function GetAllAbiturients() {
Наверно удобнее возвращать массив объектов, а не массив массивов непонятной структуры.
Твоя система авторизации никак не защищает от регистрации чужих данных.
https://github.com/ghp26/Students/blob/master/src/Displayer.php
тут не должно быть HTML кода, он должен быть в шаблонах.
> $searchDiv = str_replace("%srcValue%", $_POST["searchValue"], $searchDiv);//вернуть значение поиска обратно в поле
Это XSS уязвимость. Перечитай урок про нее. Также, View не должен обращаться к POST переменным.
Изобретать свой шаблонизатор не требуется. Можно либо использовать имеющийся в PHP функционал, либо подключить готовый шаблонизатор. Урок http://www.phpinfo.su/articles/practice/shablony_v_php.html
Более того, твой код в Displayer - это сплошная копипаста. Ты почему-то даже не попытался оптимизировать его за счет цикла. Это плохо, не надо копипастить однотипный код, надо думать, как без этого обойтись.
> $editorPage = str_replace("%groupId%", $abtrData['3'],
> $abtrData['3'],
Вот это тоже плохо. Как я должен догадываться, под каким номером идет какое поле? Более того, если мы в базу данных добавим поле, эти номера могут поменяться. Такой ненадежный код использовать неправильно.
> if (strlen($valueArray['email'])>100)
strlen считает не число букв, а число байт (буква в utf8 может занимать несколько байт). Неправильно ее тут использовать.
> $errArray[2] = "Фамилия должна быть не больше 100 символов"
Неправильно использовать тут числовые индексы так как непонятно что они обозначают.
CSS код надо вынести в отдельный CSS файл.
В общем, над задачей надо поработать. А именно:
- привести оформление в соответствие с PSR
- лучше сделать разделение на части в соответствие с архитектурой MVC
- сделать защищенную авторизацию, не позволяющую редактировать чужие данные
- сделать лучшее разделение на классы в соответствие с принципами ООП, использовать DI
- сделать защиту от XSS, CSRF
- добавить HTML5 валидацию в форме
- убрать часть данных из публичной папки
Перечитай комментарии к задаче, там много полезной информации.
Для обозначения пола и места жительства логично завести константы в модели, как описано тут: https://github.com/codedokode/pasta/blob/master/good-code.md#Используй-константы-когда-есть-выбор-из-нескольких-вариантов
Спасибо за объемный фидбек. Сейчас поисправляю.
>Желательно сделать отдельную папку для публичных файлов, а не вываливать весь код в публичную папку.
А что такое публичные файлы?
Постигаю ООП, с понятиями и всем остальным вроде разобрался. Но при этом мой код - та же процедурщина, просто глобальные переменные и функции имеющие нечто общее теперь рассованы по классам. Раньше было
$a = 5
$b = 2
function sum(a,b) {return a+b}
Теперь
class Calc() {
...
public static function sum() {return this.a+this.b}
}
Ну и так далее, я думаю каждый постигший дзен с этим сталкивался. Как уйти от "процедурного" ООП к настоящему
Файлы, которые раздает сервер и к которым можно обратиться снаружи.
Прочитай внимательно комментарии к задаче про студентов, там это упоминается. https://github.com/codedokode/pasta/blob/master/student-list.md#Выносим-код-за-корень-сервера
>>860833
Надо для начала проектировать, из каких классов будет состоять приложение, и за что каждый отвечает. Если ты видел например задачи про Вектор или Кошки-мышки в момем учебнике - там именно это и требуется, причем без ООП код получается гораздо хуже и запутаннее.
Твой пример прокомемнтировать не получится, так как для функции сложения 2 чисел ООП не нужен. Нужен пример сложнее, где было бы оправданно применение ООП.
Пока вот это смог написать http://ideone.com/HjhRws
>$x + 1000
Что это означает? Это никуда не сохраняется и вообще не имеет смысла. Любое выражение должно записывать результат куда-либо, а тут этого нет.
Вообще тут удобнее использовать цикл while: пока сумма баланса не станет больше или равной миллиону.
А если через for, то во втором действии просто плюсовать единицу к году.
Вот что тебе надо:
1. Сумма баланса делится на сто и умножается на десять - получается текущий процент.
2. Этот текуший процент просто прибавляется к текущей же суме баланса.
3. Выводится в echo.
*сумме
На уровне идеи, каждый объект можно описать как тебе хочется
класс Человек
{
обработатьРечь(звук) {}
ответить() {}
}
Всё, дальше расширяй и наследуй как тебе хочется
ООП я бы сказал это философия помогающая смотреть на вещи под правильным углом, чтобы проще потом их было выражать
Оптимизировать базу и запросы, 270 000 записей это немного.
>>850047
Не знаю, можешь попробовать параллельно смотреть и то, и другое, а потом сделать выводы.
>>850289
Файл со скриптом в какой кодировке? файл с текстом? Должны быть оба в utf-8 без BOM. Также, надо указать кодировку браузеру либо в заголовке Content-Type, либо в метатеге meta charset.
Проверить заголовки можно в отладчике браузера (ctrl + shift + I) на вкладке network.
>>850417
Ты имеешь в виду как настроить веб-сервер на твоем домашнем компьютере, чтобы он был доступен из интернета? Для этого надо получить у провайдера так называемый "белый" IP адрес, видимый снаружи. По умолчанию, многие провайдеры помещают клиентов за NAT, так, что напрямую из интернета с твоим компьютером соединиться нельзя. Получения "белого" адреса (обычно это платно) выставляет твой компьютер наружу, но надо понимать что он становится доступен и для всяких атак извне.
Ну и разумеется, компьютер должен быть постоянно включен и ты не должен его перезагружать, а то сайт будет недоступен.
Также, если поискать, можно найти какие-то варианты обойтись без "белого" адреса. Ну например, если твой провайдер выдает тебе динамический, но глобально доступный IP адрес, можно использовать dyndns.
Вообще, проще наверно найти хостинг (бывают даже бесплатные, на Западе можно найти бесплатный хостинг без рекламы погуглив "free web hosting") и загрузить свой сайт туда.
> 2. Старый оп покинул этот тред?
Нет, просто у него много дел и он не может круглосуточно сидеть в треде, а заходит периодически.
>>850614
нужно повозиться, тогда фреймворк изучать будет намного легче.
Оптимизировать базу и запросы, 270 000 записей это немного.
>>850047
Не знаю, можешь попробовать параллельно смотреть и то, и другое, а потом сделать выводы.
>>850289
Файл со скриптом в какой кодировке? файл с текстом? Должны быть оба в utf-8 без BOM. Также, надо указать кодировку браузеру либо в заголовке Content-Type, либо в метатеге meta charset.
Проверить заголовки можно в отладчике браузера (ctrl + shift + I) на вкладке network.
>>850417
Ты имеешь в виду как настроить веб-сервер на твоем домашнем компьютере, чтобы он был доступен из интернета? Для этого надо получить у провайдера так называемый "белый" IP адрес, видимый снаружи. По умолчанию, многие провайдеры помещают клиентов за NAT, так, что напрямую из интернета с твоим компьютером соединиться нельзя. Получения "белого" адреса (обычно это платно) выставляет твой компьютер наружу, но надо понимать что он становится доступен и для всяких атак извне.
Ну и разумеется, компьютер должен быть постоянно включен и ты не должен его перезагружать, а то сайт будет недоступен.
Также, если поискать, можно найти какие-то варианты обойтись без "белого" адреса. Ну например, если твой провайдер выдает тебе динамический, но глобально доступный IP адрес, можно использовать dyndns.
Вообще, проще наверно найти хостинг (бывают даже бесплатные, на Западе можно найти бесплатный хостинг без рекламы погуглив "free web hosting") и загрузить свой сайт туда.
> 2. Старый оп покинул этот тред?
Нет, просто у него много дел и он не может круглосуточно сидеть в треде, а заходит периодически.
>>850614
нужно повозиться, тогда фреймворк изучать будет намного легче.
http://ideone.com/n6X69v
установил ini_set('max_execution_time', 90000);
и сделал sleep(3600) после каждой итерации цикла. Не работает. Срабатывает не через час как задумано, а через 5 минут. Когда я ставлю sleep(60) все работает как и должно. Что за хуйня, аноны?
И да, через крон не хочу, хочу так.
> сделал sleep(3600) после каждой итерации цикла. Не работает. Срабатывает не через час как задумано, а через 5 минут.
Эм... Тогда зачем ты поставил 3600 милисекунд?
cron
http://ideone.com/0RcleA
Какой-нибудь пруф плз. Сам нагуглить не могу.
Попробовал сейчас
time_sleep_until(time()+3600);
но в этот раз было не 2 итерации а вообще только одна. говно какое-то.
Код переписал, спасибо.
Извини, я так и не понял почему не работает код перед exit.
http://ideone.com/kanmFx
>Вообще, первичный ключ все-таки лучше никогда не менять.
Почему? Вроде все работает если поменять.
Потому что первичный ключ это идентификатор и ссылки на него могут быть в других таблицах, в файлах, в логах. Искать и как-то их менять сложно, неудобно и не всегда возможно.
Чё-т я запутался, браток, но вот так работает верно: http://ideone.com/KGMfzl
Сам что-то не пойму, почему не идёт на последнюю итерацию с "=".
Может, кто объяснит.
Нашёл тут свой калькулятор, который делал 275 счастливых дней назад, когда думал, что программирование - это вполне себе легко.
ОП, зачем нужно поле number?
Реализовал и чтение и добавление комментов, но необходимости в нём не увидел
Со строкой вида "002.019" прокатывает ++$string, но в первом случае происходит перевод в integer и возвращается (int) 20
https://github.com/TheSidSpears/FileHosting/blob/master/src/classes/FilesFileManager.php#L11
> $uploaddir=$_SERVER['DOCUMENT_ROOT'].$uploadUri.$file->path;
> не полагайся на DOCUMENT_ROOT, он например не работает в консоли. Вообще, всю работу с путями стоит вынести в какой-то отдельный метод.
Вместо DOCUMENT_ROOT хранить путь вида "D:/xampp/htdocs/path/to/project" в конфиге?
> https://github.com/TheSidSpears/FileHosting/blob/master/src/classes/Helpers/Helper.php
> Форматирование ужасное
В чём именно?
фикс. Ответ на >>846554
Наверно оно задумывалось чтобы получить номер для нового вставляемого комменатрия (SELECT MAX(number) WHERE parentId = ..). Если ты можешь без него и если запросы укладываются в индекс, то наверно незачем и добавлять его.
> Вместо DOCUMENT_ROOT хранить путь вида "D:/xampp/htdocs/path/to/project" в конфиге?
Проще определять этот путь через __DIR__ например в бутстрап-скрипте или в какой-то функции.
>> Форматирование ужасное
> В чём именно?
Не соответствует PSR. Скобки после класса и функции ставятся на новой строке, между функциями стоит оставлять 1 пустую строку. Можешь вставить код на phpformatter.com и посмотреть что он там исправит.
Удоно написать 2 вспомогательные функции:
- первая преобразует путь в массив целых чисел
- вторая создает путь из массива целых чисел
Тогда ты сможешь задействовать стандартные функции рабоыт с массивом.
Разумеется это все лучше инкапсулировать внутри какого-то класса - внешнему коду знать про подробности организации комменатриев в дерево не нужно.
Привел бы пример кода. А так могу пока только в мануал отправить: http://php.net/manual/ru/language.oop5.paamayim-nekudotayim.php
>>861426
case '' может быть? case null? case 0? Или что в твоем понимании значит "пустой"? зависит от того, какое там значение.
Пустой, в моём вопросе означало "Содержит пустую строку." инчае говоря
$op='';
Спасибо за помощь. Вот мой код.
http://ideone.com/KGMfzl
Кстати я понял почему не выполнялось условие =. Потому-что на = надо проверять $char, а я проверял по очевидным причинам $op.
Молодец. Мало кто так серьезно относится к кроссбраузерности. Имей в виду что если надо быстро проверить верстку, есть еще страница на сайте МС:
https://developer.microsoft.com/en-us/microsoft-edge/tools/
https://developer.microsoft.com/en-us/microsoft-edge/tools/screenshots/
(увы, IE7 там уже нету).
Jenkins ставь на сервер, вноси туда время, и забудь о sleepах в php как о страшном сне. Все так делают, это стандарт на фирмах, вечно выполняющися скрипт никто не делает.
Я последовал вашим рекомендациям из урока по верстке под ie. Больше всего меня удивило, что майкрософт сами не заботятся о кроссбраузерности своих же браузеров. Скачать с их сайта мне так и не удалось, пришлось самому искать ссылку на удалённое скачивание с их сайта.
12 часов многовато, я по 8-9 на работе в день пишу, потом уже ничего не сображаю. За день одна-две небольшие фичи это норма, 12 тасков это ты разбежался, оптимист. Если пишешь нормальный читаемый объектно-ориентированный код с SOLID принципами, выверенными на скорость запросами в ДБ и юнит-тестами, то и вообще может по 2 дня уходить на небольшой тикет. Времени у тебя может больше уходить из-за кривой архитектуры, т.е. если все со всем связано, код повторяется и все классы не имеют четко обозначенных ролей.
Индексы ставить, юзать javascript и ajax, выводить по 500 штук максимум, при прокрутке или по кнопке грузить новые 500 штук, старые при этом стирать из браузера.
CGI скрипты гугли, там и C++ и С.
>Есть смысл на другие языки смотреть (C++, Java) или существенного выигрыша не будет?
GD - это и есть C++, просто команда от PHP передаётся ему через интерпретатор, а он обратно возвращает картинку. Хотя мжет я что-то путаю. В любом случае надо проверить, может ты напишешь что-то в 100500 раз быстрее и мощнее
В CLI max_execution_time по умолчанию выключен, включать его незачем (или надо ставить 0). sleep работает нормально, гораздо больше вероятность что ты где-то накосячил или администратор сервера прибивает долго работающие скрипты.
А вообще делать надо через крон. Если нищехостинг это не позволяет, то вряд ли он позволит тебе запускать и долгоживующие скрипты.
>>861740
Jenkins как замена крону выглядит как минимум странно.
>>861742
У МС сейчас позиция, что есть новый браузер Edge, а старые они потихоньку хотят хоронить.
Я еще помню, когда-то был сервис (xenocode), который позволял упаковывать приложения вместе с библиотеками и он в качестве своей рекламы предлагал браузеры, включая ИЕ, запакованные так, что они не требовали установки и можно было запустить хоть несколько версий одновременно, но потом они из перестали распространять.
Я сам сейчас погуглил, действительно, ИЕ7 или 8 скачать непросто, и он доступен не под все версии ОС. Если не получится их установить, можно наверно тогда ограничиться ИЕ9 и выше (для их установки понадобится семерка). Также, тут https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/ предлагаются образы вирутальных машин от МС начиная с ИЕ8.
Я сам когда-то собирал себе образы на основе какой-то "урезанной" версии винды с рутрекера, так как она занимала меньше места чем официальный образ.
>>859437
Я бы советовал не вариться в собственном соку, а показывать код или может обсуждать общую архитектуру чтобы избежать каких-то типичных ошибок, которые делают начинающие. Также могу посоветовать комментарии к задаче про студентов, там много полезных советов: https://github.com/codedokode/pasta/blob/master/student-list.md
>>861747
Для начала стоило бы изучить, что именно сколько времени занимает. Если у тебя основные задержки это скачивание файлов то может можно как-то поменять алгоритм или распараллелить процесс. Gd и Curl сами по себе на Си так что их ускорять бессмысленно.
>>861748
Не перекатились.
В CLI max_execution_time по умолчанию выключен, включать его незачем (или надо ставить 0). sleep работает нормально, гораздо больше вероятность что ты где-то накосячил или администратор сервера прибивает долго работающие скрипты.
А вообще делать надо через крон. Если нищехостинг это не позволяет, то вряд ли он позволит тебе запускать и долгоживующие скрипты.
>>861740
Jenkins как замена крону выглядит как минимум странно.
>>861742
У МС сейчас позиция, что есть новый браузер Edge, а старые они потихоньку хотят хоронить.
Я еще помню, когда-то был сервис (xenocode), который позволял упаковывать приложения вместе с библиотеками и он в качестве своей рекламы предлагал браузеры, включая ИЕ, запакованные так, что они не требовали установки и можно было запустить хоть несколько версий одновременно, но потом они из перестали распространять.
Я сам сейчас погуглил, действительно, ИЕ7 или 8 скачать непросто, и он доступен не под все версии ОС. Если не получится их установить, можно наверно тогда ограничиться ИЕ9 и выше (для их установки понадобится семерка). Также, тут https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/ предлагаются образы вирутальных машин от МС начиная с ИЕ8.
Я сам когда-то собирал себе образы на основе какой-то "урезанной" версии винды с рутрекера, так как она занимала меньше места чем официальный образ.
>>859437
Я бы советовал не вариться в собственном соку, а показывать код или может обсуждать общую архитектуру чтобы избежать каких-то типичных ошибок, которые делают начинающие. Также могу посоветовать комментарии к задаче про студентов, там много полезных советов: https://github.com/codedokode/pasta/blob/master/student-list.md
>>861747
Для начала стоило бы изучить, что именно сколько времени занимает. Если у тебя основные задержки это скачивание файлов то может можно как-то поменять алгоритм или распараллелить процесс. Gd и Curl сами по себе на Си так что их ускорять бессмысленно.
>>861748
Не перекатились.
https://github.com/never3ver/students_list/blob/master/public/index.php
Тут ошибка, что число студентов (и страниц) вычисляется без учета поискового слова.
> .okbutton{
> position: relative;
> margin-top: 70px;
> margin-bottom: -40px;
Очень странное позиционирование: зачем втягивать нижелжащий контент на 40px вверх?
https://github.com/never3ver/students_list/blob/master/app/StudentValidator.php#L20
Тут в имени группы можно указать более 5 символов. Регулярка проверяет не всю строку, а только ее часть.
> if (!preg_match("/(19|20)[0-9]{2}/"
> if ((!preg_match("/[0-9]{1,3}/", $student->score))
То же самое, нет привязки к краям строки
> if (!filter_var($student->email, FILTER_VALIDATE_EMAIL)) {
Имей в виду, что это не пропустит email вида i%'FvanANUSпоч#KOтаPUNCTUML#Oрф с нелатинским доменом.
> $errors['email'] .= " Введенный email уже используется";
> .=
Это не вызывает ошибки о попытке обращения к несуществующему элементу массива? Чтобы что-то приписать к строке, надо ведь сначала прочесть ее из массива.
https://github.com/never3ver/students_list/blob/master/app/Helper.php#L11
> preg_match("/$word/ui"
Нельзя просто так подставлять произвольную строку в регулярку так как в ней могут быть спецмисволы которые вызовут ошибку синтаксиса (например если это строка "+++"). Нужно экранировать спецсимволы с помощью preg_quote().
https://github.com/never3ver/students_list/blob/master/app/Authorization.php#L40
> public function logIn(Student $student) {
> if (!$student->cookie) {
Эта функция залогинит студента только если у него еще не сгенерирована кука. Залогинить студента с проставленной кукой не получится. Нелогично как-то, надо либо переименовать (и выдавать ошибку для непустого поля cookie) либо переделать.
https://github.com/never3ver/students_list/blob/master/templates/editForm.html#L31
> <input type="radio" name ='sex' value="<?=Student::GENDER_MALE?>" required checked='checked'>
Тут странно что радиокнопка всегда включена. Стандарт позволяет указать несколько кнопок включенными одновременно? Не стоит полагаться на поведение браузеров, оно может поменяться, надо делать максимально надежный код.
Также, ты ставишь атрибут required на радиокнопках - а как он применяется - к блоку радиокнопок в целом или к одной конкретной? Такие моменты стоит перепроверять, вдруг окажется что атрибут required значит, что именно эта конкретная кнопка должна быть нажата.
Баг: я ввел при регистрации год 1900, а он сохранился в БД и выводится как 0000.
Также, можно ввести год из будущего, например, 2090.
Вместо "Редактировать" лучше написать "Редактировать мои/ваши данные".
https://github.com/never3ver/students_list/blob/master/public/index.php
Тут ошибка, что число студентов (и страниц) вычисляется без учета поискового слова.
> .okbutton{
> position: relative;
> margin-top: 70px;
> margin-bottom: -40px;
Очень странное позиционирование: зачем втягивать нижелжащий контент на 40px вверх?
https://github.com/never3ver/students_list/blob/master/app/StudentValidator.php#L20
Тут в имени группы можно указать более 5 символов. Регулярка проверяет не всю строку, а только ее часть.
> if (!preg_match("/(19|20)[0-9]{2}/"
> if ((!preg_match("/[0-9]{1,3}/", $student->score))
То же самое, нет привязки к краям строки
> if (!filter_var($student->email, FILTER_VALIDATE_EMAIL)) {
Имей в виду, что это не пропустит email вида i%'FvanANUSпоч#KOтаPUNCTUML#Oрф с нелатинским доменом.
> $errors['email'] .= " Введенный email уже используется";
> .=
Это не вызывает ошибки о попытке обращения к несуществующему элементу массива? Чтобы что-то приписать к строке, надо ведь сначала прочесть ее из массива.
https://github.com/never3ver/students_list/blob/master/app/Helper.php#L11
> preg_match("/$word/ui"
Нельзя просто так подставлять произвольную строку в регулярку так как в ней могут быть спецмисволы которые вызовут ошибку синтаксиса (например если это строка "+++"). Нужно экранировать спецсимволы с помощью preg_quote().
https://github.com/never3ver/students_list/blob/master/app/Authorization.php#L40
> public function logIn(Student $student) {
> if (!$student->cookie) {
Эта функция залогинит студента только если у него еще не сгенерирована кука. Залогинить студента с проставленной кукой не получится. Нелогично как-то, надо либо переименовать (и выдавать ошибку для непустого поля cookie) либо переделать.
https://github.com/never3ver/students_list/blob/master/templates/editForm.html#L31
> <input type="radio" name ='sex' value="<?=Student::GENDER_MALE?>" required checked='checked'>
Тут странно что радиокнопка всегда включена. Стандарт позволяет указать несколько кнопок включенными одновременно? Не стоит полагаться на поведение браузеров, оно может поменяться, надо делать максимально надежный код.
Также, ты ставишь атрибут required на радиокнопках - а как он применяется - к блоку радиокнопок в целом или к одной конкретной? Такие моменты стоит перепроверять, вдруг окажется что атрибут required значит, что именно эта конкретная кнопка должна быть нажата.
Баг: я ввел при регистрации год 1900, а он сохранился в БД и выводится как 0000.
Также, можно ввести год из будущего, например, 2090.
Вместо "Редактировать" лучше написать "Редактировать мои/ваши данные".
>Также, тут https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/ предлагаются образы вирутальных машин от МС начиная с ИЕ8.
Cейчас скачиваю образ с ie8 под семерку. Между версией под xp и 7 ведь нету своих особенностей?
Можно не проверять, а сделать чтобы по умолчанию была обычная отправка формы, а при наличии JS и поддержки нужных технологий событие отправки формы бы перехватывалось и данные как-то отправлялись бы через JS.
>>851250
Для показа контента с другого домена можно использовать либо ифрейм, либо JSONP, либо кроссдоменный аякс-запрос.
Что касается авторизации, наверно для конкретной страницы можно сделать исключение.
>>851255
Спасибо, исправил. У меня есть скрипт проверки правописания, но он работает только в одном репозитории и не проверяет код.
>>851335
Тут можно писать покороче:
$a[] = $word1[array_rand($word1)];
Так как первая и вторая строка генеируются одинаково, то можно использовать цикл из 2 повторений для них.
Также, можно попробовать сгенерировать весь стих циклом. Мы сначала делаем массив массивов (то есть массив, cодержащий варианты выбора первого слова, второго слова итд), а потом проходим циклом по нему и генерируем стих:
$structure = [$word1, $word2, $word3, ["\n"], ...];
Можно не проверять, а сделать чтобы по умолчанию была обычная отправка формы, а при наличии JS и поддержки нужных технологий событие отправки формы бы перехватывалось и данные как-то отправлялись бы через JS.
>>851250
Для показа контента с другого домена можно использовать либо ифрейм, либо JSONP, либо кроссдоменный аякс-запрос.
Что касается авторизации, наверно для конкретной страницы можно сделать исключение.
>>851255
Спасибо, исправил. У меня есть скрипт проверки правописания, но он работает только в одном репозитории и не проверяет код.
>>851335
Тут можно писать покороче:
$a[] = $word1[array_rand($word1)];
Так как первая и вторая строка генеируются одинаково, то можно использовать цикл из 2 повторений для них.
Также, можно попробовать сгенерировать весь стих циклом. Мы сначала делаем массив массивов (то есть массив, cодержащий варианты выбора первого слова, второго слова итд), а потом проходим циклом по нему и генерируем стих:
$structure = [$word1, $word2, $word3, ["\n"], ...];
Я придумал еще такой ваиант: делаем массив, описывающий структуру стиха (то есть варианты выбора для каждого слова), проходим по нему циклом и генерируем стих:
$structure = [$words1, $words2, $words3, ["\n"], ...];
>>851463
Его не надо запоминать. Если разобрать принципы, по которым он написан (как он разбит на классы, за что отвечает каждый класс, как они связаны), то сам код запоминать не требуется, ООП код можно анализировать на уровне классов, не опускаясь до кода в них.
Так что изучай ООП, MVC, делай задачу про студентов и потихоньку начнешь это понимать.
>>851467
Если ты не понимаешь этот код, то тебе надо изучать с начала HTML, CSS, JS, jQuery, HTTP. Быстро тут не объяснить.
>>851923
Можно и так, хотя по моему получилось сложновато, лучше было бы отдельные слова получать в отдельных строчках, а не писать все в одну длинную строку.
>>851965
хорошо, надеюсь ты задачу про кредит решил с первого раза с такой-то удачей.
>>852005
Можно, надо только с настройками разобраться.
>>852018
Гит с фтп никак не взаимодействует.
>>852052
Нормально.
Я придумал еще такой ваиант: делаем массив, описывающий структуру стиха (то есть варианты выбора для каждого слова), проходим по нему циклом и генерируем стих:
$structure = [$words1, $words2, $words3, ["\n"], ...];
>>851463
Его не надо запоминать. Если разобрать принципы, по которым он написан (как он разбит на классы, за что отвечает каждый класс, как они связаны), то сам код запоминать не требуется, ООП код можно анализировать на уровне классов, не опускаясь до кода в них.
Так что изучай ООП, MVC, делай задачу про студентов и потихоньку начнешь это понимать.
>>851467
Если ты не понимаешь этот код, то тебе надо изучать с начала HTML, CSS, JS, jQuery, HTTP. Быстро тут не объяснить.
>>851923
Можно и так, хотя по моему получилось сложновато, лучше было бы отдельные слова получать в отдельных строчках, а не писать все в одну длинную строку.
>>851965
хорошо, надеюсь ты задачу про кредит решил с первого раза с такой-то удачей.
>>852005
Можно, надо только с настройками разобраться.
>>852018
Гит с фтп никак не взаимодействует.
>>852052
Нормально.
Задачка про доллары http://ideone.com/86CmmQ
Все верно.
Игра в кубики http://ideone.com/OjJpCM
> elseif ($sumManThrow = $sumAIThrow) {
тут можно было не писать условие, а просто написать else.
А так, все верно.
> Миллион в банке http://ideone.com/93sy0B
> $starterMoney+($starterMoney(10/100));
Тут вместо числа 10 стоило использовать переменную $percent.
Считает верно.
Школьник и кредит на айфон http://ideone.com/AuZYfX
> if ($oversum>5000){
> elseif($oversum<5000){
А что, если ровно 5000?
> $credit+$commission+($credit($percent/100));
Это выражение там раза 3 повторяется. Попробуй убрать копипасту, например, вынеся его в отдельную переменную или сразу прибавив к долгу.
> $credit=($credit+$commission+($credit*($percent/100)))-$oversum;
Если мы тут подставим oversum то получится что там выражение вычитается из точно такого же выраждения и проще было сразу написать ноль.
Ответ верный, но код слишком усложнен. Можно упростиь.
Задачка про доллары http://ideone.com/86CmmQ
Все верно.
Игра в кубики http://ideone.com/OjJpCM
> elseif ($sumManThrow = $sumAIThrow) {
тут можно было не писать условие, а просто написать else.
А так, все верно.
> Миллион в банке http://ideone.com/93sy0B
> $starterMoney+($starterMoney(10/100));
Тут вместо числа 10 стоило использовать переменную $percent.
Считает верно.
Школьник и кредит на айфон http://ideone.com/AuZYfX
> if ($oversum>5000){
> elseif($oversum<5000){
А что, если ровно 5000?
> $credit+$commission+($credit($percent/100));
Это выражение там раза 3 повторяется. Попробуй убрать копипасту, например, вынеся его в отдельную переменную или сразу прибавив к долгу.
> $credit=($credit+$commission+($credit*($percent/100)))-$oversum;
Если мы тут подставим oversum то получится что там выражение вычитается из точно такого же выраждения и проще было сразу написать ноль.
Ответ верный, но код слишком усложнен. Можно упростиь.
> Средняя оценка. http://ideone.com/1ELpFU
Верно.
> Сколько выше анона человек http://ideone.com/I9STv2
Правильно.
> Ответ на любой вопрос http://ideone.com/885RFf
> $random=array_rand ($answers, 2);
не очень понятно, зачем брать 2 случайных ответа, но работает в общем верно.
>>852132
Для любых поисков/замен/разбиения текста, где просто str_replace не хватает.
HTML, JSON и другие языки для которых есть парсеры, лучше ими не парсить.
>>852183
В ОП посте есть пара хороших, не совсем для начинающих и не очень новых.
>>852585
Не знаю.
> Если я просто нажму стар дебагинг - ничего не происходит,
Скорее всего он запускает скрипт в командной строке и вдобавок может быть останавливает его на первой строке. Или же может это режим когда ты должен руками вставить нужную ссылку в браузер. Надо смотреть документацию чтобы понять.
>можно было не писать условие, а просто написать else.
Исправил (Тут понятно что исправил незначительную деталь, пожтому не буду тебя лишний раз нагружать кодом. )
>Тут вместо числа 10 стоило использовать переменную $percent.
Исправил.
>А что, если ровно 5000?
Вероятность крайне мала, но добавил в обработку.
>Попробуй убрать копипасту, например, вынеся его в отдельную переменную или сразу прибавив к долгу.
Поправил. Впринципе всё как ты сказал, если нет времени не смотри.
http://ideone.com/2mhFHe
>проще было сразу написать ноль.
Страшно же, вдруг ошибусь в расчётах, а это как раз покажет что ошибся.
>не очень понятно, зачем брать 2 случайных ответа,
По другому не работает. Я думал что он берёт 2 параметра из массива, ключ и значение ключа.
> Скобки после класса и функции ставятся на новой строке
А это критично? Я просто привык уже ставить скобки так
>>861710
Видимо, я не понял суть. Вот будет у нас массив array(1,1,1,19), полученный с помощью первой ф-ии. Нам нужно сделать ++19 и вернуть его в виде валидной строки с помощью второй ф-ии. Так вот как будет происходить процесс замены 20 на "020" внутри этой ф-ии? В этом как-то помогут стандартные функции работы с массивом?
> Скобки после класса и функции ставятся на новой строке
>А это критично? Я просто привык уже ставить скобки так
В приличных IT компаниях, такое может вызварь разрыв тимлидера. И я не шучу.
Что еще можно проверить?
Я хочу выделять красным цветом поля в которые пользователь ввел неправильные значения. Но в треде мне сказали что
а) настройки стилей должны лежать в отдельном ЦСС-файле.
Б) ЦСС/ХТМЛ кода в моих контролерах быть не должно.
Вопрос: как мне выделять красным определенные поля формы, если php-код в css файле не работает? А если я загружу CSS файл в стринг и в нем исправлю какие то строки, то нарушу требования MVC.
Ну у меня есть массив с ошибками, и я хочу проверять наличие в нем элементов с какими нибудь ключами и выделять соответствующие поля формы.
Ну например если ErrorsArray['name'] существует то background-color у inputa с именем "name" сделать красным.
Такой был план.
добавляешь свои стили в цсс класс, а класс применяешь к элементу в зависимости от того, есть ли ошибка или нет.
Блин, элементарно же. Спасибо, Анон.
>Jenkins как замена крону выглядит как минимум странно.
Чому странно? Уже в третьей компании сталкиваюсь, что все кронжобы в дженкинсе по табам прописаны, и /etc/crontab вообще не используется. В последней компашке даже заставили оставшиеся кронжобы в дженкинс перевозить. Плюсы налицо - дженкинс кладет в лог для каждого билда весь вывод, красит неудачные билды, можно по истории билдов потом смотреть, где что не так пошло. Еще в кронжобах из php мы тогда [START], [INFO] и [ERROR] тэги используем при выводе, дженкинс соответственно их правильно обрабатывает, по цветам и табам раскидывает.
Не переживай, оп тут, вон же вверху анонам отвечает. Скоро и до тебя дойдет. Не жди опа, а решай дальше всегда.
>>А что, если ровно 5000?
> Вероятность крайне мала, но добавил в обработку.
Надо писать так:
if ($x > 5000) { ...
} else { ..
Тогда вопросов нет - видно, что все возможные варианты проверены. А когда ты пишешь
if ($x > 5000) { ...
} elseif ($x < 5000) { ..
Тогда при чтении кода появляется вопрос - а почему пропущен случай с 5000? Не важно, большая или маленькая вероятность, что попадется такое число, код вверху выглядит логичнее.
> Поправил. Впринципе всё как ты сказал, если нет времени не смотри.
Код внутри веток if/elseif довольно похожий. Нельзя ли оставить только одну копию кода? Также подумай, не удобнее ли тут использовать функции min/max для определения размера выплаты.
>>проще было сразу написать ноль.
> Страшно же, вдруг ошибусь в расчётах, а это как раз покажет что ошибся.
да, это хорошая идея.
>>не очень понятно, зачем брать 2 случайных ответа,
> По другому не работает
Работает, перечитай мануал по этой функции.
>>861777
>> Скобки после класса и функции ставятся на новой строке
> А это критично? Я просто привык уже ставить скобки так
Если каждый будет писать, как ему нравится, в коде будет бардак. Лучше сейчас привыкнуть писать правльно. Смотри второй пост в треде.
> Видимо, я не понял суть. Вот будет у нас массив array(1,1,1,19), полученный с помощью первой ф-ии. Нам нужно сделать ++19 и вернуть его в виде валидной строки с помощью второй ф-ии. Так вот как будет происходить процесс замены 20 на "020" внутри этой ф-ии?
- берем существующий путь и разбиваем на массив чисел
- увеличиваем последнее на 1
- собираем новый путь из массива
За добавление нулей отвечает функция сборки пути из массива чисел. Она получает на вход массив чисел и возвращает правильно отформатированную строку.
Этот подход позже позволит легко поменять алгоритм записи пути, например, убрать точки (чтобы место не занимали) или использовать более плотный бинарный формат хранения чисел.
>>А что, если ровно 5000?
> Вероятность крайне мала, но добавил в обработку.
Надо писать так:
if ($x > 5000) { ...
} else { ..
Тогда вопросов нет - видно, что все возможные варианты проверены. А когда ты пишешь
if ($x > 5000) { ...
} elseif ($x < 5000) { ..
Тогда при чтении кода появляется вопрос - а почему пропущен случай с 5000? Не важно, большая или маленькая вероятность, что попадется такое число, код вверху выглядит логичнее.
> Поправил. Впринципе всё как ты сказал, если нет времени не смотри.
Код внутри веток if/elseif довольно похожий. Нельзя ли оставить только одну копию кода? Также подумай, не удобнее ли тут использовать функции min/max для определения размера выплаты.
>>проще было сразу написать ноль.
> Страшно же, вдруг ошибусь в расчётах, а это как раз покажет что ошибся.
да, это хорошая идея.
>>не очень понятно, зачем брать 2 случайных ответа,
> По другому не работает
Работает, перечитай мануал по этой функции.
>>861777
>> Скобки после класса и функции ставятся на новой строке
> А это критично? Я просто привык уже ставить скобки так
Если каждый будет писать, как ему нравится, в коде будет бардак. Лучше сейчас привыкнуть писать правльно. Смотри второй пост в треде.
> Видимо, я не понял суть. Вот будет у нас массив array(1,1,1,19), полученный с помощью первой ф-ии. Нам нужно сделать ++19 и вернуть его в виде валидной строки с помощью второй ф-ии. Так вот как будет происходить процесс замены 20 на "020" внутри этой ф-ии?
- берем существующий путь и разбиваем на массив чисел
- увеличиваем последнее на 1
- собираем новый путь из массива
За добавление нулей отвечает функция сборки пути из массива чисел. Она получает на вход массив чисел и возвращает правильно отформатированную строку.
Этот подход позже позволит легко поменять алгоритм записи пути, например, убрать точки (чтобы место не занимали) или использовать более плотный бинарный формат хранения чисел.
Скорее всего проблема в бекслешах в пути. Лучше использовать прямые слеши, которые работают под Windows и linux. Также стоит проверить мануал по xsendfile:
https://tn123.org/mod_xsendfile/
- есть ли mod_xsendfile в списке расширений Апача, которые выводятся в phpinfo() ?
- включена ли опция XSendFile on ?
- задан ли белый список разрешенных папок в опции XSendFilePath ?
- проверь лог ошибок Апача, нет ли там чего.
То, что ты видишь заголовок X-Sendfile скорее всего значит, что он не перехватывается модулем и не обрабаывается.
Если поле заполнено неправильно, просто добавь к нему специальный css класс. Если ты используешь бутстрап, то там уже есть такой класс, который подсвечивает поле красным.
Если ты не используешь бутстрап и пишешь CSS сам, то обрати внимание, что поле может быть ошибочным по 2 причинам:
- после проверки на сервере и добавления css класса
- после HTML5 валидации, в этом случае можно использовать псевдокласс :invalid https://developer.mozilla.org/ru/docs/Web/CSS/:invalid
То есть если ты пишешь CSS сам то тебе надо написать стили, выделяющие поле красным в обоих случаях. Если ты используешь бутстрап - там все уже есть.
> А если я загружу CSS файл в стринг и в нем исправлю какие то строки, то нарушу требования MVC.
и сделаешь твой код переусложненным. Для того чтобы поменять состояние какого-то элемента удобнее всего добавить ему CSS класс:
<input <?= $errors->hasError('name') ? ' class="with-error" ' : '' ?> name="name" value=...>
>>861834
Не слышал о таком. Ну не знаю, все таки он не для того придумывался, да и крон гораздо легче чем сложное приложение на Яве.
>>861937
Проверяет же потихоньку.
https://github.com/TheSidSpears/Students/blob/master/app/Controllers/MainController.php#L39
> if (in_array($_GET['sortBy']
> $sortBy=strval($_GET['sortBy']);
Ты проверяешь в массиве значение без strval, а используешь значение с strval. Не может ли из-за этого получиться способ обхода проверки?
А каким образом такое возможно, не вдупляю?
https://github.com/yiisoft/yii2/blob/master/tests/framework/web/UrlManagerTest.php#L361
https://github.com/yiisoft/yii2/blob/master/tests/framework/web/UrlManagerTest.php#L279
https://github.com/yiisoft/yii2-httpclient/blob/master/tests/ClientTest.php#L144
Из прочитанного мной только мануал по PHPUnit.
ПОКА-ЧТО все ошибки из-за невнимательности и рассеянности, а не из-за не усвоения материала. Ну это пока. Угу.
В самом последнем блоке вместо elseif ... лучше написать просто else без указания условия. Имена функций (mt_rand) принято писать с маленькой буквы.
?> в конце писать не надо.
>>862064
Стабы и моки используются если ты хочешь протестировать сам класс в изоляции от остальных классов. Это не всегда нужно, иногда нам может понадобиться протестировать класс вместе со всеми зависимостями. Хотя это уже будет называться не "юнит", а "функциональный" тест.
То есть вопрос именно в том, что ты тестируешь. Если например твой класс может использоваться совместно с какими-то классами которые пишет пользователь (и которых у тебя нет), то естественно тебе надо тестировать его с моками вместо пользовательских классов. Если зависимости берутся из другой библиотеки - то наверно тоже стоит тестировать класс в изоляции (какой смысл тестировать чужую библиотеку?).
Если же у класса всегда одни и те же зависимости и их пишешь тоже ты, то тут возможны варианты и может быть проще тестировать все вместе.
В примере:
$manager->normalizer = new UrlNormalizer([
Авторы тестируют классы вместе, они все равно к одному компоненту относятся и они тестируют этот компонент целиком.
Вот тут:
$request = new Request;
Тоже все нормально, если какая-то функция принимает на вход объект Request то почему бы его в тестах и не использовать? Он тут используется как "глупое" хранилище данных без внутренней логики.
Но я замечу, что там используется глобальная переменная $_GET что в общем плохо (это по идее может иметь какие-то побочные эффекты). Из-за того что код в Юи ее использует, и тесты получаются не очень чистые.
Вообще, я бы переписал этот тест. Я бы на каждый шаг создавал новые Request и UrlManager чтобы сделать тест более надежным и избежать влияния предыдущего теста на следующий, и вместо копипасты я бы сделал массив значений pathInfo и ожидаемых результатов роутинга. Но конечно если код исплоьзует глобальные переменные то добиться полной изоляции сложнее.
В примере тут https://github.com/yiisoft/yii2-httpclient/blob/master/tests/ClientTest.php#L144 авторы опять же предпочли тестировать классы вместе, а не в полной изоляции. В принципе я бы тоже не стал там писать моки, смысла особого не вижу.
Я сам не сторонник усложнять тесты без надобности, но ответ на вопрос использовать моки/не использовать зависит от планируемого сценария использования класса.
Могу предложить еще посмотреть тесты от симфониевсого роутера:
- https://github.com/symfony/routing/tree/master/Tests
- док-я http://symfony.com/doc/current/routing.html (при желании можно нагуглить перевод)
Вот тут используются моки и мне не нравится как они использованы:
https://github.com/symfony/routing/blob/master/Tests/RouterTest.php#L150
Этот тест фактически проверяет что роутер вызывает метод matchRequest у матчера (там роутер содержит матчеры, которые проверяют запрос на соответствие опрделенному правилу) ровно 1 раз. Если подумать, это довольно бредовый тест: например, почему он должен вызывать этот метод ровно 1 раз? Задача роутера разбирать URL и нигде не написано как именно он это делает.
Вдобавок, матчера в тесте внедряется в роутер в обход инкапсуляции, через рефлекшен, что тоже неправильно, так как этот тест сломается если мы поменяем имя приватного поля в роутере.
Вот как бы я тестировал сценарий "проверить, что в роутер можно вставить кастомный матчер":
- сделал бы свой класс тестового матчера, реагирующего на определенный запрос и возвращающего определенный ответ. Не знаю, можно ли это сделать через мок, может быть надо писать именно новый класс.
- создал роутер, внедрив в него этот матчер
- дал бы роутеру запрос с определенным URL
- проверил бы что возвращен определенный ответ
То есть я бы не делал предположений о том как внутри устроен роутер и сколько раз он вызывает какой метод, а тестровал бы его так же как если бы я использовал его в своем коде.
А то что у них - по сути тестирует не документированное поведение роутера, а особенности его внутреннего устройства. Такие тесты легко ломаются пи рефакторингах и непонятно что тестируют.
Вообще, я смотрю, там тесты злоумпотребляют этими проверками, что определенный метод определенного класса вызван N раз. Это нормально, создать мок, который всегда возвращает фиксированное значение, но вот так считать сколько раз какой метод вызван - это стоит использовать только там, где документировано что эти методы будут столько раз вызываться.
В самом последнем блоке вместо elseif ... лучше написать просто else без указания условия. Имена функций (mt_rand) принято писать с маленькой буквы.
?> в конце писать не надо.
>>862064
Стабы и моки используются если ты хочешь протестировать сам класс в изоляции от остальных классов. Это не всегда нужно, иногда нам может понадобиться протестировать класс вместе со всеми зависимостями. Хотя это уже будет называться не "юнит", а "функциональный" тест.
То есть вопрос именно в том, что ты тестируешь. Если например твой класс может использоваться совместно с какими-то классами которые пишет пользователь (и которых у тебя нет), то естественно тебе надо тестировать его с моками вместо пользовательских классов. Если зависимости берутся из другой библиотеки - то наверно тоже стоит тестировать класс в изоляции (какой смысл тестировать чужую библиотеку?).
Если же у класса всегда одни и те же зависимости и их пишешь тоже ты, то тут возможны варианты и может быть проще тестировать все вместе.
В примере:
$manager->normalizer = new UrlNormalizer([
Авторы тестируют классы вместе, они все равно к одному компоненту относятся и они тестируют этот компонент целиком.
Вот тут:
$request = new Request;
Тоже все нормально, если какая-то функция принимает на вход объект Request то почему бы его в тестах и не использовать? Он тут используется как "глупое" хранилище данных без внутренней логики.
Но я замечу, что там используется глобальная переменная $_GET что в общем плохо (это по идее может иметь какие-то побочные эффекты). Из-за того что код в Юи ее использует, и тесты получаются не очень чистые.
Вообще, я бы переписал этот тест. Я бы на каждый шаг создавал новые Request и UrlManager чтобы сделать тест более надежным и избежать влияния предыдущего теста на следующий, и вместо копипасты я бы сделал массив значений pathInfo и ожидаемых результатов роутинга. Но конечно если код исплоьзует глобальные переменные то добиться полной изоляции сложнее.
В примере тут https://github.com/yiisoft/yii2-httpclient/blob/master/tests/ClientTest.php#L144 авторы опять же предпочли тестировать классы вместе, а не в полной изоляции. В принципе я бы тоже не стал там писать моки, смысла особого не вижу.
Я сам не сторонник усложнять тесты без надобности, но ответ на вопрос использовать моки/не использовать зависит от планируемого сценария использования класса.
Могу предложить еще посмотреть тесты от симфониевсого роутера:
- https://github.com/symfony/routing/tree/master/Tests
- док-я http://symfony.com/doc/current/routing.html (при желании можно нагуглить перевод)
Вот тут используются моки и мне не нравится как они использованы:
https://github.com/symfony/routing/blob/master/Tests/RouterTest.php#L150
Этот тест фактически проверяет что роутер вызывает метод matchRequest у матчера (там роутер содержит матчеры, которые проверяют запрос на соответствие опрделенному правилу) ровно 1 раз. Если подумать, это довольно бредовый тест: например, почему он должен вызывать этот метод ровно 1 раз? Задача роутера разбирать URL и нигде не написано как именно он это делает.
Вдобавок, матчера в тесте внедряется в роутер в обход инкапсуляции, через рефлекшен, что тоже неправильно, так как этот тест сломается если мы поменяем имя приватного поля в роутере.
Вот как бы я тестировал сценарий "проверить, что в роутер можно вставить кастомный матчер":
- сделал бы свой класс тестового матчера, реагирующего на определенный запрос и возвращающего определенный ответ. Не знаю, можно ли это сделать через мок, может быть надо писать именно новый класс.
- создал роутер, внедрив в него этот матчер
- дал бы роутеру запрос с определенным URL
- проверил бы что возвращен определенный ответ
То есть я бы не делал предположений о том как внутри устроен роутер и сколько раз он вызывает какой метод, а тестровал бы его так же как если бы я использовал его в своем коде.
А то что у них - по сути тестирует не документированное поведение роутера, а особенности его внутреннего устройства. Такие тесты легко ломаются пи рефакторингах и непонятно что тестируют.
Вообще, я смотрю, там тесты злоумпотребляют этими проверками, что определенный метод определенного класса вызван N раз. Это нормально, создать мок, который всегда возвращает фиксированное значение, но вот так считать сколько раз какой метод вызван - это стоит использовать только там, где документировано что эти методы будут столько раз вызываться.
>В самом последнем блоке вместо elseif ... лучше написать просто else без указания условия. Имена функций (mt_rand) принято писать с маленькой буквы.
Т.е. даже не указывая условия, этот если выполнится, ТОЛЬКО при равном количестве очков у игрока и судьбы?
Окей. Понял.
А если в условиях не выйдет так легко, как в этом уроке, то не критично будет все-таки делать elseif?
Во-первых, вместо setInterval правильнее использовать setTimeout - в случае ошибки в коде его работа прервется, в отличи от setInterval. Во-вторых. каждую секунду опрашивать это перебор, будет много запросов если много пользвоателей.
Твой подход называется polling, то есть периодический опрос сервера. Есть методы получше, а именно:
- (костыль из старых времен) long polling, COMET - это когда мы отправляем запрос и сервер "подвисает" до истечения таймаута или появления нового сообщения. тянуть больше 30-60 секунд нельзя, так как браузер или прокси-сервер может закрыть соединение по таймауту. Профит в том что нам не надо слать запросы каждую секунду
- (современный подход) использовать вебсокет. Вебсокет позволяет установить постоянное соединение с сервером и пересылать по нему данные в обе стороны, в том числе с сервера на клиент, асинхронно. Минус - нужен современный браузер и конечно JS.
В случае с вебсокетом тебе так же нужна программа-демон-мультиплексор, которая принимает и держит соединения от клиентов, а также принимает и пересылает уведомления о событиях клиентам. То есть когда пользователь A отправляет сообщение в комнату, скрипт на сервере уведомляет демона и тот пересылает сообщение всем клиентам, которые подписаны на эту комнату.
Мультиплексор можно написать самому или взять готовый.
Есть также стандартный протокол, работающий поверх вебсокета, The Web Application Messaging Protocol (WAMP) и библиотеки для работы с ним.
Если ты хочешь это сделать, тебе надо изучить:
- сетевое программирование и обычные классические сокеты
- асинхронная работа с сокетами
- WebSockets
- The Web Application Messaging Protocol
- библиотеку ReactPHP которая позволяет писать программы, асинхронно работающие с сокетами, поддерживающую в том числе WAMP
- JS библиотеку вроде autobahn поддерживающую WAMP на стороне клиента
Вот тут ссылки и задачи по сеетвому программированию: >>853691
Если тебе интересны исторические и работающие в старых браузерах способы long polling, то надо гуглить по слову COMET: https://habrahabr.ru/post/104945/
Во-первых, вместо setInterval правильнее использовать setTimeout - в случае ошибки в коде его работа прервется, в отличи от setInterval. Во-вторых. каждую секунду опрашивать это перебор, будет много запросов если много пользвоателей.
Твой подход называется polling, то есть периодический опрос сервера. Есть методы получше, а именно:
- (костыль из старых времен) long polling, COMET - это когда мы отправляем запрос и сервер "подвисает" до истечения таймаута или появления нового сообщения. тянуть больше 30-60 секунд нельзя, так как браузер или прокси-сервер может закрыть соединение по таймауту. Профит в том что нам не надо слать запросы каждую секунду
- (современный подход) использовать вебсокет. Вебсокет позволяет установить постоянное соединение с сервером и пересылать по нему данные в обе стороны, в том числе с сервера на клиент, асинхронно. Минус - нужен современный браузер и конечно JS.
В случае с вебсокетом тебе так же нужна программа-демон-мультиплексор, которая принимает и держит соединения от клиентов, а также принимает и пересылает уведомления о событиях клиентам. То есть когда пользователь A отправляет сообщение в комнату, скрипт на сервере уведомляет демона и тот пересылает сообщение всем клиентам, которые подписаны на эту комнату.
Мультиплексор можно написать самому или взять готовый.
Есть также стандартный протокол, работающий поверх вебсокета, The Web Application Messaging Protocol (WAMP) и библиотеки для работы с ним.
Если ты хочешь это сделать, тебе надо изучить:
- сетевое программирование и обычные классические сокеты
- асинхронная работа с сокетами
- WebSockets
- The Web Application Messaging Protocol
- библиотеку ReactPHP которая позволяет писать программы, асинхронно работающие с сокетами, поддерживающую в том числе WAMP
- JS библиотеку вроде autobahn поддерживающую WAMP на стороне клиента
Вот тут ссылки и задачи по сеетвому программированию: >>853691
Если тебе интересны исторические и работающие в старых браузерах способы long polling, то надо гуглить по слову COMET: https://habrahabr.ru/post/104945/
Ну это зависит от ситуации: если тебе надо ловить все случаи, когда ни одно условие выше не сработало, то else. Если же надо ловить не все случаи, то elseif.
Вот, понял.
Слушай. Это все замечательно, но я не понимаю, как это пхп работает в виде интерфейса. Ну вот я сделал эту игру, это же последовательные строки идут. А как здесь вот как на харкаче. Нажал кнопку - доп. окно, вот снизу списочек ссылоку, набор досок.
Это все пхп, и это все вот таким же путем можно провернуть?
А графика сайтов?
Как связывается графика и код? Как это все распределяется?
Интерактивность на страницах делается за счет яваскрипта (а не за счет PHP). В HTML-страницу можно встроить программу на языке яваскрипт, и она будет вызываться при нажатии например на кнопку, и будет перестраивать DOM (дерево HTML документа) так, что на страницу вставится нарисованное окошко.
Загруженный в браузер HTML документ представлен в памяти в виде дерева объектов DOM и программа на яваскрипт может модицифировать это дерево, соответственно меняя вид страницы на экране, показывая окошки, выводя надписи итд.
При желании яваскрипт-программа может отправлять фоновые HTTP запросы на сервер (это называется аякс).
Окей. Т.е. вся табличная структура и все расположение ссылок на сайте - дело ХТМЛ.
Всплывающие окошки и прочее - яваскрипт.
А какая роль пхп? Он помогает где нужно вставить ява-скрипт и хтмл? Он хранилище информации о сайтах на сервере ( в виде явы и хтмл)?
К примеру, человек нажимает на ссылку, и на сервере сигналами пхп кода выбирается нужная инфа в виде куска кода явы или хтмл?
PHP отвечает за обработку, хранение и выдачу данных на сервере. Это не всегда нужно, иногда нам хватает только HTML + JS. Но если у тебя например есть на сервере база данных, то тебе понадобится PHP-код, принимающий данные с клиента и отдающий их ему. Или если у тебя чат, то тебе понадобится программа на сервере, пересылающая данные между клиентами.
Плюс, если сайт большой, какие-то страницы могут генерироваться на PHP и быть неинтерактивными,а какие-то интерактивными и использовать JS.
Т.е. я правильно написал?
Грубо говоря пхп - информационный банк данных о сайте.
Ява и хтмл - объекты, которые хранятся в "банковских ячейках" этого банка?
Человек жмет ссылку - ссылка идет по номеру в нужную ячейку, достает оттуда объект и отсылает человеку.
Нет. PHP это не банк данных, это язык для написания программ, которые выполняются на сервере. "банк данных" это база данных, например MySQL или Postgresql.
Яваскрипт (не ява) и HTML не хранятся в базе данных.
Начни с изучения основ протокола HTTP, и как работает веб-сервер:
- https://github.com/codedokode/pasta/blob/master/soft/web-server.md (ту часть что про PHP, можно не читать)
- https://github.com/codedokode/pasta/blob/master/network/http.md
Там в том числе есть пункт про статические и динамические сайты.
Хорошо. Спасибо.
Если нужно 9 раз перемножить. Здесь 10 переменных?
Или как.
х * х = у
Где х одна переменная, а у - другая?
Как это составить в цикле?
Нужен сброс какой то переменной?
Я час корпел, и так ничего и не придумал. Тут же дело в математике.
Зачем нужно действие 1, если в цикле оно выполняется самый первый раз, и все? Просто как хранилище одной переменной?
Тело цикла в задаче подразумевает ТОЛЬКО echo использовать?
В действие два в цикле можно несколько действий совершить.
Я не понял. Бля. Как. Не понял. Вообще. Пиздец.
У тебя две переменные. Сначала меняешь одну, потом меняешь вторую по очереди, потом снова первую. Получается два цикла.
>Тут же дело в математике.
Нет, чисто программирование. Математику за тебя комп сам считать будет. Главное указать ему, что делать.
Пхп это тот, кто все обрабатывает на сервере. Зашел ты в магазин например, набил корзину, и хочешь сделать заказ. Кому-то надо проверить наличие товара на складе, посчитать сумму заказа, проверить правильно ли ты адрес свой ввел, и прочее такое. Вот этим Php на сервере и будет заниматься. Чтобы с данными работать (например проверить есть ли товар на складе), ему надо к базе данных подсоединиться, тут он и будет использовать какой-нибудь Mysql. А часть правил можно жестко закодировать, например список городов России прямо в PHP файле, и если ты страну Россия ввел и город не из списка, то php поймет и выдаст, что заказ невозможен. Причем часть таких расчетов можно не делать на сервере, а делать сразу в клиенте, что быстрее (нет передачи данных по сети, и не грузится сервер). Тогда и используют Javascript, например им можно проверить правильность формата телефона или тот же список городов России.
Бекслеши преобразовал в прямые
> есть ли mod_xsendfile в списке расширений Апача, которые выводятся в phpinfo() ?
есть
> включена ли опция XSendFile on ?
> задан ли белый список разрешенных папок в опции XSendFilePath ?
Прилагаю скрины
> лог ошибок Апача
Ничего подозрительного не вижу http://pastebin.com/4TYJr3H1
Куда дальше копать?
Починилось!
Скорее всего ошибка с путями в settings.php была, т.к. заработало после того, как я там поправил. Приятно когда откладываешь решение ошибки, занимаешься другим, и в процессе и VHost настроил и ошибку исправил.
На бекслеши скрипту пофиг - и так загружает
>х * х = у
Это неверно, потому что в программировании надо наоборот: у = х умножить х.
В случае этой задачи нужно $i умножить на $i в теле цикла for.
Цикл for состоит из трёх условий и позволяет в третьем условии, допустим, прибавлять к переменной $i единицу for ($i = 1; $i <= 9; $i++).
А уже в самом теле цикла эта переменная умножается сама на себя, выдаётся результат с помощью echo.
Собери это - задача решится.
Погоди.
Получается, тело цикла - основное поле для творчества, и там можно что угодно написать, помимо простого echo?
Т.е. я там могу и переменные сохранить, и изменять их?
А инфа переменных в теле цикла сохраняется только во время работы цикла?
Допустим
$а = 1
$б = 1 + 1
И с каждым циклом а будет постоянно увеличиваться на 1, а как цикл перестанет работать все сбросится.
Блин. Что то я не понимаю.
>Получается, тело цикла - основное поле для творчества, и там можно что угодно написать, помимо простого echo?
>Т.е. я там могу и переменные сохранить, и изменять их?
Конечно! И в теле цикла можно что угодно писать, и в условиях тоже (только там должно быть обязательно три разделённых точками с запятой условия).
>А инфа переменных в теле цикла сохраняется только во время работы цикла?
>Допустим
>$а = 1
>$б = 1 + 1
>И с каждым циклом а будет постоянно увеличиваться на 1, а как цикл перестанет работать все сбросится.
Да, пробуй это на простом цикле, быстро и решительно - только так будешь усваивать всё, а иначе ничего не поймёшь.
http://ideone.com/d321qG
>$а = 1
>$б = 1 + 1
>И с каждым циклом а будет постоянно увеличиваться на 1, а как цикл перестанет работать все сбросится.
Нет, в этом случае $a будет всё время равно 1 - хоть это в теле цикла, хоть это в условии.
А $б будет равно 2 - и там, и там.
Чтобы они изменялись, надо делать так:
>$а = $а + 1
>$б = $б + 1
Такого рода. Чтобы переменная, которая получилась от предыдущего прохождения цикла, увеличивалась на 1.
А иначе ничего не будет изменяться - каждый раз переменная будет становиться равной единице или равной "единица плюс единица".
В 50% случаев она не работает. Судя по условиям опа, писал неправильно. Понятия не имею как её решать и в каком направлении вообще идти (
Вот уж не думал что она окажется настолько сложной.
Саркози, это ти?
Можно обойтись одной переменной. Сможешь? Для начала попробуй обойтись двумя, а там может сообразишь как и от второй избавиться
По моему там есть какой-то плагин autocompleteIntel или как-то так, не помню.
>>854384
https://github.com/enotocode/Studentslist
> Использовал такое решение: require_once (__DIR__ . '/../app/init.php');
> Это абсолютный путь или относительный?
__DIR__ возвращает абсолютный путь.
> Можно ли использовать такое решение require_once ($_SERVER['DOCUMENT_ROOT'] . '/app/init.php')?
Не стоит. DOCUMENT_ROOT отсутствует при вызове скрипта из командной строки например.
>>а как же зайти на страницу с таблицей студентов?
>>Мне кажется, это неудобно, если она не открывается напрямую.
> Ты имеешь ввиду добавить адрес вроде /list, который бы вел на список?
> Как я понял условия задачи, доступ к списку студентов пользователь получает по ссылке
Я имел в виду что у тебя список не был доступен без регистрации, а хорошо бы иметь возможность его просматривать.
> Можно ли использовать в автозагрузчике вот такие пути __DIR__ . '/../' . $className . ".php" ?
Можно. Но лучше всего не расставлять __DIR__ по куче функций, а сделать одну функцию, получающую путь к корню проекта.
> Но ведь HTML валидация тоже не пропускает русские символы?
Проверил, ;/IivanANUSпочт/
> Я решил проверять только на наличие следующих опечаток - отсутствие @ или точки перед доменом или самого домена.
Ок, хорошо
> В другой ситуации, думаю можно устанавливать часовой пояс клиента в объекте DateTime::setTimezone(), гадая по IP и на JS?
Можно, но это редко когда нужно, при указании даты рождения часовой пояс не важен ведь. Он важен если нам нужно время и тут да, проще всего получить часовой пояс средствами JS.
> Если в каждом поле формы плеэйсхолдер будет начинаться с "Например, ...",
> то воспринимать такую форму будет сложнее из-за повторений?
Да, тоже верно.
> В Bootstrap отступы другие получаются, не так красиво выглядит.
Можно переопределить же.
> Нужен ли префикс в именах переменных при экстракции, например form_abiturient?
нет
> Ты имеешь ввиду алгоритм в методе updateAbiturient в Gateway или в контроллере ?
> Но ведь я и так загружаю студента из бд, затем заполняю его свойствами поля формы. Пользователь
> изменяет или не изменяет эти свойства. Затем обновляю только те свойства студента, которые есть в форме.
Да, тогда все правильно.
В ридми не указано что надо настроить папку public как публичную.
https://github.com/enotocode/Studentslist/blob/master/abiturients.sql#L43
> ENGINE=MyISAM
Почитай про отличия InnoDB и MyISAM. Из самого важного - MyISAM старый движок и не поддерживает внешние ключи и транзакции.
> if (isset($_GET['page']) && (intval($_GET['page']))) {
А что проверяет условие intval($_GET['page']) ? Что после преобразования в число там будет не 0? Если ты хотел проверить, является ли выражение числом, то есть is_numeric и ctype_digit.
> $curl['page'] = intval($_GET['page']);
> } else {
> $curl['page'] = NULL;
По умолчанию наверно можно ставить значение 1
https://github.com/enotocode/Studentslist/blob/master/public/index.php#L61
Тут отофрматировано кривовато, в таких случаях обычно у содержимого массива просто отступ + 4 пробела, а у тебя как-то далеко вправо задвинуто.
> $formData = array_map(
> function ($a) {return trim($a);},
имя функции может использоваться для ее вызова ( http://php.net/manual/ru/language.types.callable.php ) потому можно писать array_map('trim', ...)
https://github.com/enotocode/Studentslist/blob/master/public/register.php#L37
После редиректа скрипт не завершается.
Логика обновления абитуриента по-прежнему неудачная. Вот твой алгоритм редактирования:
- создать пустого абитуриента
- записать в него данные из формы
- сделать UPDATE в БД
Тут много возможностей сделать ошибку. Например, мы добавим в абитуриента новое поле, но не добавим его в форму. Тогда метод updateAbiturient() вполне может записать для этого поля в базу пустое знаечние. Или наоборот, мы уберем одно из полей из формы, и тогда опять же в базе оно будет очищено.
Правильнее делать так:
- загрузить абитуриента из БД
- обновить в нем поля соответствующие форме
- сохранить обратно
Либо же надо как-то явно передавать в функцию обновления список обновляемых полей, что неудобно - проще сохранять все поля.
https://github.com/enotocode/Studentslist/blob/master/app/init.php#L14
> (!empty($settings['database']['port'])) ? (';port=' . $settings['database']['port']) : ''
Здесь точка с запятой не в том месте.
https://github.com/enotocode/Studentslist/blob/master/app/Authorization.php#L41
> public function createNewRegistry()
Вот этот метод на мой взгляд сделан неудачно. Ты сначала генерируешь код и ставишь куку, а только потом сохраняешь его в базу. Мне кажется, надежнее наоборот. Иначе возможна ситуация, когда кука выставлена, а записи в БД нет.
Ты используешь там название "пароль", но наверно правильнее будет "токен", так как пользователь этого пароля не видит и ввести не может.
В классе авторизации очень не хватает комментариев, там куча методов, названия которых не дают особых подробностей. Вот представь что тебе дали такой класс, ты разберешься, как им пользоваться?
Непонятно назначение метод authosise(). Зачем он, если можно сразу вызвать getUserId() ?
Ты сохраняешь поля userId и userPass, но они обрабатываются несогласованно. Например при регистрации поле userPass перезаписывается, а userId сохраняет старое значение.
Более того, если подумать, кешировать достаточно одно поле, а не два. Это лишь повышает вероятность ошибок.
В общем, нужно отрефакторить класс авторизации.
> setcookie ('userPassword', $pass, strtotime( '+10 years' ));
Ты не указываешь путь, и кука может быть доступна не на всем сайте. Прочитай про параметр path у кук.
https://github.com/enotocode/Studentslist/blob/master/app/Authorization.php#L30
> if ($pass) {
> $userId = $this->getUserId();
> }
Здесь у тебя переменная $userId может не существовать, что вызовет ошибку. Ты создаешь переменную внутри блока if, а используешь снаружи.
> $sql .= " WHERE CONCAT (name, lastName, groupNum, egePoints, email, dateOfBirth) LIKE '%" . $searchKey . "%'";
Лучше бы подставлять значение через плейсхолдер. Вообще, может тут удобнее собирать запрос через sprintf?
$sql = sprintf("SELECT ... %s", $order ? "ORDER BY $order" : '');
И надо правильнее проверять значения $order, сейчас у тебя при передаче неправильного значения будет ошибка обращения к несуществующему элементу массива вот тут: $this->sort[$colum]
Сборку запроса надо упростить, сейчас там нагромождено много ифов и легко сделать ошибку.
$offset и $limit никак не фильтруются.
https://github.com/enotocode/Studentslist/blob/master/app/AbiturientDataGateway.php#L136
> return substr($set, 0, -2);
Это неудачный код. Что такое -2? Почему именно 2? Надо либо отрезать лишнюю запятую через trim() либо использовать implode().
https://github.com/enotocode/Studentslist/blob/master/app/AbiturientDataGateway.php#L156
> if (!is_array(current($values))) {
Ты усложняешь функцию, разрешая ей принимать массивы разных форматов. Тип для каждого аргумента должен быть задан однозначно без таких вот ифов: https://github.com/codedokode/pasta/blob/master/good-code.md#Тип-должен-быть-один
https://github.com/enotocode/Studentslist/blob/master/app/Errors.php#L16
> if (isset($this->errors[$name])) {
Для проверки наличия элемента лучше использовать array_key_exists так как isset не выдаст ошибки если ты например опечатаешься в имени массива.
> public function isEmpty()
Тут наверно можно было просто написать return count($this->errors) == 0;
https://github.com/enotocode/Studentslist/blob/master/app/LinkHelper.php#L42
> if (!isset($order) | $order == AbiturientDataGateway::ASC) {
| это битовый, а не логический оператор. Тебе нужен ||.
https://github.com/enotocode/Studentslist/blob/master/app/View.php
пустой конструктор можно не писать.
https://github.com/enotocode/Studentslist/blob/master/templates/form.html#L12
> <?php if ($errors && $errors->get('nameForbidden')):
Неудобно что объект $errors может отстутствовать. Лучше сделать так, чтобы не надо было проверять, что $errors не пуст.
> <?= "Имя должно содержать только буквы, символ(ы): " . htmlspecialchars($errors->get('nameForbidden'), ENT_QUOTES) . " - недопустимы"; ?>
Наверно сообщение удобнее было бы целиком формировать в валидаторе?
> Поле может принимать значение GENDER_MALE или GENDER_FEMALE, вы отправили:
Боюсь для обычного пользователя это сообщение не очень понятно.
https://github.com/enotocode/Studentslist/blob/master/templates/form.html#L106
> nim="1900"
Опечатка
https://github.com/enotocode/Studentslist/blob/master/templates/header.html#L6
> <meta name="viewport"
раз ты используешь этот метатег, то ты проверил как страницы отображаются при маленькой ширине окна?
> <?= (isset($curl['search'])) ? 'value="' . htmlspecialchars($curl['search'], ENT_QUOTES) . '"' : '';?>
Слишком много кавычек. Лучше так: value="<?= htmlspecialchars(...) ?>"
https://github.com/enotocode/Studentslist/blob/master/templates/list.html#L49
> <?php foreach($abiturient as $valueName => $value):
> if (in_array($valueName, $allowedValues)) : ?>
лучше просто foreach ($allowedValues as $column)
> htmlspecialchars(app\ViewHelper::html($value)
двойное экранирование?
> <?php endif;
> endforeach; ?>
В данном случае каждую команду надо в свой блок: <?php endif ?>
По моему там есть какой-то плагин autocompleteIntel или как-то так, не помню.
>>854384
https://github.com/enotocode/Studentslist
> Использовал такое решение: require_once (__DIR__ . '/../app/init.php');
> Это абсолютный путь или относительный?
__DIR__ возвращает абсолютный путь.
> Можно ли использовать такое решение require_once ($_SERVER['DOCUMENT_ROOT'] . '/app/init.php')?
Не стоит. DOCUMENT_ROOT отсутствует при вызове скрипта из командной строки например.
>>а как же зайти на страницу с таблицей студентов?
>>Мне кажется, это неудобно, если она не открывается напрямую.
> Ты имеешь ввиду добавить адрес вроде /list, который бы вел на список?
> Как я понял условия задачи, доступ к списку студентов пользователь получает по ссылке
Я имел в виду что у тебя список не был доступен без регистрации, а хорошо бы иметь возможность его просматривать.
> Можно ли использовать в автозагрузчике вот такие пути __DIR__ . '/../' . $className . ".php" ?
Можно. Но лучше всего не расставлять __DIR__ по куче функций, а сделать одну функцию, получающую путь к корню проекта.
> Но ведь HTML валидация тоже не пропускает русские символы?
Проверил, ;/IivanANUSпочт/
> Я решил проверять только на наличие следующих опечаток - отсутствие @ или точки перед доменом или самого домена.
Ок, хорошо
> В другой ситуации, думаю можно устанавливать часовой пояс клиента в объекте DateTime::setTimezone(), гадая по IP и на JS?
Можно, но это редко когда нужно, при указании даты рождения часовой пояс не важен ведь. Он важен если нам нужно время и тут да, проще всего получить часовой пояс средствами JS.
> Если в каждом поле формы плеэйсхолдер будет начинаться с "Например, ...",
> то воспринимать такую форму будет сложнее из-за повторений?
Да, тоже верно.
> В Bootstrap отступы другие получаются, не так красиво выглядит.
Можно переопределить же.
> Нужен ли префикс в именах переменных при экстракции, например form_abiturient?
нет
> Ты имеешь ввиду алгоритм в методе updateAbiturient в Gateway или в контроллере ?
> Но ведь я и так загружаю студента из бд, затем заполняю его свойствами поля формы. Пользователь
> изменяет или не изменяет эти свойства. Затем обновляю только те свойства студента, которые есть в форме.
Да, тогда все правильно.
В ридми не указано что надо настроить папку public как публичную.
https://github.com/enotocode/Studentslist/blob/master/abiturients.sql#L43
> ENGINE=MyISAM
Почитай про отличия InnoDB и MyISAM. Из самого важного - MyISAM старый движок и не поддерживает внешние ключи и транзакции.
> if (isset($_GET['page']) && (intval($_GET['page']))) {
А что проверяет условие intval($_GET['page']) ? Что после преобразования в число там будет не 0? Если ты хотел проверить, является ли выражение числом, то есть is_numeric и ctype_digit.
> $curl['page'] = intval($_GET['page']);
> } else {
> $curl['page'] = NULL;
По умолчанию наверно можно ставить значение 1
https://github.com/enotocode/Studentslist/blob/master/public/index.php#L61
Тут отофрматировано кривовато, в таких случаях обычно у содержимого массива просто отступ + 4 пробела, а у тебя как-то далеко вправо задвинуто.
> $formData = array_map(
> function ($a) {return trim($a);},
имя функции может использоваться для ее вызова ( http://php.net/manual/ru/language.types.callable.php ) потому можно писать array_map('trim', ...)
https://github.com/enotocode/Studentslist/blob/master/public/register.php#L37
После редиректа скрипт не завершается.
Логика обновления абитуриента по-прежнему неудачная. Вот твой алгоритм редактирования:
- создать пустого абитуриента
- записать в него данные из формы
- сделать UPDATE в БД
Тут много возможностей сделать ошибку. Например, мы добавим в абитуриента новое поле, но не добавим его в форму. Тогда метод updateAbiturient() вполне может записать для этого поля в базу пустое знаечние. Или наоборот, мы уберем одно из полей из формы, и тогда опять же в базе оно будет очищено.
Правильнее делать так:
- загрузить абитуриента из БД
- обновить в нем поля соответствующие форме
- сохранить обратно
Либо же надо как-то явно передавать в функцию обновления список обновляемых полей, что неудобно - проще сохранять все поля.
https://github.com/enotocode/Studentslist/blob/master/app/init.php#L14
> (!empty($settings['database']['port'])) ? (';port=' . $settings['database']['port']) : ''
Здесь точка с запятой не в том месте.
https://github.com/enotocode/Studentslist/blob/master/app/Authorization.php#L41
> public function createNewRegistry()
Вот этот метод на мой взгляд сделан неудачно. Ты сначала генерируешь код и ставишь куку, а только потом сохраняешь его в базу. Мне кажется, надежнее наоборот. Иначе возможна ситуация, когда кука выставлена, а записи в БД нет.
Ты используешь там название "пароль", но наверно правильнее будет "токен", так как пользователь этого пароля не видит и ввести не может.
В классе авторизации очень не хватает комментариев, там куча методов, названия которых не дают особых подробностей. Вот представь что тебе дали такой класс, ты разберешься, как им пользоваться?
Непонятно назначение метод authosise(). Зачем он, если можно сразу вызвать getUserId() ?
Ты сохраняешь поля userId и userPass, но они обрабатываются несогласованно. Например при регистрации поле userPass перезаписывается, а userId сохраняет старое значение.
Более того, если подумать, кешировать достаточно одно поле, а не два. Это лишь повышает вероятность ошибок.
В общем, нужно отрефакторить класс авторизации.
> setcookie ('userPassword', $pass, strtotime( '+10 years' ));
Ты не указываешь путь, и кука может быть доступна не на всем сайте. Прочитай про параметр path у кук.
https://github.com/enotocode/Studentslist/blob/master/app/Authorization.php#L30
> if ($pass) {
> $userId = $this->getUserId();
> }
Здесь у тебя переменная $userId может не существовать, что вызовет ошибку. Ты создаешь переменную внутри блока if, а используешь снаружи.
> $sql .= " WHERE CONCAT (name, lastName, groupNum, egePoints, email, dateOfBirth) LIKE '%" . $searchKey . "%'";
Лучше бы подставлять значение через плейсхолдер. Вообще, может тут удобнее собирать запрос через sprintf?
$sql = sprintf("SELECT ... %s", $order ? "ORDER BY $order" : '');
И надо правильнее проверять значения $order, сейчас у тебя при передаче неправильного значения будет ошибка обращения к несуществующему элементу массива вот тут: $this->sort[$colum]
Сборку запроса надо упростить, сейчас там нагромождено много ифов и легко сделать ошибку.
$offset и $limit никак не фильтруются.
https://github.com/enotocode/Studentslist/blob/master/app/AbiturientDataGateway.php#L136
> return substr($set, 0, -2);
Это неудачный код. Что такое -2? Почему именно 2? Надо либо отрезать лишнюю запятую через trim() либо использовать implode().
https://github.com/enotocode/Studentslist/blob/master/app/AbiturientDataGateway.php#L156
> if (!is_array(current($values))) {
Ты усложняешь функцию, разрешая ей принимать массивы разных форматов. Тип для каждого аргумента должен быть задан однозначно без таких вот ифов: https://github.com/codedokode/pasta/blob/master/good-code.md#Тип-должен-быть-один
https://github.com/enotocode/Studentslist/blob/master/app/Errors.php#L16
> if (isset($this->errors[$name])) {
Для проверки наличия элемента лучше использовать array_key_exists так как isset не выдаст ошибки если ты например опечатаешься в имени массива.
> public function isEmpty()
Тут наверно можно было просто написать return count($this->errors) == 0;
https://github.com/enotocode/Studentslist/blob/master/app/LinkHelper.php#L42
> if (!isset($order) | $order == AbiturientDataGateway::ASC) {
| это битовый, а не логический оператор. Тебе нужен ||.
https://github.com/enotocode/Studentslist/blob/master/app/View.php
пустой конструктор можно не писать.
https://github.com/enotocode/Studentslist/blob/master/templates/form.html#L12
> <?php if ($errors && $errors->get('nameForbidden')):
Неудобно что объект $errors может отстутствовать. Лучше сделать так, чтобы не надо было проверять, что $errors не пуст.
> <?= "Имя должно содержать только буквы, символ(ы): " . htmlspecialchars($errors->get('nameForbidden'), ENT_QUOTES) . " - недопустимы"; ?>
Наверно сообщение удобнее было бы целиком формировать в валидаторе?
> Поле может принимать значение GENDER_MALE или GENDER_FEMALE, вы отправили:
Боюсь для обычного пользователя это сообщение не очень понятно.
https://github.com/enotocode/Studentslist/blob/master/templates/form.html#L106
> nim="1900"
Опечатка
https://github.com/enotocode/Studentslist/blob/master/templates/header.html#L6
> <meta name="viewport"
раз ты используешь этот метатег, то ты проверил как страницы отображаются при маленькой ширине окна?
> <?= (isset($curl['search'])) ? 'value="' . htmlspecialchars($curl['search'], ENT_QUOTES) . '"' : '';?>
Слишком много кавычек. Лучше так: value="<?= htmlspecialchars(...) ?>"
https://github.com/enotocode/Studentslist/blob/master/templates/list.html#L49
> <?php foreach($abiturient as $valueName => $value):
> if (in_array($valueName, $allowedValues)) : ?>
лучше просто foreach ($allowedValues as $column)
> htmlspecialchars(app\ViewHelper::html($value)
двойное экранирование?
> <?php endif;
> endforeach; ?>
В данном случае каждую команду надо в свой блок: <?php endif ?>
Если посмотреть условие задач, то видно, что требуется вывести 9 строчек. То есть повторить 1 действие 9 раз, подставляя числа от 1 до 9.
Значит нам нужен цикл, который будет менять значение переменной от 1 до 9. На каждом шаге он будет выводить 1 строчку.
> Здесь 10 переменных?
Идея цикла в том, что у нас одна переменная и код выполняется 9 раз с разными значениями этой переменной.
Если сложно - попробуй для начала написать цикл который просто выведет числа от 1 до 9, каждое на новой строке.
> В действие два в цикле можно несколько действий совершить.
Можно, но не стоит так как это лучше поместить в тело цикла ради читаемости.
>>862259
Бекслеши не заработают под линуксом (или тебе надо под линуксом тогда генерировать путь с прямыми слешами).
>>862328
В теле цикла пишутся команды которые должны выполняться несколько раз. В шапке обычно пишутся команды для создания и увеличения переменной-счетчика.
> А инфа переменных в теле цикла сохраняется только во время работы цикла?
Переменные не исчезнут никуда, останутся и после цикла.
>>862492
Код запости что ли.
>>862538
У тебя слишком много переменных. Какой смысл делать 2 переменные с одинаковым значением?
Если посмотреть условие задач, то видно, что требуется вывести 9 строчек. То есть повторить 1 действие 9 раз, подставляя числа от 1 до 9.
Значит нам нужен цикл, который будет менять значение переменной от 1 до 9. На каждом шаге он будет выводить 1 строчку.
> Здесь 10 переменных?
Идея цикла в том, что у нас одна переменная и код выполняется 9 раз с разными значениями этой переменной.
Если сложно - попробуй для начала написать цикл который просто выведет числа от 1 до 9, каждое на новой строке.
> В действие два в цикле можно несколько действий совершить.
Можно, но не стоит так как это лучше поместить в тело цикла ради читаемости.
>>862259
Бекслеши не заработают под линуксом (или тебе надо под линуксом тогда генерировать путь с прямыми слешами).
>>862328
В теле цикла пишутся команды которые должны выполняться несколько раз. В шапке обычно пишутся команды для создания и увеличения переменной-счетчика.
> А инфа переменных в теле цикла сохраняется только во время работы цикла?
Переменные не исчезнут никуда, останутся и после цикла.
>>862492
Код запости что ли.
>>862538
У тебя слишком много переменных. Какой смысл делать 2 переменные с одинаковым значением?
Спасибо за ответ, начинаю усваивать.
В первый же раз прочитал, что в начале выполняется тело, а потом второе действие, но не сразу же это понял. До конца думал что в начале действие 2, а потом тело в конце списка.
Алсо, шапка это действие1, условие и действие 2?
Буквально два часа потратил на эту задачу. Пипец, аж голова заболела.
Но рад что решил, сейчас начну переделывать первую задачу, и таки сделаю с 1 переменной.
Попробую.
"Действие 2" выполняется после тела и там обычно увеличивается переменная-счетчик.
На скриншоте я бы вынес все кроме moneyBoy из шапки, так как там многовато переменных и из-за этого труднее понять, как будет выполняться цикл.
$procent не надо вычислять 2 раза. Увеличить сумму можно просто умножая ее на (1 + 10/100).
Из переменных $yearBoy и $yearCredit одну наверно можно убрать так как возраст всегда можно посчитать как начальный возраст + число прошедших лет.
Я тут понял.
>>862676
А тут - нет.
$moneyBoy = $moneyBoy + $procent * (1 + 10/100);
так что-ли? И после этого вторую строчку $procent можно убирать?
Погоди. Так это адаптация формулы расчета сложного вклада? Тогда зачем 10/100, а не сразу 0,10?
И по второму. Что значит, начальный возраст + число прошедших лет? Начальное число одной переменной шестнадцать. А второй 0.
Разве переменная может одновременно держать две разных цифры, автономных друг от друга?
Это не годится. Вот допустим мы захотим чтобы там выводилось не 9, а только 6 строчек. Или 20 строчек. Придется переделывать код. А я хочу чтобы нужно было поменять только 1 цифру.
Также, цикл у тебя там не используется так как код внутри выполняется лишь 1 раз. Если та, то цикл и не нужен получается, ведь цикл нужен чтобы выполнить одни и те же действия несколько раз.
Надо переделать программу так, чтобы число строчек задавалось только в одном месте и можно было его поменять на любое другое число.
http://jtest.ru/bazyi-dannyix/sql-dlya-nachinayushhix-chast-3.html
>>862680
Нет, неверно. Ну вот смотри, что такое процент? Это 1/100 доля. Чтобы получить N % числа мы должны поделить его на 100 и умножить на N:
share = number / 100 * N
Чтобы увеличить число на N%, мы придавляем к нему эту долю:
number = number + number / 100 * N
number += number / 100 * N
Но тут можно пойти еще чуть дальше. В первом выражении number можно вынести за скобки и получается
number = number *(1+ N / 100)
number *= ...
> Что значит, начальный возраст + число прошедших лет? Начальное число одной переменной шестнадцать. А второй 0.
> Разве переменная может одновременно держать две разных цифры, автономных друг от друга?
Не может. Но мы можем сделать одну переменную, хранящую начальный возраст, вторую - сколько прошло лет и получить текущий возраст, сложив их.
Спасибо
Таблица 1 questions столбцы id, text_quest
Таблица 2 options столбцы id, text_option, qwant, id_quest
(Столбец id_quest в таблице 2, соответствует полю id в таблице 1)
"SELECT questions.text_quest, options.text_option, options.qwant
FROM `questions`
INNER JOIN `options`
ON questions.id = options.id_quest"
Само собой мне выводит в немного не нужном мне виде, мне надо, чтобы был многомерный массив, каждый массив которого содержал данные поля questions.text_quest и все варианты ответов options.text_option, как это сделать?
Я наверное немного не правильно объяснил, суть в том что есть две таблицы, в одной вопросы, в другой варианты ответов, мне надо на странице вывести вопрос а под ними варианты ответа на этот вопрос. Таблицы объединены внешним ключом.
Я используют такой запрос:
SELECT * FROM 'таблица_вопросов'
INNER JOIN 'таблица_ответов'
ON 'поле_ид_в_таблице вопросов' ='поле_ид_вопроса_в_таблице_ответов'
В итоге мне выводится массив в таком формате:
Array(
[0] => stdClass Object ( [text_quest] => Текст вопроса 1 [text_option] => Вариант ответа 1)
[1] => stdClass Object ( [text_quest] => Текст вопроса 1 [text_option] => Вариант ответа 2 )
[3] => stdClass Object ( [text_quest] => Текст вопроса 1 [text_option] => Вариант ответа 3 )
...
[0] => stdClass Object ( [text_quest] => Текст вопроса 2 [text_option] => Вариант ответа 1)
[1] => stdClass Object ( [text_quest] => Текст вопроса 2 [text_option] => Вариант ответа 2 )
[3] => stdClass Object ( [text_quest] => Текст вопроса 2 [text_option] => Вариант ответа 3 )
и т.д.
Как мне изменить формат вывода на более удобный? Конечно можно сделать в два запроса, вначале вызывать все вопросы и по полю id в каждом из них вызывать варианты ответа со всеми данными, но хотелось бы сделать в один.
А по другому никак разве нельзя? Разве нет команд для того чтобы получить что-то типа "Текст вопроса 1"=>array(
"Вариант ответа 1"=>array(
"текст ответа"=>"текст", "количество проголосовавших"=10),
"Вариант ответа 2"=>array(
"текст ответа"=>"текст", "количество проголосовавших"=30),
....
MySQL всегда возвращает результат в виде плоской таблицы. На то она и табличная база данных.
То есть вариантов как облагородить вывод нет? Никакие группировки не помогут? Это не так и плохо, а то я уже подумал что я тупой.
Аноны я поехал уже? Или это нормально?
> w5_2(переделал) http://ideone.com/US6sev
Ок, тут верно.
> в_тылу_врага http://ideone.com/30Nvg3
Все правильно.
> l33tspeak http://ideone.com/DJagBh
Верно.
> Лев Толстой http://ideone.com/NkKaTA
Тоже верно, хотя тут можно было сделать массив вариантов и пройтись по нему циклом:
$structure = [$word1, $word2, $word3, ["\n"], ...];
>>854570
> Генератор имён. http://ideone.com/Ltxckh
Правильно.
> Шифр http://ideone.com/ODeVzj
Верно, хотя у тебя при расшифровке точка превращается в твердый знак.
> L33t http://ideone.com/pAeeUC
Верно.
> Лев Толстой http://ideone.com/c0UXxS
Вот тут не очень удачно: $rndWord1=mt_rand(0,3); - надо вручную считать число слов в массиве и пересчитывать при изменении. Лучше без этого.
Также, первые 2 строки генерируются одинаково, потому можно использовать цикл чтобы избежать повторений.
Также, тут можно было сделать массив вариантов и пройтись по нему циклом:
$structure = [$word1, $word2, $word3, ["\n"], ...];
> Палиндром. http://ideone.com/uRe0gA
Правильно.
> Айпады и кредиты http://ideone.com/sGBReF
Неправильный ответ получается, там во втором банке около 61270 выходит.
И обрати внимание, у тебя ответ всегда кратен 5000. Поищи причину ошибки.
> if ($dolg > 5000) {
> } elseif ($dolg < 5000) {
А если ровно 5000?
> } elseif ($dolg < 0) {
Это условие никогда не сработает так как если долг отрицательный, сработает условие $dolg < 5000, которое выше.
Ну и переменные лучше не писать транслитом, посмотри в гуглопереводчике названия если не знаешь английский.
> w5_2(переделал) http://ideone.com/US6sev
Ок, тут верно.
> в_тылу_врага http://ideone.com/30Nvg3
Все правильно.
> l33tspeak http://ideone.com/DJagBh
Верно.
> Лев Толстой http://ideone.com/NkKaTA
Тоже верно, хотя тут можно было сделать массив вариантов и пройтись по нему циклом:
$structure = [$word1, $word2, $word3, ["\n"], ...];
>>854570
> Генератор имён. http://ideone.com/Ltxckh
Правильно.
> Шифр http://ideone.com/ODeVzj
Верно, хотя у тебя при расшифровке точка превращается в твердый знак.
> L33t http://ideone.com/pAeeUC
Верно.
> Лев Толстой http://ideone.com/c0UXxS
Вот тут не очень удачно: $rndWord1=mt_rand(0,3); - надо вручную считать число слов в массиве и пересчитывать при изменении. Лучше без этого.
Также, первые 2 строки генерируются одинаково, потому можно использовать цикл чтобы избежать повторений.
Также, тут можно было сделать массив вариантов и пройтись по нему циклом:
$structure = [$word1, $word2, $word3, ["\n"], ...];
> Палиндром. http://ideone.com/uRe0gA
Правильно.
> Айпады и кредиты http://ideone.com/sGBReF
Неправильный ответ получается, там во втором банке около 61270 выходит.
И обрати внимание, у тебя ответ всегда кратен 5000. Поищи причину ошибки.
> if ($dolg > 5000) {
> } elseif ($dolg < 5000) {
А если ровно 5000?
> } elseif ($dolg < 0) {
Это условие никогда не сработает так как если долг отрицательный, сработает условие $dolg < 5000, которое выше.
Ну и переменные лучше не писать транслитом, посмотри в гуглопереводчике названия если не знаешь английский.
Спасибо, исправил.
https://github.com/never3ver/students_list
Смущают вот какие моменты:
>Тут странно что радиокнопка всегда включена.
Выставлено, так сказать, значение по умолчанию, не совсем понимаю почему это странно.
>Также, ты ставишь атрибут required на радиокнопках - а как он применяется - к блоку радиокнопок в целом или к одной конкретной?
Я так понимаю, что радикнопки изначально предполагают выбор или или, так что к блоку.
>Баг: я ввел при регистрации год 1900, а он сохранился в БД и выводится как 0000.
Гугл говорит что тип YEAR корректно работает с промежутком 1901-2155. Как это лучше обойти?
Большое спасибо за комментарии, буду допиливать.
Я понял почему не работает условие - команда на умножение сохраняется только внутри echo.
Блин. Ну и что теперь делать.
a++ логичней внутри () прописывать, как ты раньше и делал
>>863132
Подсказка. Сейчас у тебя выводится 81 строка как думаешь, как я это узнал? А тебе сколько нужно? Вот сколько нужно, столько и задай
Кстати, ОП и знающие люди, а с давних пор в php конкатенацию можно делать запятыми? Чёт нагуглить немогу
Прыснул со смеху.
Вспоминаю себя конца прошлого года.
Но такое, правда, не вертел.
Ничего, скоро попрёшь вверх и вширь.
Конструкция echo позволяет указать несколько аргументов через запятую: http://php.net/manual/ru/function.echo.php
>>863165
Молодец, теперь правильно решено. Ну зато в циклах, надеюсь, разобрался.
>>863206
Кодировку соединения с БД может быть не задал?
http://ideone.com/885RFf
>Работает, перечитай мануал по этой функции.
Пик1 Php 7
Пик2 Php 5.4 на хосте Godaddy
Пик3 Php 5.4 на хосте Godaddy с 2 параметрами
Пик4 Код из мануала.
Скрины к тому, что я не придумываю, оно и вправду у меня только так работает.
пик 1 отклеился (
>Сейчас ифон добью и ваще кайф
Не всё так просто, друг мой.
Редко кто решает эту задачу правильно с первого раза.
"Спроектировать БД (можно в любом виде - таблицами, схемои - хоть от руки, SQL- фаилом). Есть саит интернет магазина. Там есть категории, которые могут быть вложены друг в друга (уровень вложенности не будет более 3х). В категориях находятся товары. На саите также есть личныи кабинет. В нем могут зарегистрироваться пользователи. У пользователя есть заказы, в которых есть товары."
Мое решение на пикриле и по ссылке дамп http://ideone.com/u0RIKT
Взлетит ли мое решение?
Как отличать категорию от товара в реализации Nested Set?
Что почитать на данную тему?
У тебя всего 5 таблиц, а ты уже всё запутал так, будто их у тебя 500. А смысл?
В Orders - 2 user_id? зачем?
bigint? У твоего мгазина будет 9 223 372 036 854 775 807 Юзеров?
Name 63? Тут ты зачем экономишь?
Если попросить функцию найти 1 ключ (то есть не ставить второй аргумент), она вернет не массив, а сам этот ключ. Ты это учел?
Разработчики функции явно не учли мою рекомендацию https://github.com/codedokode/pasta/blob/master/good-code.md#Тип-должен-быть-один
>>863307
> Как отличать категорию от товара в реализации Nested Set?
Категории и товары хранятся в разных таблицах. У тебя по моему товары и категории почему-то в одной таблице.
Писать в названии nestedTree не надо.
Таблица product_attribute не соответствет принципам нормализации (поле attribute_name не зависит от ключа целиком и значения дублируются).
Названия таблицы лучше писать как productAttributes. Во множ. числе.
Первичные ключи выбраны неверно в productsAttributes. Вспомни определение перв. ключа для начала.
Почитать про нормализацию в первую очередь: https://github.com/codedokode/pasta/blob/master/db/normalization.md
Возможно лучше сначала нарисовать сущности и виды связей между ними, а только потом таблицы.
>>863312
В bigint ничего сообо плохого. Не магазин, но я сталкивался когда int не хватает (например когда записи часто пересоздаются, также у мейл ру ид юзера это бигинт).
Если попросить функцию найти 1 ключ (то есть не ставить второй аргумент), она вернет не массив, а сам этот ключ. Ты это учел?
Разработчики функции явно не учли мою рекомендацию https://github.com/codedokode/pasta/blob/master/good-code.md#Тип-должен-быть-один
>>863307
> Как отличать категорию от товара в реализации Nested Set?
Категории и товары хранятся в разных таблицах. У тебя по моему товары и категории почему-то в одной таблице.
Писать в названии nestedTree не надо.
Таблица product_attribute не соответствет принципам нормализации (поле attribute_name не зависит от ключа целиком и значения дублируются).
Названия таблицы лучше писать как productAttributes. Во множ. числе.
Первичные ключи выбраны неверно в productsAttributes. Вспомни определение перв. ключа для начала.
Почитать про нормализацию в первую очередь: https://github.com/codedokode/pasta/blob/master/db/normalization.md
Возможно лучше сначала нарисовать сущности и виды связей между ними, а только потом таблицы.
>>863312
В bigint ничего сообо плохого. Не магазин, но я сталкивался когда int не хватает (например когда записи часто пересоздаются, также у мейл ру ид юзера это бигинт).
EAV надо использовать только для атрибутов, которые есть не у всех товаров. Если атрибут есть у всех товаров, например, цена, его надо добавлять как обычное поле.
Скорее всего нужна какая-то связь между категориями и допустимыми атрибутами товара. То есть у всех процессоров есть Тактовая Частота и число ядер, и это должно где-то храниться.
>я сталкивался когда int не хватает
2 миллиарда записей не хватает? Хотел бы я посмотреть на такую таблицу.
>Если попросить функцию найти 1 ключ (то есть не ставить второй аргумент), она вернет не массив, а сам этот ключ. Ты это учел?
У всех опы странные, а у нас самый лучший оп на свете. Спасибо!
Таблица с чем-то вроде кеша, где по крону пересоздаются порядка миллиона или нескольких записей (ссылающихся на другую таблицу). За полтора года лимит id был исчерпан и посыпались ошибки.
>Таблица product_attribute не соответствет принципам нормализации (поле attribute_name не зависит от ключа целиком и значения дублируются).
>Первичные ключи выбраны неверно в productsAttributes. Вспомни определение перв. ключа для начала.
Если убрать поле id, а поля product_id и attribute_name сделать первичным ключом, то я молодец?
Сударь, вы охуенны!
Задача 2.
Лиличка
http://ideone.com/r7UONQ
Ошибка при обращении к несуществующему элементу массива проявляется. Может кто подскажет как её обойти?
код не читай@разу отвечай
для проверки существования значения переменной (элемента массива) можно использовать специальную функцию isset(value)
> count($lines)+10;
а зачем ты прибавляешь к строкам 10? У тебя получается 10 лишних итераций цикла. Похоже ты опечатался.
>EAV надо использовать только для атрибутов, которые есть не у всех товаров
Ты предлагаешь сделать одну "широкую" таблицу для общих свойств, а остальные хранить при помощи модели EAV?
https://github.com/ghp26/Students
Переписал и исправил почти все кроме пары вещей.
>валидировать лучше не массив неизвестной структуры, а модель студета. »наче твой валидатор заточен только на работу с формой и им нельз¤ например проверить данные из базы.
Вот это не понял. валидатор заточен для работы с формой и больше ни для чего другого не используется.
>У тебя тут расчет что массив содержит все нужные поля. Но вообще, массив POST может и не содержать их или содержать массивы вместо строк например. Нужно сделать чтобы код не выдавал ошибок в такой ситуации.
Да, у меня расчет что массив POST содержит все нужные поля, и это не безосновательно, потому что все поля POSTa проверяются валидатором и если в них есть ошибки, то код не поломается, а выведет странцу на которой будет указанно(подчеркнуто красным и написано текстом) что именно введено не правильно
"WHERE `birth` LIKE %текст_на_кирилице%" выдает ошибку SQL General error: 1271 Illegal mix of collations for operation 'like'
Что с этим делать так и не придумал, поэтому поиска по дате пока нет. Вообще совершенно внезапно прога начала выдавать эту ошибку.
>Почитать про нормализацию в первую очередь: https://github.com/codedokode/pasta/blob/master/db/normalization.md
только тут их всего 3 , а на самом деле то их 5 уровней нормализации
Их больше 5-и, ты на практике все используешь?
Скопировал с той пасты:
> Другие нормальные формы
> Еще есть более строгие BCNF, 4NF, 5NF, 6NF. Про них можно почитать в статьях по ссылкам выше, ...
Ссылку давай, так непонятно ничего.
В любом случае, в минус не должно ничего уходить: получается, что так банк тебе платит в какой-то момент, а ты ему возвращаешь часть, логики нет.
http://ideone.com/e.js/MHoMsH
Вот. В минус уходить не должно.
А я подумал в задачи написано про минус вообще, что типа условие внутри тела не работает. Ок, ща покумекаю.
Вот такого вида должна быть ссылка: http://ideone.com/MHoMsH
А выведи там сумму долга - какая получится? Почему ты думаешь, что получилась верная сумма?
Пока вижу, что всё неправильно, должно получиться в итоге 61270 рублей со многими копейками.
А по условиям задачи пацан знает о текущем долге?
Т.е. он видит что можно заплатить меньше 5к?
Если да, то какая проблема просто еще одним условием урезать уплату долга до такого значения, чтобы в ноль ушло?
Попробовал проверять на массиве двойной вложенности, и заработало. В коде выше, почему-то isset выдавал что элемент массива существует, а потом снова ошибку.
Спасибо тебе добрый анон за помощь.
>>863448
Я пробовал искатть максимальное количество элементов в массиве символов (в строке), но после этого я получил много ошибок при работе с массивом и вынужден был уискать другие пути.
Попытался сделать с разметкой как у опа, но я слишком ньюфаг для этого.
http://ideone.com/cPXoQI
Не знаю.
>>855719
> 11: http://ideone.com/sbm9XK
> return (a.population < b.population) ? 1 : -1;
Ты не проверяешь ситуацию, когда население равно и надо вернуть 0. Из-за этого при сортировке может быть ошибка. Алсо, есть интересный хак:
return a.population - b.population, хотя конечно такие хаки стоит как минимум комментировать.
В остальном верно.
> 12: http://ideone.com/fu1J3t
> Hamburger.sizeList = {
> "small": {money: 50, calories: 20},
для обозначения типа надо тут тоже использовать константу, а то если мы поменяем определение на
Hamburger.SIZE_SMALL = 1;
то все перестанет работать.
> " Разрешены размеры: " + Object.keys(Hamburger.sizeList) + ".
А это можно, складывать строку и массив? Интересно. Я бы добавил join рад пробела после запятой.
> this._size = Hamburger.sizeList[size];
Я думаю, правильнее хранить исходные данные. Свойство называется размер а не стоимость и число калорий с указанным размером. Более того, как ты напишешь условие "если этот гамбургер маленький"? Надо хранить сам размер, а не прозводные данные.
> for (var topping in this._toppings) {
Имей в виду, что у цикла for .. in есть проблемы если кто-то расширит прототип Object - добавленные в прототип свойства попадут в цикл:
- https://learn.javascript.ru/prototype
- https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Statements/for...in#Проход_только_через_собственные_свойства.
Я обновил задачу, добавив описание класса Гамбургер.
> 14: http://ideone.com/QQnfE5
> if (typeof data == "object" && data.length > 0) {
Неточное определение array-like. Array-like это любой объект у которого есть length >= 0 и свойства 0 .. length - 1. Кроме arguments это например
- {length: 2, 0: 'a', 1: 'b' }
- document.body.children
- document.links
>>855731
Использование ООП в твоем случае вряд ли повлияет на производительность. Оно лишь позволяет грамотно организовать код, разложив его по классам.
Не знаю.
>>855719
> 11: http://ideone.com/sbm9XK
> return (a.population < b.population) ? 1 : -1;
Ты не проверяешь ситуацию, когда население равно и надо вернуть 0. Из-за этого при сортировке может быть ошибка. Алсо, есть интересный хак:
return a.population - b.population, хотя конечно такие хаки стоит как минимум комментировать.
В остальном верно.
> 12: http://ideone.com/fu1J3t
> Hamburger.sizeList = {
> "small": {money: 50, calories: 20},
для обозначения типа надо тут тоже использовать константу, а то если мы поменяем определение на
Hamburger.SIZE_SMALL = 1;
то все перестанет работать.
> " Разрешены размеры: " + Object.keys(Hamburger.sizeList) + ".
А это можно, складывать строку и массив? Интересно. Я бы добавил join рад пробела после запятой.
> this._size = Hamburger.sizeList[size];
Я думаю, правильнее хранить исходные данные. Свойство называется размер а не стоимость и число калорий с указанным размером. Более того, как ты напишешь условие "если этот гамбургер маленький"? Надо хранить сам размер, а не прозводные данные.
> for (var topping in this._toppings) {
Имей в виду, что у цикла for .. in есть проблемы если кто-то расширит прототип Object - добавленные в прототип свойства попадут в цикл:
- https://learn.javascript.ru/prototype
- https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Statements/for...in#Проход_только_через_собственные_свойства.
Я обновил задачу, добавив описание класса Гамбургер.
> 14: http://ideone.com/QQnfE5
> if (typeof data == "object" && data.length > 0) {
Неточное определение array-like. Array-like это любой объект у которого есть length >= 0 и свойства 0 .. length - 1. Кроме arguments это например
- {length: 2, 0: 'a', 1: 'b' }
- document.body.children
- document.links
>>855731
Использование ООП в твоем случае вряд ли повлияет на производительность. Оно лишь позволяет грамотно организовать код, разложив его по классам.
> (А|В|Е|К|М|Н|О|Р|С|Т|У|Х)
Удобнее использовать тут символьные классы: [АВЕКМНО...]
> {1}
Это можно было не писать
У тебя нет привязки к краям строки потому номер щщщщщооооо123ооооо тоже пройдет проверку.
> for ($i=0;$i<$arCount;$i++){
тут лучше foreach
> как добавить поддержку номеров типа z123df
Добавить a-z в символьный класс.
>>855750
Сложный алгоритм, при этом нет комментария. Имена переменных однобуквенные так что понять что они значат, трудно. Что значит $pew? Как это читать и проверять? Имена переменных должны начинаться с маленькой буквы.
> // заполнение массива значением long, до 6600
Там наверно надо брать сумму, а не заложенное жестко число 9999
> $nominals = array(100, 200, 500, 1000, 2000, 5000);
Этот массив можно получить из $check.
> $check[0] = array(
Не очень понятно почему не просто $check = array ...
переименуй переменные, добавь комментарии и ссылку на алгоритм, а пока проверить код трудно.
>>855761
Те же замечания что и к предыдущей версии задачи выше.
>>855765
Может логично для каждой статьи делать одноименную папку?
> (А|В|Е|К|М|Н|О|Р|С|Т|У|Х)
Удобнее использовать тут символьные классы: [АВЕКМНО...]
> {1}
Это можно было не писать
У тебя нет привязки к краям строки потому номер щщщщщооооо123ооооо тоже пройдет проверку.
> for ($i=0;$i<$arCount;$i++){
тут лучше foreach
> как добавить поддержку номеров типа z123df
Добавить a-z в символьный класс.
>>855750
Сложный алгоритм, при этом нет комментария. Имена переменных однобуквенные так что понять что они значат, трудно. Что значит $pew? Как это читать и проверять? Имена переменных должны начинаться с маленькой буквы.
> // заполнение массива значением long, до 6600
Там наверно надо брать сумму, а не заложенное жестко число 9999
> $nominals = array(100, 200, 500, 1000, 2000, 5000);
Этот массив можно получить из $check.
> $check[0] = array(
Не очень понятно почему не просто $check = array ...
переименуй переменные, добавь комментарии и ссылку на алгоритм, а пока проверить код трудно.
>>855761
Те же замечания что и к предыдущей версии задачи выше.
>>855765
Может логично для каждой статьи делать одноименную папку?
RAR? Боюсь что мне пока что неохота это скачивать, копировать, настраивать сервер. Начни с отладчика в браузере (Ctrl + Shift + I), почитай про него https://learn.javascript.ru/debugging-chrome
Посмотри, какие данные отправляются, что происходит на сервере. Посмотри логи ошибок веб-сервера (error.log). Также, ты можешь использовать встроенный в PHP веб-сервер, который пишет запросы и ошибки в консоль. Если ты работаешь с БД, то убедись что включен режим выброса исключений при ошибке.
Натыкай в скрипт var_dump и посмотри какие данные куда приходят, что в переменных, что возвращают функции. Найди строку, которая работает не так, как надо.
В общем, изучи и изложи суть проблемы более подробно. Какие данные приходят в скрипт, какая строчка работает не так, что пишется. В какой строчке проблема.
>>855787
> очему не работает доступ к символу через $char = $text[1].
Потому что пхп криво спроектирован в этом случае. [1] берет не второй символ, а второй байт строки. А в utf-8 символ может занимать несколько байт и ты его в принципе получить не можешь целиком без mb_substr. В общем, непродуманно сделано, они ориентировались на древние 1-байтные кодировки которые мы сейчас не используем (так как в них нельзя использовать более 256 символов).
Почитать https://gist.github.com/codedokode/ff99e357e9860ea169b8
> ни echo $char, ни var_dump($char) - ничего не выводят.
Они выводят один байт из нескольких, только половину буквы.
> http://ideone.com/SuS3yI - палиндром
Выглядит верно, но хотелось бы увидеть работающую версию кода, а не закомментированную.
> http://ideone.com/eTXny3 - Лев Толстой.
Код очень переусложнен. Также, ты используешь неудачные имена переменных вроде $all1_3Words, all2Words которые легко перепутать и плохо читаются (1 похожа на l). Подчеркивание не используется в PSR.
тут надо либо сделать по-простому, либо сделать массив с вариантами слов и пройтись по нему циклом:
$structure = [$word1, $word2, ["\n"], ...];
>>855931
ALTER TABLE во многих случаях сводится к пересозданию таблицы (создание нового файла таблицы, копирования в него данных и замены старого файла), если она большая то это определяется временем чтения и записи на диск (гигабайт нельзя мгновенно прочитать). Выгоднее делать один большой ALTER TABLE чем много маленьких.
И странно что ты делаешь изменение структуры БД из веб-скрипта. Такие вещи надо запускать в командной строке, также погугли про миграции. По моему ты изобретаешь велосипед.
Ну и mysql_fetch_array устарел несколько лет назад. Изучай PDO.
RAR? Боюсь что мне пока что неохота это скачивать, копировать, настраивать сервер. Начни с отладчика в браузере (Ctrl + Shift + I), почитай про него https://learn.javascript.ru/debugging-chrome
Посмотри, какие данные отправляются, что происходит на сервере. Посмотри логи ошибок веб-сервера (error.log). Также, ты можешь использовать встроенный в PHP веб-сервер, который пишет запросы и ошибки в консоль. Если ты работаешь с БД, то убедись что включен режим выброса исключений при ошибке.
Натыкай в скрипт var_dump и посмотри какие данные куда приходят, что в переменных, что возвращают функции. Найди строку, которая работает не так, как надо.
В общем, изучи и изложи суть проблемы более подробно. Какие данные приходят в скрипт, какая строчка работает не так, что пишется. В какой строчке проблема.
>>855787
> очему не работает доступ к символу через $char = $text[1].
Потому что пхп криво спроектирован в этом случае. [1] берет не второй символ, а второй байт строки. А в utf-8 символ может занимать несколько байт и ты его в принципе получить не можешь целиком без mb_substr. В общем, непродуманно сделано, они ориентировались на древние 1-байтные кодировки которые мы сейчас не используем (так как в них нельзя использовать более 256 символов).
Почитать https://gist.github.com/codedokode/ff99e357e9860ea169b8
> ни echo $char, ни var_dump($char) - ничего не выводят.
Они выводят один байт из нескольких, только половину буквы.
> http://ideone.com/SuS3yI - палиндром
Выглядит верно, но хотелось бы увидеть работающую версию кода, а не закомментированную.
> http://ideone.com/eTXny3 - Лев Толстой.
Код очень переусложнен. Также, ты используешь неудачные имена переменных вроде $all1_3Words, all2Words которые легко перепутать и плохо читаются (1 похожа на l). Подчеркивание не используется в PSR.
тут надо либо сделать по-простому, либо сделать массив с вариантами слов и пройтись по нему циклом:
$structure = [$word1, $word2, ["\n"], ...];
>>855931
ALTER TABLE во многих случаях сводится к пересозданию таблицы (создание нового файла таблицы, копирования в него данных и замены старого файла), если она большая то это определяется временем чтения и записи на диск (гигабайт нельзя мгновенно прочитать). Выгоднее делать один большой ALTER TABLE чем много маленьких.
И странно что ты делаешь изменение структуры БД из веб-скрипта. Такие вещи надо запускать в командной строке, также погугли про миграции. По моему ты изобретаешь велосипед.
Ну и mysql_fetch_array устарел несколько лет назад. Изучай PDO.
Не знаю конкретную книгу, но там обязательно должна изучаться нормализация, виды связей между таблицами, первичные и внешние ключи.
Алсо у нас есть немного задачек и ссылок https://github.com/codedokode/pasta/blob/master/db/databases.md
https://github.com/never3ver/fileshare/blob/master/public/index.php#L92
Пытаюсь реализовать отображение страницы ошибки при отсутствии файла для скачивания, ситуация абсолютно идентична как для обработчика самого слима так и для самописного обработчика.
При нажатии на ссылку "скочять" фаерфокс сначала показывает свою страницу об ошибке, что-то там про "firefox couldn't find...", при обновлении либо нажатии try again отображается уже то что и должно вылезать, т.е. моя страничка с ошибкой или страничка обработчика слима. Хромиум вообще пытается скачать файл весом 0 с именем плейсхолдера.
Далее, и в лисе и в хромиуме при прописывании ссылки в адресной строке или открытии ссылки в новой вкладке/окне все работает как часы, т.е. я сразу вижу то что должно быть. Почему так?
З.Ы. ОП, у тебя случайно нет урока по PSR-7?
Надо бы открыть отладчик в браузере (Ctrl + Shift + I) и посмотреть на вкладке network что там посылается и получается.
Также можно установить Wireshark, но он не ловит пакеты на 127.0.0.1, тебе надо узнать IP на сетевой карте и обращаться к нему. В Вайршарке будет видно все, что пересылается. желательно закрыть все лишние программы чтобы было меньше мусорного трафика.
В любом случае ты должен не гадать вслепую, а уметь посмотреть HTTP запросы и ответы.
В гугле есть уроки https://www.google.ru/search?q=psr-7&newwindow=1&gbv=1&sei=wT0QWKKKKJHLsAGnkzY хотя по моему если долго смотреть на код из самого стандарта то более менее понятно станет. Там описаны интерфейсы для классов, которые представлояют разные виды HTTP сообщений (запрос/ответ). Мне немного не нраится что туда еще $_SERVER засунули который мало отношения имеет к HTTP.
Для показа страниц ошибки может быть стоит сделать функию.
Еще один вариант - использовать отладчный прокси вроде Fiddler который ставится между браузером и сервером и перехватывает запросы.
Надо кликнуть на строчку в таблице запросов чтобы увидеть подробности.
Также, подумай над использованием Fiddler или Wireshark.
Хотя не, под виндой Wireshark не ловит пакеты, отправляемые с хоста на тот же хост. Надо заморачиваться: https://wiki.wireshark.org/CaptureSetup/Loopback
Тогда у тебя все хорошо. У тебя есть низкоуровневый инструмент - tcpump + GUI инструмент WireShark который все отлично будет перехватывать. Обязательно попробуй его.
Вот пример использования tcpdump- https://texnoblog.wordpress.com/2010/04/17/using-tcpdump/ - его просто запустить, но увы, он выводит пакеты, а не собранный HTTP диалог. Ели ты не разбираешься в TCP/IP то будет немного сложно понять.
Также, есть такая тулза как curl. С ней легко отправить запрос руками:
curl -v 'http://lalala/lololo'
(он разумеется умеет и другие виды запросов делать).
Также есть такой прокси https://mitmproxy.org/ - он запускается и прописывается в настройки браузера и запросы идут через него.
Я обычно просто курлом запрос отправляю.
спасибо, я прочитал урок, про нормализацию даже понял/заучил первые 3 формы. По ссылкам прошелся, часть задач решил, но вопрос именно про проектирование базы данных для типичных задач, вроде способов хранения свойств товара. В нете есть много статей, но они все отрывочны и словно пересказ пересказа. 99% предлагают EAV. Также нашел еще 2 решения: для каждой категории товаров своя таблица, и общая таблица для всех товаров (поля с отсутствующими свойствами товаров заполняются NULL).
>>863333
Выше предлагал сделать одну таблицу с общими свойствами цена/название, а индивидуальные свойства категорий товаров реализовать с помощью EAV?
Обязательно покопаюсь в этой теме подробнее, сейчас я запустил wireshark и вот что заметил: пикрилейтед показывает, что при отображении фаерфоксом собственной заглушки, это второй пик >>863783, в теле ответа есть верстка. Почему она не обрабатывается браузером?
В общем действительно все как нужно возвращается, как-то даже не знаю что дальше с этим делать.
Длинна контента у сервера не такая как у документа. Смотри заголовок Content-Length, а потом посмотри сколько занимает твоя разметка.
Попробовал через оперу, старую, еще до вебкита, в ней все норм! Даже в links работает как надо, кек. В общем я воткнулся в тупик с этой ситуацией.
Резюмируя: сервер получает запрос и отдает правильный ответ, на который странно реагируют лиса и хромиум, лиса думает что у ответа нет тела, хромиум вообще ничего не думает и пытается скачать файл с нулевым размером, при обращении по вбиванию ссылки в адресной строке и при пкм и открытии в новой вкладке все норм. При этом старая опера и консольный линкс реагируют адекватно без всяких проблем, уверен что остальной зоопарк маргинальных линуксобраузеров также покажет отсутствие каких-либо неприятностей. Какая-то НЁХ.
Все, решил проблему. Дело было в наличии атрибута download в ссылке. Потому и некробраузеры нормально реагировали, им этот атрибут по всей видимости неизвестен.
У тебя не вычисляется в последний месяц 1000 за кредит и три процента от 200 с чем-то рублей.
Но вот сами эти 200 с чем-то рублей прибавляются.
Задача - на последнем круге прибавить и 1000 + 3% от 200.
>Ну и mysql_fetch_array устарел несколько лет назад. Изучай PDO.
Этот поезд в огне, но по прежнему едет в Бабруйск. PDO будет в версси 2.0.
Мне нужно заменить в таблице все запятые точками, за исключением первого столбца. Как это сделать? Если имена столбцов известны, то можно просто их прописать в запросе типа
$request_create_table = "UPDATE $table_1c SET `НДФЛ` =REPLACE (`НДФЛ`, ' ', '');";
Но если их много и они могут изменяться? Можно, конечно, подсчитать количество столбцов, потом запустить цикл и последовательно в каждом столбце изменить (за исключением первого), но мне кажется, должно быть более простое решение. Или нет?
Банкомат. Сложный вариант.
https://ideone.com/CT8F66
Добавил подробный комментарий и переименовал некоторые переменные.
>Там наверно надо брать сумму, а не заложенное жестко число 9999
Нет, там так и задумано, но если есть вариант лучше - с удовольствием выслушаю.
>Этот массив можно получить из $check.
Мне нужны были в цикле не только значения номиналов(100, 200, 500), но и их ключи для более простой записи(они используются в цикле где инициализирована переменная $i), но если возможно использовать один массив, при этом не сильно усложняя запись кода - так и сделаю.
>Не очень понятно почему не просто $check = array ...
у каждой суммы, которую можно выдать - свой запас банкнот, который хранится в $check[n], где n - сумма, которую нужно выдать. При этом используются только те элементы массива $check, при котором возможно выдать сумму n используемыми номиналами, если сумму выдать невозможно, в элементе массива $check[n] будет NULL.
Ладно, уже не нужно, я так и сделал, как описал.
Да, знает и видит, что можно заплатить меньше 5к.
Но дело в том, что вот на последнем месяце ему надо заплатить 200 рублей - а ведь ещё и 1000 за обслуживание кредита, а ещё 3% от этих 200 рублей.
Там в какой-то момент сумма становится 4к - а к ним прибавляется 1000 за обслуживание и проценты, в итоге как раз остаётся 200р, к которым опять тыщу и проценты нужно прибавить.
Вот тут какая логика.
> А это можно, складывать строку и массив? Интересно. ...
Не рекомендуется все что кроме строк складывать со строками? А то мне понравилось, что в js есть возможность преобразования любого объекта в строку (toString), которое еще можно по-своему сделать.
> для обозначения типа надо тут тоже использовать константу ...
SMALL_SIZE: {money: 50, calories: 20},
Вот так? Или как. Кстати, а есть ли возможность в js узнать имя переменной? Я пытался в первом решении этой задачи вытащить имя константы из Hamburger.ИМЯ_КОНСТАНТЫ, но не нагуглил как такое возможно.
Оригинальное решение, неплохо, не шаблонно.
include "inc\db.php";
include "inc\quest.php";
include "inc\quest_maper.php";
include "inc\option.php";
include "inc\option_maper.php";
Пытаюсь добавить ещё один файл:
include "inc\voter.php";
Выводит ошибку failed to open stream
Если записать вот так:
include "inc/voter.php";
Всё начинает работать, причём слеш в предыдущих подключениях не меняю, всё выглядит таким образом:
include "inc\db.php";
include "inc\quest.php";
include "inc\quest_maper.php";
include "inc\option.php";
include "inc\option_maper.php";
include "inc/voter.php";
Почему так странно?
include "inc\db.php";
include "inc\quest.php";
include "inc\quest_maper.php";
include "inc\option.php";
include "inc\option_maper.php";
Пытаюсь добавить ещё один файл:
include "inc\voter.php";
Выводит ошибку failed to open stream
Если записать вот так:
include "inc/voter.php";
Всё начинает работать, причём слеш в предыдущих подключениях не меняю, всё выглядит таким образом:
include "inc\db.php";
include "inc\quest.php";
include "inc\quest_maper.php";
include "inc\option.php";
include "inc\option_maper.php";
include "inc/voter.php";
Почему так странно?
Вряд ли это поможет, но я читал о том, что если использовать include/require вместо include_once/require_once, то это может привести к проблемам при множественном подключении различных скриптов. В одном из include'ов вверху есть уже include "inc\voter.php"?
Почему ты просто не используешь автозагрузчик композера, твои обратные слеши не будут под линуксом работать.
Бесслеш а строках в кавычках имеет специальное значение, читай мануал http://php.net/manual/ru/language.types.string.php
>>864216
Скоро
>>864205
> SMALL_SIZE: {money: 50, calories: 20},
> Вот так?
Нет, не так. Обычно исплоьзуют число или строку в качестве значения. Я специально в комментариях к задаче написал что если поменять значение константы, программа должна работать так же как и раньше.
Константа используется для обозначения типа гамбургера, а не хранения его цены.
> Не рекомендуется все что кроме строк складывать со строками?
Главное чтобы ты понимал, по каким правилам происходит это сложение. Не сказал бы что это полезная фича, из-за нее ошибки остаются незамеченными, например:
return "Size: " + hamburger;
вместо
return "Size: " + hamburger.getSize();
Из-за того, что JS позволяет строку сложить с объектом, ошибка в первом варианте остается незамеченной.
> if (is_array($value)) {
мне кажется проще все значения сделать массивами, просто там, где единственный вариант, делать массив из 1 элемента, например ["\n"]. Хотя не знаю, твой вариант тоже в годится.
>>863842
Хороший повод не использовать атрибут download (либо написать разработчикам браузера в багтрекер). Я не знал про такую особенность. Как по мне, так лучше не пользоваться тогда этим атрибутом, а полагаться на Content-disposition.
Еще у некоторых браузеров есть/была особенность, что если тело страницы с ошибкой меньше определенного порога, то они вместо нее показывают свою. Может у старых ИЕ была такая проблема.
https://blogs.msdn.microsoft.com/ieinternals/2010/08/18/friendly-http-error-pages/
http://www.404-error-page.com/404-error-page-too-short-problem-microsoft-ie.shtml
В случае с товарами мы имеем наследование таблиц (то есть мы можем вообразить что у нас есть таблица товаров-процессоров, таблица товаров-монитров, и тд и все они унаследованы от базовой таблицы товаров). Для наледования таблиц есть несколько стандартных паттернов:
http://design-pattern.ru/patterns/class-table-inheritance.html
http://design-pattern.ru/patterns/single-table-inheritance.html
http://design-pattern.ru/patterns/concrete-table-inheritance.html
Но в случае с товарами:
1) видов товаров очень много так что например реализация Class Table Inheritance потребует кучу таблиц и приведет к гигантским запросам с джойнами
2) свойства и категории товаров могут добавляться менеджерами без привлечения программиста - значит надо бы это делать без изменения структуры базы
Потому в таких случаях используют EAV. Она обычно содержит примерно такие таблицы (пишу по памяти, могут быть неточности):
- таблица категорий товаров
- таблица всех существующих свойств
- таблица связи М-М между категориями и свойствами
- таблица значений свойств, перв ключ в ней (id товара + id свойства), плюс она обычно содержит колонки вроде intValue, stringValue, dateValue для разных типов значений
EAV имеет и недостатки. Это некоторая громоздкость запросов и возможные иногда затыки с производительностью. Для борьбы с ними можно использовать разные формы кеширования, в том числе и с хранением денормализованных (избыточных) данных в самой БД.
Но обычно все же используеют именно EAV благодаря ее гибкости и расширяемости и соответствию принципам нормализации.
> Также нашел еще 2 решения: для каждой категории товаров своя таблица, и общая таблица для всех товаров (поля с отсутствующими свойствами товаров заполняются NULL).
Это реализации описанных выше паттернов.
> вопрос именно про проектирование базы данных для типичных задач,
Ну вот в моем уроке перечислены основные принципы на основе которых делается проектирование:
https://github.com/codedokode/pasta/blob/master/db/databases.md#Теория-по-проектированию-БД
И самое главное это конечно нормализация и избегание дублирования данных.
Ты можешь поискать книги по проектированию, но я подозреваю, что там будет в итоге примерно то же самое написано.
В случае с товарами мы имеем наследование таблиц (то есть мы можем вообразить что у нас есть таблица товаров-процессоров, таблица товаров-монитров, и тд и все они унаследованы от базовой таблицы товаров). Для наледования таблиц есть несколько стандартных паттернов:
http://design-pattern.ru/patterns/class-table-inheritance.html
http://design-pattern.ru/patterns/single-table-inheritance.html
http://design-pattern.ru/patterns/concrete-table-inheritance.html
Но в случае с товарами:
1) видов товаров очень много так что например реализация Class Table Inheritance потребует кучу таблиц и приведет к гигантским запросам с джойнами
2) свойства и категории товаров могут добавляться менеджерами без привлечения программиста - значит надо бы это делать без изменения структуры базы
Потому в таких случаях используют EAV. Она обычно содержит примерно такие таблицы (пишу по памяти, могут быть неточности):
- таблица категорий товаров
- таблица всех существующих свойств
- таблица связи М-М между категориями и свойствами
- таблица значений свойств, перв ключ в ней (id товара + id свойства), плюс она обычно содержит колонки вроде intValue, stringValue, dateValue для разных типов значений
EAV имеет и недостатки. Это некоторая громоздкость запросов и возможные иногда затыки с производительностью. Для борьбы с ними можно использовать разные формы кеширования, в том числе и с хранением денормализованных (избыточных) данных в самой БД.
Но обычно все же используеют именно EAV благодаря ее гибкости и расширяемости и соответствию принципам нормализации.
> Также нашел еще 2 решения: для каждой категории товаров своя таблица, и общая таблица для всех товаров (поля с отсутствующими свойствами товаров заполняются NULL).
Это реализации описанных выше паттернов.
> вопрос именно про проектирование базы данных для типичных задач,
Ну вот в моем уроке перечислены основные принципы на основе которых делается проектирование:
https://github.com/codedokode/pasta/blob/master/db/databases.md#Теория-по-проектированию-БД
И самое главное это конечно нормализация и избегание дублирования данных.
Ты можешь поискать книги по проектированию, но я подозреваю, что там будет в итоге примерно то же самое написано.
Пользователь может сменить и IP и куки и при желании даже User-Agent. Вопрос лишь в том, что стоит на кону. Если ценный приз - накрутят сколько угодно голосов.
Можно требовать телефон или паспортные данные.
А, локация ДС.
http://ideone.com/VC2y4t
Да, в задаче сказано сколько человек в классе и сколько слогов в считалочке, но ничего не сказано о том, сколько человек должно в итоге остаться пить чай. Поэтому у меня это 7 человек. И наверное поэтому у меня и у ОПа разные ответы (хотя скорее всего я неправильно решил задачу.)
есть задачка
Например: есть число 123, то программа должна вычислить сумму цифр 1, 2, 3, т. е. 6.
мое решение
$numberRandom = 55;
$array = str_split($numberRandom);
echo array_sum($array);
решение автора
$number = "1547";
$sum = 0;
for($i = 0; $i <= strlen($number); $i++) {
$sum += $number[$i];
}
echo $number."<br/>";
echo $sum;
все разное, но мое короче
или что то я сделал не так?
Мне нужно кешировать html-странички (чтобы не мучать чужой сайт запросами) и я не особо понимаю зачем страницы сериализовать и имена прогонять через md5.
Думаю, разобрался. Функция md5 нормализует имя файла, так как её результат - только латинские буквы и цифры, без слешей и прочих ненужных символов. А сериализация мне не нужна, так как я сохраняю только страницы, а не переменные.
Мне не нравится использование md5 так как имена нечитаемые. Лучше как-то по другому фильтровать допустимые символы.
Я не разбирался с алгоритом работы md5, но он ведь 100% даст уникальное имя для URL? А мои функции, фильтрующие слеши и все остальные символы, могут в теории дать разным URL одинаковые имена при создании кеш-файла. Например, если я буду убирать из URL символы [^\w\d]
Или можно просто сделать preg_replace для '/' и '\' на 'slash'.
md5 дает не 100% уникальное имя так как его результат может быть короче чем само имя. Но на практике коллизии практически не бывают.
md5 недостаточно так как 2 пользователя могут загрузить файл с одинаковым именем.
Чтобы избежать коллизий лучше всего добавлять в имя уникальное число. Например, номер файла.
Калькулятор
> Перенес switch в функцию, так будет правильней?
> if ($char == '=') {
> $result = calculate($op, $numberText, $result);
> } else {
> $result = calculate($op, $numberText, $result);
> }
Не очень понятно, зачем if, если обе ветки одинаковы.
Считает вроде верно.
Навигатор
>>Попробуй написать решение с рекурсией
> Что-то слепил, немного не по предложенному алгоритму. Поэкспериментировал, вроде бы решает верно.
> static $allPath = array();
Вот это неправильно. Эта же переменная никуда не исчезает и при попытке проложить второй маршрут в ней останутся данные из первого. Получается побочный эффект. Очевидно тут нельзя ее использовать.
Функция не должна ничего сохранять в долгоживущую переменную. Она получает нужные ей данные через аргументы и возвращает через return.
Маска файла
>>Также, дам дополнительную задачку на рекурсию, чтобы лучше в ней разобраться
Некорректно работает для маски te*?? и имени tennis ( http://ideone.com/UuWPSV ). Значит, есть ошибки в алгоритме.
Я думаю, проблема в том, как ты обрабатываешь звездочку. Ты при наличии звездочки сначала проверяешь версию, что она не соответствует ни одному символу:
return doOneStep(mb_substr($mask, 1), $filename, $lMask);
А только потом, в другом месте, ниже, пробуешь убрать один символ из файла. Но это происходит в самом конце функции и если после звездочки идет знак вопроса, до туда просто не доходит выполнение.
Не надо разносить код обработки звездочки на 2 части. Надо вписать его внутри if ($lMask == '*').
Там можно использовать либо цикл либо рекурсию. Кстати, перебирать варианты можно в 2 направлениях:
- попытаться захватить зведочкой весь остаток имени, а если не сработает, убавлять символы по одному - это "жадный" подход, звездочка пытается съесть максимум символов
- наоборот, попытаться захватывать по 1 символу, увеличивая длину - это "нежадный" подход
То есть логика тут примерно такая:
- если в маске встретилась звездочка, она может соответствовать от 0 до N любых символов. Соответственно, делаем цикл и перебираем все варианты, пока какой-нибудь не сработает. Либо рекурсия (то же самое, но другим способом): вызываем сами себя 2 раза: со звездочкой и отрезанной буквой от имени и без звездочки и проверяем, совпал ли хоть один. Но мне кажется, с циклом будет нагляднее. Тут жадность звездочки определяется порядком вызова.
Навигатор
> Нормально ли здесь использовать global или нужно всё же передавать через параметры?
Не, это плохая идея так как создает побочные эффекты и затрудняет понимание работы функции.
> $labels[$point] = PHP_INT_MAX;
есть еще константа, обозначающая бесконечность - INF
> function doAlgorithmDijstra($labels, $visited)
Комментарии улучшают код, но тут стоило бы дописать еще тайп-хинты (array $labels).
> Поиск вершины с наименьшей меткой
Это можно было вынести в отдельную функцию ради читабельности.
> foreach ($labels as $label => $value) {
$label наверно правильнее было назвать как $pointName, а $value как $distance или $time или $label.
> $nextPoint = $paths[$workPoint];
Не $nextPoint, а $nextPoints (множ. число)
Сама реализация выглядит верно.
> В алгоритме сказано:
> ".. из ещё не посещённых вершин выбирается вершина u, имеющая минимальную метку", для этого я выполняю:
> вроде бы всё по алгоритму…
Ну ок, значит я не разобрал код правильно. Может потому, что он был не очень понятный. Сейчас намного лучше.
Числа прописью
Выглядит верно, хотя там перед скобкой лишний пробел затесался.
Вектор
> Убрал в функция createEmployee, padLeft, padRight - тайп-хинт
> //Для int и string, т.к. ideone считает их за объекты
Это потому что там PHP5, а не PHP7.
> Метод возвращающий имя компании
Лучше "Возвращает название компании"
Комментарии в общем хорошие. Но не менее важно давать такие имена переменным и методам, чтобы их назначение было понятно без комментария (у тебя это более-менее соблюдается).
> abstract protected function setSalary();
Правильнее назвать getDefaultSalary() так как этот метод не меняет ставку, а возвращает ее значение по умолчанию. Сделать чтобы они возвращали нужное число, а не присваивали.
В случае с профессией, она не может поменяться, потому логично убрать свойство profession и оставить только абстрактный метод getProfession().
Константы LARGE_COL можно поместить в класс CompanyReport, так ка кони с ним связаны. Обычно пишут как CompanyReport::COL_LARGE, то есть тип знаечния идет в начале.
> preg_match('/([0-9]+)x([а-яё]+)([0-9])/iu',
Нет привязки к краям строки, также теоретически строка может не соответствовать регулярке и надо бы поставить if.
> $isDirector = ($i == ($totalPeople - 1)) ? true : false;
То же самое что $isDirector = ($i == ($totalPeople - 1)). == возвращает true или false.
> for ($i = 0; $i < $totalEmployee; $i++) {
> $departament->addEmployeeToDepartment($employee[$i]);
Тут лучше foreach использовать.
Так, в общем, неплохо.
Антикризисные меры
> А такие вещи, как количество инженеров/менеджеров можно оставлять в Департаменте?
Если эта функция достаточно универсальна и может использоваться где-то еще, то можно в Департаменте. Вместо 4 отдельных функций лучше сделать одну, принимающую название класса. А то что ты будешь делать, если надо добавить новые профессии?
Можно усовершенствовать функцию еще дальше и принимать анонимную функицю, которая получает по очереди каждого работника и определяет, учитывается ли он или нет. Это позволит делать подсчет по произвольному условию.
>>Если директора нет, будет ошибка обращения к несуществующей переменной
> Создал до цикла. Какое значение при создании будет правильней: NULL, false?
null, так как оно обычно обозначает отсутствие значения.
> Здесь можно использовать значение по умолчанию setSalary($salary = 500)? То есть, ставим зарплату по умолчанию, как указано в задании, а в случае чего, антикризисный комитет может поставить свое значение.. Или нужно пересмотреть подход?
Я думаю, лучше сделать отдельную функцию определения начальной зарплаты и отдельную для ее изменения.
> $countDepartment = $this->getCountDeparments();
> for ($i = 0; $i < $countDepartment; $i++) {
Тут лучше foreach использовать.
Увольнение у тебя реализовано на мой взгляд неправильно. Ты берешь список работников, меняешь его и записываешь его назад в Департамент. Но разве это правильно, когда любой может менять список работников? Правильнее будет использовать инкапсуляцию и скрыть список работников внутри Департамента так, что снаружи можно только вызывать методы найма и увольнения, но нельзя менять список напрямую. Это задача Департамента - поддерживать список работников.
А ты фактически кусок кода из Департамента вынул и перенес в другой класс. Логичнее если Антикризисный Комитет знаимается более высокоуровневыми вещами чем ручная правка списка сотрудников, а правкой списка занимается Департамент.
Или представь, например, что ты захочешь сделать счетчик уволенных их Департамента работников. В твоем нынешнем коде тебе придется искать все места где их увольняют, и туда вписывать еще увеличение счетчика. А в моем варианте код увольнения находится в Департаменте и добавить счетчик очень просто.
То же самое касается и назначения нового Директора - это логично сделать методом в Департаменте.
Кстати поиск работников соответствующих условию - тоже довольно универсальная вещь, чтобы реализовать ее в Департаменте.
> uasort($listOfEmployee, 'sortByRank');
Вместо глобальной функции тут лучше использовать метод класса или анонимную функцию:
- http://php.net/manual/ru/language.types.callable.php
- https://habrahabr.ru/post/259991/
> echo "Не задан директор";
> exit();
В ООП принято при ошибке выбрасывать исключения.
Калькулятор
> Перенес switch в функцию, так будет правильней?
> if ($char == '=') {
> $result = calculate($op, $numberText, $result);
> } else {
> $result = calculate($op, $numberText, $result);
> }
Не очень понятно, зачем if, если обе ветки одинаковы.
Считает вроде верно.
Навигатор
>>Попробуй написать решение с рекурсией
> Что-то слепил, немного не по предложенному алгоритму. Поэкспериментировал, вроде бы решает верно.
> static $allPath = array();
Вот это неправильно. Эта же переменная никуда не исчезает и при попытке проложить второй маршрут в ней останутся данные из первого. Получается побочный эффект. Очевидно тут нельзя ее использовать.
Функция не должна ничего сохранять в долгоживущую переменную. Она получает нужные ей данные через аргументы и возвращает через return.
Маска файла
>>Также, дам дополнительную задачку на рекурсию, чтобы лучше в ней разобраться
Некорректно работает для маски te*?? и имени tennis ( http://ideone.com/UuWPSV ). Значит, есть ошибки в алгоритме.
Я думаю, проблема в том, как ты обрабатываешь звездочку. Ты при наличии звездочки сначала проверяешь версию, что она не соответствует ни одному символу:
return doOneStep(mb_substr($mask, 1), $filename, $lMask);
А только потом, в другом месте, ниже, пробуешь убрать один символ из файла. Но это происходит в самом конце функции и если после звездочки идет знак вопроса, до туда просто не доходит выполнение.
Не надо разносить код обработки звездочки на 2 части. Надо вписать его внутри if ($lMask == '*').
Там можно использовать либо цикл либо рекурсию. Кстати, перебирать варианты можно в 2 направлениях:
- попытаться захватить зведочкой весь остаток имени, а если не сработает, убавлять символы по одному - это "жадный" подход, звездочка пытается съесть максимум символов
- наоборот, попытаться захватывать по 1 символу, увеличивая длину - это "нежадный" подход
То есть логика тут примерно такая:
- если в маске встретилась звездочка, она может соответствовать от 0 до N любых символов. Соответственно, делаем цикл и перебираем все варианты, пока какой-нибудь не сработает. Либо рекурсия (то же самое, но другим способом): вызываем сами себя 2 раза: со звездочкой и отрезанной буквой от имени и без звездочки и проверяем, совпал ли хоть один. Но мне кажется, с циклом будет нагляднее. Тут жадность звездочки определяется порядком вызова.
Навигатор
> Нормально ли здесь использовать global или нужно всё же передавать через параметры?
Не, это плохая идея так как создает побочные эффекты и затрудняет понимание работы функции.
> $labels[$point] = PHP_INT_MAX;
есть еще константа, обозначающая бесконечность - INF
> function doAlgorithmDijstra($labels, $visited)
Комментарии улучшают код, но тут стоило бы дописать еще тайп-хинты (array $labels).
> Поиск вершины с наименьшей меткой
Это можно было вынести в отдельную функцию ради читабельности.
> foreach ($labels as $label => $value) {
$label наверно правильнее было назвать как $pointName, а $value как $distance или $time или $label.
> $nextPoint = $paths[$workPoint];
Не $nextPoint, а $nextPoints (множ. число)
Сама реализация выглядит верно.
> В алгоритме сказано:
> ".. из ещё не посещённых вершин выбирается вершина u, имеющая минимальную метку", для этого я выполняю:
> вроде бы всё по алгоритму…
Ну ок, значит я не разобрал код правильно. Может потому, что он был не очень понятный. Сейчас намного лучше.
Числа прописью
Выглядит верно, хотя там перед скобкой лишний пробел затесался.
Вектор
> Убрал в функция createEmployee, padLeft, padRight - тайп-хинт
> //Для int и string, т.к. ideone считает их за объекты
Это потому что там PHP5, а не PHP7.
> Метод возвращающий имя компании
Лучше "Возвращает название компании"
Комментарии в общем хорошие. Но не менее важно давать такие имена переменным и методам, чтобы их назначение было понятно без комментария (у тебя это более-менее соблюдается).
> abstract protected function setSalary();
Правильнее назвать getDefaultSalary() так как этот метод не меняет ставку, а возвращает ее значение по умолчанию. Сделать чтобы они возвращали нужное число, а не присваивали.
В случае с профессией, она не может поменяться, потому логично убрать свойство profession и оставить только абстрактный метод getProfession().
Константы LARGE_COL можно поместить в класс CompanyReport, так ка кони с ним связаны. Обычно пишут как CompanyReport::COL_LARGE, то есть тип знаечния идет в начале.
> preg_match('/([0-9]+)x([а-яё]+)([0-9])/iu',
Нет привязки к краям строки, также теоретически строка может не соответствовать регулярке и надо бы поставить if.
> $isDirector = ($i == ($totalPeople - 1)) ? true : false;
То же самое что $isDirector = ($i == ($totalPeople - 1)). == возвращает true или false.
> for ($i = 0; $i < $totalEmployee; $i++) {
> $departament->addEmployeeToDepartment($employee[$i]);
Тут лучше foreach использовать.
Так, в общем, неплохо.
Антикризисные меры
> А такие вещи, как количество инженеров/менеджеров можно оставлять в Департаменте?
Если эта функция достаточно универсальна и может использоваться где-то еще, то можно в Департаменте. Вместо 4 отдельных функций лучше сделать одну, принимающую название класса. А то что ты будешь делать, если надо добавить новые профессии?
Можно усовершенствовать функцию еще дальше и принимать анонимную функицю, которая получает по очереди каждого работника и определяет, учитывается ли он или нет. Это позволит делать подсчет по произвольному условию.
>>Если директора нет, будет ошибка обращения к несуществующей переменной
> Создал до цикла. Какое значение при создании будет правильней: NULL, false?
null, так как оно обычно обозначает отсутствие значения.
> Здесь можно использовать значение по умолчанию setSalary($salary = 500)? То есть, ставим зарплату по умолчанию, как указано в задании, а в случае чего, антикризисный комитет может поставить свое значение.. Или нужно пересмотреть подход?
Я думаю, лучше сделать отдельную функцию определения начальной зарплаты и отдельную для ее изменения.
> $countDepartment = $this->getCountDeparments();
> for ($i = 0; $i < $countDepartment; $i++) {
Тут лучше foreach использовать.
Увольнение у тебя реализовано на мой взгляд неправильно. Ты берешь список работников, меняешь его и записываешь его назад в Департамент. Но разве это правильно, когда любой может менять список работников? Правильнее будет использовать инкапсуляцию и скрыть список работников внутри Департамента так, что снаружи можно только вызывать методы найма и увольнения, но нельзя менять список напрямую. Это задача Департамента - поддерживать список работников.
А ты фактически кусок кода из Департамента вынул и перенес в другой класс. Логичнее если Антикризисный Комитет знаимается более высокоуровневыми вещами чем ручная правка списка сотрудников, а правкой списка занимается Департамент.
Или представь, например, что ты захочешь сделать счетчик уволенных их Департамента работников. В твоем нынешнем коде тебе придется искать все места где их увольняют, и туда вписывать еще увеличение счетчика. А в моем варианте код увольнения находится в Департаменте и добавить счетчик очень просто.
То же самое касается и назначения нового Директора - это логично сделать методом в Департаменте.
Кстати поиск работников соответствующих условию - тоже довольно универсальная вещь, чтобы реализовать ее в Департаменте.
> uasort($listOfEmployee, 'sortByRank');
Вместо глобальной функции тут лучше использовать метод класса или анонимную функцию:
- http://php.net/manual/ru/language.types.callable.php
- https://habrahabr.ru/post/259991/
> echo "Не задан директор";
> exit();
В ООП принято при ошибке выбрасывать исключения.
ты бы написал подробности, может мы бы посоветовали что-то.
>>856249
Оценить популярность можно на сайте с вакансиями. Пара книг есть в ОП посте. Насчет заданий, не знаю, посмотри ОП пост, может что-то присмотришь.
> HTML знаю, в CSS смогу походу, делов там.
Ну ты посмотри наши задачи на HTML, может ты что-то не знаешь.
> Нужно ли знать wordpress или что-то вроде этого?
Зависит от компании
> Linux или винда? Что лучше, удобнее?
Кому-то нравится одно, кому-то другое.
>>856308
Скорее всего - никак.
>>856331
> (^ ?8|^\+ ?7)
^ можно вынести за скобки
> echo " ".phoneNumberCheck($correctNumbers[$i])." \n ";
Но функция phoneNumberCheck() ничего не возвращает, а ты пытаешься ее результат вклеить в строку.
Работает правильно.
ты бы написал подробности, может мы бы посоветовали что-то.
>>856249
Оценить популярность можно на сайте с вакансиями. Пара книг есть в ОП посте. Насчет заданий, не знаю, посмотри ОП пост, может что-то присмотришь.
> HTML знаю, в CSS смогу походу, делов там.
Ну ты посмотри наши задачи на HTML, может ты что-то не знаешь.
> Нужно ли знать wordpress или что-то вроде этого?
Зависит от компании
> Linux или винда? Что лучше, удобнее?
Кому-то нравится одно, кому-то другое.
>>856308
Скорее всего - никак.
>>856331
> (^ ?8|^\+ ?7)
^ можно вынести за скобки
> echo " ".phoneNumberCheck($correctNumbers[$i])." \n ";
Но функция phoneNumberCheck() ничего не возвращает, а ты пытаешься ее результат вклеить в строку.
Работает правильно.
> public function getSalary()
> {
> $salary;
А что делает команда $salary; ? В PHP объявлять переменные не надо. Они сами создаются при прсвоении значения.
У тебя конструктор класса-наследника проставляет зарплату по умолчанию, потребление кофе итд. Но ведь это не очень очевидно, что при наследовании надо написать это в конструкторе. Надо бы сделать код более очевидным. Например, сделать абстрактный метод getDefaultSalary() который обязан будет реализовать наследник.
> public function addEmployees($number, $class, $rang)
> public function addDirector($class, $rang)
На мой взгляд, тут лучше сделать по-другому. Создание работников - не задача Департамента. Его задача - поддерживать их список, принимать и увольнять. Есть ли какая-то причина, по которой Департамент должен сам создавать объекты Работников, а не принимать уже созданные? Мне кажется удобнее создавать их снаружи, так как мы в этом случае можем менять разные свойства работника перед приемом на работу.
В классе Company ты зря в конструктор прописал список работников. Ведь получился не универсальный класс Компании, а с жестко заложенным списком. Лучше сделать универсальный класс, а работников создавать снаружи.
Вывод таблиц тоже лучше бы убрать из класса Компании. Его задача наверно представлять компанию и хранить департаменты, а не выводить отчет. Хотя конечно тут программа не очень большая, и можно совместисть эти функции, но лучше наверно сделать вывод отчета отдельно от Компании.
> PHP Notice: Undefined variable: sumOfSalary in /home/kGVikj/prog.php on line 221
А вот это надо бы исправить.
>>856528
Это новые mysqli-функции молчат, а не устаревшие mysql-.
>>856495
Если разобрать, что делает код, то будет очевидно, почему пропадает первая строка.
> Насколько я понимаю, mysql_fetch_array при каждом вызове сдвигает указатель, поэтому такая шляпа и происходит. Как это пофиксить?
Ну ты в общем-то прав. Пофиксить - поменяв алгоритм работы.
>>856679
Не знаю, давно не был на фриланс-биржах. Можешь попробовать проверить.
>>856693
Потихоньку обретает. Тайп-хинты улучшили например в PHP7. Просто не все сразу делается.
> public function getSalary()
> {
> $salary;
А что делает команда $salary; ? В PHP объявлять переменные не надо. Они сами создаются при прсвоении значения.
У тебя конструктор класса-наследника проставляет зарплату по умолчанию, потребление кофе итд. Но ведь это не очень очевидно, что при наследовании надо написать это в конструкторе. Надо бы сделать код более очевидным. Например, сделать абстрактный метод getDefaultSalary() который обязан будет реализовать наследник.
> public function addEmployees($number, $class, $rang)
> public function addDirector($class, $rang)
На мой взгляд, тут лучше сделать по-другому. Создание работников - не задача Департамента. Его задача - поддерживать их список, принимать и увольнять. Есть ли какая-то причина, по которой Департамент должен сам создавать объекты Работников, а не принимать уже созданные? Мне кажется удобнее создавать их снаружи, так как мы в этом случае можем менять разные свойства работника перед приемом на работу.
В классе Company ты зря в конструктор прописал список работников. Ведь получился не универсальный класс Компании, а с жестко заложенным списком. Лучше сделать универсальный класс, а работников создавать снаружи.
Вывод таблиц тоже лучше бы убрать из класса Компании. Его задача наверно представлять компанию и хранить департаменты, а не выводить отчет. Хотя конечно тут программа не очень большая, и можно совместисть эти функции, но лучше наверно сделать вывод отчета отдельно от Компании.
> PHP Notice: Undefined variable: sumOfSalary in /home/kGVikj/prog.php on line 221
А вот это надо бы исправить.
>>856528
Это новые mysqli-функции молчат, а не устаревшие mysql-.
>>856495
Если разобрать, что делает код, то будет очевидно, почему пропадает первая строка.
> Насколько я понимаю, mysql_fetch_array при каждом вызове сдвигает указатель, поэтому такая шляпа и происходит. Как это пофиксить?
Ну ты в общем-то прав. Пофиксить - поменяв алгоритм работы.
>>856679
Не знаю, давно не был на фриланс-биржах. Можешь попробовать проверить.
>>856693
Потихоньку обретает. Тайп-хинты улучшили например в PHP7. Просто не все сразу делается.
У тебя ответ правильный.
>>856943
Ответ правильный, но называть переменные по-русски не стоит.
>>856946
Это не лишнее, это полезная возможность.
>>856969
> $mobileNumber = str_replace(" ","",$mobileNumber);
> $mobileNumber = str_replace("-","",$mobileNumber);
Эти 4 строки можно заменить одной preg_replace. Что и сделано во второй версии функции. Только я бы не заводил переменные $pattern и $replacement, а сразу бы подставил строки.
> (^ ?8|^\+ ?7)
^ можно вынести за скобку
> PHPstorm говорит что код не будет работать и ругается именно на строку где я считаю сколько осталось денег отдать банку. Уж не понимаю почему так.
Ты бы ссылку еще дал на тот код, а то я подсказать не смогу ничего.
>>856999
Сложновато как-то. Это ведь решается одной регуляркой, они для того и придуманы, чтобы кода меньше писать.
> return NULL; // А так можно?
Логичнее возвращать исходную строку. А то странно, функция удаляет все из строки если там нет латинских букв. Легко из-за этого ошибиться.
И как я понимаю, если написать английскими буквами и через пробелы: ДY PAK то функция пропустит слово: http://ideone.com/SCdl9U
У тебя ответ правильный.
>>856943
Ответ правильный, но называть переменные по-русски не стоит.
>>856946
Это не лишнее, это полезная возможность.
>>856969
> $mobileNumber = str_replace(" ","",$mobileNumber);
> $mobileNumber = str_replace("-","",$mobileNumber);
Эти 4 строки можно заменить одной preg_replace. Что и сделано во второй версии функции. Только я бы не заводил переменные $pattern и $replacement, а сразу бы подставил строки.
> (^ ?8|^\+ ?7)
^ можно вынести за скобку
> PHPstorm говорит что код не будет работать и ругается именно на строку где я считаю сколько осталось денег отдать банку. Уж не понимаю почему так.
Ты бы ссылку еще дал на тот код, а то я подсказать не смогу ничего.
>>856999
Сложновато как-то. Это ведь решается одной регуляркой, они для того и придуманы, чтобы кода меньше писать.
> return NULL; // А так можно?
Логичнее возвращать исходную строку. А то странно, функция удаляет все из строки если там нет латинских букв. Легко из-за этого ошибиться.
И как я понимаю, если написать английскими буквами и через пробелы: ДY PAK то функция пропустит слово: http://ideone.com/SCdl9U
> У транзакта слишком неявные профиты.
Ты просто про них не знаешь. Например, меньше вероятность получить мусор или несогласованные данные в БД.
>>857073
Значит надо посмотреть получше.
>>857197
В учебнике в ОП посте есть глава про ООП, а также в книгах которые упомянуты в ОП посте, ООП изучается подробно.
>>857247
Лучше получать путь через __DIR__, а то менять потом замучаешься.
>>857363
> function City(powerStations, powerPanels, powerLines, houses) {
Удобнее тут сначала создать пустой город, а потом добавлять элементы сети. Плюс, у тебя класс так написан, что добавить новые виды элементов сети нельзя. А надо, чтобы было можно. Ну например, завтра появится какая-нибудь ТЭЦ которая вырабатывает электричество и тепло сразу. Или аккумулирующая станция, запасающая энергию днем и отдающая ночью.
Лучше сделать универсальный метод city.addNetworkElement(element).
Насчет функций. Там много похожего кода. Лучше сделать одну функцию, считающую и возвращающую все данные (баланс, прибыль/расходы, количество произведенного/потребленного), и вызываеть ее из функций вроде getFinanceResult ().
> City.prototype.getFinanceResult = function(overflowPower) {
Неудобно как-то. Почему нельзя без передачи overflowPower сразу получить результат?
> Util.convertKwToMw
Я бы советовал использовать внутри везде стандартные единицы, а преобразоывать только если на выходе, хотя лучше вообще не преоразовывать. Пусть другой код этим занимается.
> House.FLAT_TAKE_DAY_POWER = "4KW";
Проще наверно в ваттах или киловаттах все считать...
> PowerPanel.TYPE_ONE = "typeOne";
> PowerPanel.TYPE_TWO = "typeTwo";
лучше наверно просто мощность числом передать.
Элементы сети (электростанции, дома) имеют кое-что общее:
- их можно присоединить к сети
- они потребляют или отдают энергию в сеть
Раз так, логично тут использовать наследование и сделать общие методы, например чтобы узнать их вклад в баланс энергии. Тогда мы сможем в Городе не разделять их по типам, а работать с любым элементом сети одинаково.
Ну к примеру для подсчета баланса достаточно просто просуммировать вклад каждого элемента независимо от типа.
> Правильно ли я поступил, что не делил методы на дневные и ночные, а в борьбе с копипастой соединил их, разделив логику кода через аргумент timesOfDay?
Можно так сделать, можно сделать 2 метода.
> И нужно ли было решать отдельно для разных времен суток.
По идее хорошо бы иметь возможность получить дневной/ночной балансы отдельно.
> У транзакта слишком неявные профиты.
Ты просто про них не знаешь. Например, меньше вероятность получить мусор или несогласованные данные в БД.
>>857073
Значит надо посмотреть получше.
>>857197
В учебнике в ОП посте есть глава про ООП, а также в книгах которые упомянуты в ОП посте, ООП изучается подробно.
>>857247
Лучше получать путь через __DIR__, а то менять потом замучаешься.
>>857363
> function City(powerStations, powerPanels, powerLines, houses) {
Удобнее тут сначала создать пустой город, а потом добавлять элементы сети. Плюс, у тебя класс так написан, что добавить новые виды элементов сети нельзя. А надо, чтобы было можно. Ну например, завтра появится какая-нибудь ТЭЦ которая вырабатывает электричество и тепло сразу. Или аккумулирующая станция, запасающая энергию днем и отдающая ночью.
Лучше сделать универсальный метод city.addNetworkElement(element).
Насчет функций. Там много похожего кода. Лучше сделать одну функцию, считающую и возвращающую все данные (баланс, прибыль/расходы, количество произведенного/потребленного), и вызываеть ее из функций вроде getFinanceResult ().
> City.prototype.getFinanceResult = function(overflowPower) {
Неудобно как-то. Почему нельзя без передачи overflowPower сразу получить результат?
> Util.convertKwToMw
Я бы советовал использовать внутри везде стандартные единицы, а преобразоывать только если на выходе, хотя лучше вообще не преоразовывать. Пусть другой код этим занимается.
> House.FLAT_TAKE_DAY_POWER = "4KW";
Проще наверно в ваттах или киловаттах все считать...
> PowerPanel.TYPE_ONE = "typeOne";
> PowerPanel.TYPE_TWO = "typeTwo";
лучше наверно просто мощность числом передать.
Элементы сети (электростанции, дома) имеют кое-что общее:
- их можно присоединить к сети
- они потребляют или отдают энергию в сеть
Раз так, логично тут использовать наследование и сделать общие методы, например чтобы узнать их вклад в баланс энергии. Тогда мы сможем в Городе не разделять их по типам, а работать с любым элементом сети одинаково.
Ну к примеру для подсчета баланса достаточно просто просуммировать вклад каждого элемента независимо от типа.
> Правильно ли я поступил, что не делил методы на дневные и ночные, а в борьбе с копипастой соединил их, разделив логику кода через аргумент timesOfDay?
Можно так сделать, можно сделать 2 метода.
> И нужно ли было решать отдельно для разных времен суток.
По идее хорошо бы иметь возможность получить дневной/ночной балансы отдельно.
поиск мыла
> ([a-z0-9\-])+\.)+([a-zа-я0-9]
почему-то в начале доменного имени можно использовать только латиницу, а в конце - еще и кириллицу. А так, работает верно. Я бы только еще \b добавил для надежности. А то вот такое получается: https://ideone.com/6Vs5HX
> Оп сделай пожалуйста задачи на двумерные массивы!
Подумаем, вообще многомерные массивы усложняют понимание кода и с ними важно не переусердствовать.
> Напиши скрипт, проверяющий текст на наличие злостных ошибок:
> В общем как всегда 2 варианта.
> str_replace https://ideone.com/IZHbzC
> $regexpA='/(\s\sа\s)|(([а-я0-9]\sа\s))/u';
> $regexpNO='/(\s\sно\s)|(([а-я0-9]\sно\s))/u';
Они очень похожи, можно объединить. Вместо \s\s не лучше написать "1 или более раз \s" ? Если после "но" стоит запятая, \s не сработает, лучше использовать \b.
> $regexpSpace='/(,[^\s])|(;[^\s])|(![^\s])|([?][^\s])|([.]{2}[^\s])|([:][^\s])/';
Это можно упростить, используя для знаков препинания символьный класс [....]
> '/(жы)|(шы)/ui';
И тут можно укоротить регулярку за счет символьного класса.
> '/(координально)|(сдесь)|(зделал)|(зделаю)|(зделан)/u';
Скобки не нужны.
> (зделал)|(зделаю)|(зделан)
Это можно сгруппировать и укоротить.
str_replace что-то уж очень много. Лучше preg_replace.
Разбивать на слова не обязательно - если делать правильно, можно заменять сразу в тексте.
> а тут preg_replace https://ideone.com/BcQcvB
Что-то длинно получилось. Там 4 регулярки или около того достаточно, по одной на правило. Упрощай.
>>857447
ну хорошо.
>>857458
> [a-zA-z]
Должно быть A-Z иначе туда попадет все, что идет между этми буквами в Юникоде, а там еще символы какие-то: http://unicode-table.com/ru/
Я думаю, проверять на опечатки до разбиения на слова нет особого смысла.
Твой код считает английские буквы опечатками. Но что если английское слово содержит 1 русскую букву? Это она будет опечаткой.
> array_push($fixedWords, $someWord);
Можно писать $fixedWords[] = $someWord;
>>857492
> $regexp='/([a-zA-z][а-яА-Я])|([а-яА-Я][a-zA-z])/u';
Это не используется.
Код переусложнен. Можно одним preg_replace заменить все латинские буквы в слове без цикла.
поиск мыла
> ([a-z0-9\-])+\.)+([a-zа-я0-9]
почему-то в начале доменного имени можно использовать только латиницу, а в конце - еще и кириллицу. А так, работает верно. Я бы только еще \b добавил для надежности. А то вот такое получается: https://ideone.com/6Vs5HX
> Оп сделай пожалуйста задачи на двумерные массивы!
Подумаем, вообще многомерные массивы усложняют понимание кода и с ними важно не переусердствовать.
> Напиши скрипт, проверяющий текст на наличие злостных ошибок:
> В общем как всегда 2 варианта.
> str_replace https://ideone.com/IZHbzC
> $regexpA='/(\s\sа\s)|(([а-я0-9]\sа\s))/u';
> $regexpNO='/(\s\sно\s)|(([а-я0-9]\sно\s))/u';
Они очень похожи, можно объединить. Вместо \s\s не лучше написать "1 или более раз \s" ? Если после "но" стоит запятая, \s не сработает, лучше использовать \b.
> $regexpSpace='/(,[^\s])|(;[^\s])|(![^\s])|([?][^\s])|([.]{2}[^\s])|([:][^\s])/';
Это можно упростить, используя для знаков препинания символьный класс [....]
> '/(жы)|(шы)/ui';
И тут можно укоротить регулярку за счет символьного класса.
> '/(координально)|(сдесь)|(зделал)|(зделаю)|(зделан)/u';
Скобки не нужны.
> (зделал)|(зделаю)|(зделан)
Это можно сгруппировать и укоротить.
str_replace что-то уж очень много. Лучше preg_replace.
Разбивать на слова не обязательно - если делать правильно, можно заменять сразу в тексте.
> а тут preg_replace https://ideone.com/BcQcvB
Что-то длинно получилось. Там 4 регулярки или около того достаточно, по одной на правило. Упрощай.
>>857447
ну хорошо.
>>857458
> [a-zA-z]
Должно быть A-Z иначе туда попадет все, что идет между этми буквами в Юникоде, а там еще символы какие-то: http://unicode-table.com/ru/
Я думаю, проверять на опечатки до разбиения на слова нет особого смысла.
Твой код считает английские буквы опечатками. Но что если английское слово содержит 1 русскую букву? Это она будет опечаткой.
> array_push($fixedWords, $someWord);
Можно писать $fixedWords[] = $someWord;
>>857492
> $regexp='/([a-zA-z][а-яА-Я])|([а-яА-Я][a-zA-z])/u';
Это не используется.
Код переусложнен. Можно одним preg_replace заменить все латинские буквы в слове без цикла.
Молодец, правильно.
>>857584
Я эту задачу так помню.
>>857815
Вложенные массивы плохо, но в больших фреймворках с конфигами всегда так.
>>857857
Реши сначала задачу про студентов и файлообменник. Вряд ли успеешь.
>>858379
> return mb_strtoupper(mb_substr($text, 0, 1, 'UTF-8'), 'UTF-8')
Кодировку писать не надо если она задана в mb_internal_encoding
Эта строка слишком длинная, надо разбить ее переносами на несколько строк.
> $regexpSpace="/(\s){2,100}/ui";
Скобки лишние
> $someoffer=preg_replace($regexpSpace, '' ,$offer);
Странно что ты удаляешь лишние пробелы, а не заменяешь на 1 пробел.
> foreach (($offers) as $offer) {
Скобки лишние
> mb_convert_case($text, MB_CASE_LOWER, 'UTF-8')
mb_strtolower
> mb_substr(mb_convert_case($text, MB_CASE_LOWER, 'UTF-8'), 1, mb_strlen($text)
mb_strlen можно не указывать (и ты забыл -1).
> $fixedtext=preg_replace("/([[:punct:]]+)\s/", '$1 ', $fixedtext);
> $fixedtext=preg_replace("/\s([[:punct:]]+)/", '$1 ', $fixedtext);
Это можно объединить.
Также, у тебя многоточие разбивается пробелами. Попробуй исправить.
>>858381
> Ведь если просто поставить кнопку, то в пхп-скрипт улетят все данные из инпутов и страница перезагрузится. А мне хочется, чтобы не перезагружалась.
тебе рано браться за аякс, тебе надо изучить обработку событий в DOM. https://learn.javascript.ru/events-and-interfaces
Молодец, правильно.
>>857584
Я эту задачу так помню.
>>857815
Вложенные массивы плохо, но в больших фреймворках с конфигами всегда так.
>>857857
Реши сначала задачу про студентов и файлообменник. Вряд ли успеешь.
>>858379
> return mb_strtoupper(mb_substr($text, 0, 1, 'UTF-8'), 'UTF-8')
Кодировку писать не надо если она задана в mb_internal_encoding
Эта строка слишком длинная, надо разбить ее переносами на несколько строк.
> $regexpSpace="/(\s){2,100}/ui";
Скобки лишние
> $someoffer=preg_replace($regexpSpace, '' ,$offer);
Странно что ты удаляешь лишние пробелы, а не заменяешь на 1 пробел.
> foreach (($offers) as $offer) {
Скобки лишние
> mb_convert_case($text, MB_CASE_LOWER, 'UTF-8')
mb_strtolower
> mb_substr(mb_convert_case($text, MB_CASE_LOWER, 'UTF-8'), 1, mb_strlen($text)
mb_strlen можно не указывать (и ты забыл -1).
> $fixedtext=preg_replace("/([[:punct:]]+)\s/", '$1 ', $fixedtext);
> $fixedtext=preg_replace("/\s([[:punct:]]+)/", '$1 ', $fixedtext);
Это можно объединить.
Также, у тебя многоточие разбивается пробелами. Попробуй исправить.
>>858381
> Ведь если просто поставить кнопку, то в пхп-скрипт улетят все данные из инпутов и страница перезагрузится. А мне хочется, чтобы не перезагружалась.
тебе рано браться за аякс, тебе надо изучить обработку событий в DOM. https://learn.javascript.ru/events-and-interfaces
В софтобанке должно быть около 61280.
> $strawberryBank = countSum(1.02, 0, 39999, 5000) + 7777;
7777 прибавляется к долгу в начале, а не в конце
> if ($debt > $payment) {
> } else {
Тут код почти одинаковый в обоих случаях. Нельзя ли объединить?
>>858419
> elseif ($anonSum == $compSum ) {
тут можно было написать просто else
> echo "Игра окончена\n";
> exit ();
тут exit не нужен так как это и так конец программы
В общем, решено верно.
>>858612
> Палиндром http://ideone.com/Wd5fBF
> вырежем пробельчики
Это делается одним str_replace.
> -++$i,
Так писать не стоит, так как трудно понять последовательность действий. $i++ лучше вынести на отдельную строку.
> Айпад в кредит http://ideone.com/E90Mea
> if ($creditBalance <= $monthlyPayment) {
> $monthlyPayment = $creditBalance;
Тут можно заменить if на min/max
Решено верно.
В софтобанке должно быть около 61280.
> $strawberryBank = countSum(1.02, 0, 39999, 5000) + 7777;
7777 прибавляется к долгу в начале, а не в конце
> if ($debt > $payment) {
> } else {
Тут код почти одинаковый в обоих случаях. Нельзя ли объединить?
>>858419
> elseif ($anonSum == $compSum ) {
тут можно было написать просто else
> echo "Игра окончена\n";
> exit ();
тут exit не нужен так как это и так конец программы
В общем, решено верно.
>>858612
> Палиндром http://ideone.com/Wd5fBF
> вырежем пробельчики
Это делается одним str_replace.
> -++$i,
Так писать не стоит, так как трудно понять последовательность действий. $i++ лучше вынести на отдельную строку.
> Айпад в кредит http://ideone.com/E90Mea
> if ($creditBalance <= $monthlyPayment) {
> $monthlyPayment = $creditBalance;
Тут можно заменить if на min/max
Решено верно.
У тебя не очень очевидно. Когда за раз просматриваешь 10 задач, над каждой ломать голову и вспоминать порядок операций не хочется.
>>858688
Позволяют организовать большой и сложный код и не запутаться в нем.
>>858789
> Внезапно выяснилось что хром сам зменяет все двойные пробелы на одинарные.
Скорее всего ты выводишь текст не как текст, а как HTML, а в этом языке любое число пробелов и переводов строк воспринимается как 1 пробел.
>>858793
Те же замечания, что и к предыдущей версии выше.
>>858868
Не очень понял вопрос, но думаю, что можно. Ты бы привел пример кода.
Подставлять данные в запрос надо через плейсхолдеры и подготовленные запросы, а не напрямую.
>>858876
В верном, и много полезных ссылок в ОП посте.
>>858885
> return mb_strtoupper(mb_substr($text, 0, 1, 'UTF-8'), 'UTF-8') .
Слишком длинно, многое можно выкинуть.
> [.]|[!]|[?]|[;]
Тут лучше использовать просто квадратные скобки без вертикальной черты
> foreach ($sentences as $sentence){
> echo $sentence;
echo лучше ставить снаружи функции.
> $yodaSay=preg_replace("/([[:punct:]]+)\s/", '$1 ', $yodaSay);
> $yodaSay=preg_replace("/\s([[:punct:]]+)/", '$1 ', $yodaSay);
Это можно сделать одной строкой
>>858909
Разницу можно нагуглить по словам "sql dialects" или "различия sql диалектов"
> с MySQL и mongodb?
есть, это абсолютно разные СУБД, mongo не поддерживает язык SQL
>>858978
Косые кавычки нужны если название поля содержит пробелы или спецсимволы или если совпадает с зарезервированным ключевым словом вроде date.
>>859012
Верно, и в итоге гораздо больше процентов набегает.
>>859419
Если подходить с точки зрения нормализации и "идеального" проектирования, то у тебя нет такой вещи как "пользователь в комнате". У тебя есть список пользователей, комнат и список заходов/выходов пользователей в комнаты. Но работать будет очень неудобно, да и чат не банк чтобы требовать такой уровень, потому проще сделать просто связь между пользователями и комнатами.
Лучше не делать связь "много пользователей - одна комната", а сделать "много пользователей - много комнат", то есть пользователь может сидеть в нескольких комнатах.
> Сам чат само собой аяксовый и будет работать без перезагрузки, но любой пользователь в любой момент может перезагрузить страницу, и каждый раз будут дополнительные запросы к базе данных ради проверки принадлежность ид пользователя, к этой комнате, не слишком ли это будет напрягать базу сам сайт?
думаю нет, если правильно расставить индексы.
У тебя не очень очевидно. Когда за раз просматриваешь 10 задач, над каждой ломать голову и вспоминать порядок операций не хочется.
>>858688
Позволяют организовать большой и сложный код и не запутаться в нем.
>>858789
> Внезапно выяснилось что хром сам зменяет все двойные пробелы на одинарные.
Скорее всего ты выводишь текст не как текст, а как HTML, а в этом языке любое число пробелов и переводов строк воспринимается как 1 пробел.
>>858793
Те же замечания, что и к предыдущей версии выше.
>>858868
Не очень понял вопрос, но думаю, что можно. Ты бы привел пример кода.
Подставлять данные в запрос надо через плейсхолдеры и подготовленные запросы, а не напрямую.
>>858876
В верном, и много полезных ссылок в ОП посте.
>>858885
> return mb_strtoupper(mb_substr($text, 0, 1, 'UTF-8'), 'UTF-8') .
Слишком длинно, многое можно выкинуть.
> [.]|[!]|[?]|[;]
Тут лучше использовать просто квадратные скобки без вертикальной черты
> foreach ($sentences as $sentence){
> echo $sentence;
echo лучше ставить снаружи функции.
> $yodaSay=preg_replace("/([[:punct:]]+)\s/", '$1 ', $yodaSay);
> $yodaSay=preg_replace("/\s([[:punct:]]+)/", '$1 ', $yodaSay);
Это можно сделать одной строкой
>>858909
Разницу можно нагуглить по словам "sql dialects" или "различия sql диалектов"
> с MySQL и mongodb?
есть, это абсолютно разные СУБД, mongo не поддерживает язык SQL
>>858978
Косые кавычки нужны если название поля содержит пробелы или спецсимволы или если совпадает с зарезервированным ключевым словом вроде date.
>>859012
Верно, и в итоге гораздо больше процентов набегает.
>>859419
Если подходить с точки зрения нормализации и "идеального" проектирования, то у тебя нет такой вещи как "пользователь в комнате". У тебя есть список пользователей, комнат и список заходов/выходов пользователей в комнаты. Но работать будет очень неудобно, да и чат не банк чтобы требовать такой уровень, потому проще сделать просто связь между пользователями и комнатами.
Лучше не делать связь "много пользователей - одна комната", а сделать "много пользователей - много комнат", то есть пользователь может сидеть в нескольких комнатах.
> Сам чат само собой аяксовый и будет работать без перезагрузки, но любой пользователь в любой момент может перезагрузить страницу, и каждый раз будут дополнительные запросы к базе данных ради проверки принадлежность ид пользователя, к этой комнате, не слишком ли это будет напрягать базу сам сайт?
думаю нет, если правильно расставить индексы.
Открытие! Можно не писать ничего,а просто нажать звездочку в японской раскладке - вставится японская звездочка.
>>860354
> if ($number == 1) {
А если число == 21 ? Выведет "рублей"? 21 рубль должно быть.
> }elseif ($number == 0 || $number >5 and $number<21){
> return "рублей";
> }else {
> return "рублей";
По моему elseif тут не особо нужен
> $splitter = preg_split('//u', $number, -1, PREG_SPLIT_NO_EMPTY);
С числами надо работать математическими методами, деление, умножение, а не как со строками.
> function smallNumberToText($number, $isFemale)
Функция переусложнена и много кода дублируется. Надо упрощать до 5-6 условий.
> switch (($separatedNumbers[$i])) {
> case 1;
> case 2;
Разве это не задача функции inclineWord выбирать форму слова?
> Исходное число 39917850
> На вашем счету три квадриллиона девять триллионов девять миллиардов один миллион семь тысячь восемьсот пятьдесят рублей
Неправильно ведь. Там всего 39 миллионов с копейками.
Если ты хочешь считать квадриллионы, надо кое-что учесть. В PHP есть 2 типа чисел:
- int, на 32-битных машинах - целые числа от -2 млрд до 2 млрд (квадриллион не влезет) http://php.net/manual/ru/language.types.integer.php
- float, квадиллион в него влезет, но он хранит около 14 цифр http://php.net/manual/ru/language.types.float.php
Чтобы хранить огромные числа без потерь, их надо представлять как строку, а не число.
>>860356
Да. Зачем ОПу решать задачи для начинающих?
>>861065
Чтобы увеличивать $x каждый год, надо написать что-то вроде
$x = $x + 100; // увеличить $x на 100
Возьми это за основу, а также перечитай урок. Если не придумаешь, как решить - запости код и снова попроси совет.
> $x + 1000
Так он прибавит 1000, но никуда не сохранит результат и $x останется неизменным.
Открытие! Можно не писать ничего,а просто нажать звездочку в японской раскладке - вставится японская звездочка.
>>860354
> if ($number == 1) {
А если число == 21 ? Выведет "рублей"? 21 рубль должно быть.
> }elseif ($number == 0 || $number >5 and $number<21){
> return "рублей";
> }else {
> return "рублей";
По моему elseif тут не особо нужен
> $splitter = preg_split('//u', $number, -1, PREG_SPLIT_NO_EMPTY);
С числами надо работать математическими методами, деление, умножение, а не как со строками.
> function smallNumberToText($number, $isFemale)
Функция переусложнена и много кода дублируется. Надо упрощать до 5-6 условий.
> switch (($separatedNumbers[$i])) {
> case 1;
> case 2;
Разве это не задача функции inclineWord выбирать форму слова?
> Исходное число 39917850
> На вашем счету три квадриллиона девять триллионов девять миллиардов один миллион семь тысячь восемьсот пятьдесят рублей
Неправильно ведь. Там всего 39 миллионов с копейками.
Если ты хочешь считать квадриллионы, надо кое-что учесть. В PHP есть 2 типа чисел:
- int, на 32-битных машинах - целые числа от -2 млрд до 2 млрд (квадриллион не влезет) http://php.net/manual/ru/language.types.integer.php
- float, квадиллион в него влезет, но он хранит около 14 цифр http://php.net/manual/ru/language.types.float.php
Чтобы хранить огромные числа без потерь, их надо представлять как строку, а не число.
>>860356
Да. Зачем ОПу решать задачи для начинающих?
>>861065
Чтобы увеличивать $x каждый год, надо написать что-то вроде
$x = $x + 100; // увеличить $x на 100
Возьми это за основу, а также перечитай урок. Если не придумаешь, как решить - запости код и снова попроси совет.
> $x + 1000
Так он прибавит 1000, но никуда не сохранит результат и $x останется неизменным.
Не пишите больше в этот тред. Тут будут только ответы на не проверенные еще заадчи.
Если вас пропустили - напомните о себе в новом треде.
>Что на картинке?
Гитхаб, календарь показывающий когда ты размещал код.
Надписи "Я""Парень про которого она сказала не беспокоится."
Спасибо добрый анон.
В общем, решено верно, разве что русские буквы в английских словах не подсвечивает.
>>861418
> $op=$char;
> $number = 0;
Это повторяется много раз. Надо бы избавиться от повторов.
> Алсо не могу понять почему строка 37 не выводит echo
Потому что в группе if/elseif может выполниться только один блок, и до условия elseif ($char=="=") { просто не доходит. Срабатывает одно из более ранних условий вроде elseif ($op == "+")
>>861435
Та же проблема, строки
> $op = $char;
> $number = 0;
скопипащены много раз.
Код в case '=' не работает, так как срабатывает одно из условий выше. Поставь там echo с выводом знаечний перемнных и может увидишь.
>>861592
Потому что в блоке switch срабатывает одно из более ранних условий и до знака равно не доходит.
>>861593
> if ($op == "+") {
> $result = $result + $number;
Вот эти вот условия по 2 раза повторяются, плохо.
В остальном верно.
>>861735
> $op=$char;
> $number = 0;
Это по прежнему повторяется много раз.
В общем, решено верно, разве что русские буквы в английских словах не подсвечивает.
>>861418
> $op=$char;
> $number = 0;
Это повторяется много раз. Надо бы избавиться от повторов.
> Алсо не могу понять почему строка 37 не выводит echo
Потому что в группе if/elseif может выполниться только один блок, и до условия elseif ($char=="=") { просто не доходит. Срабатывает одно из более ранних условий вроде elseif ($op == "+")
>>861435
Та же проблема, строки
> $op = $char;
> $number = 0;
скопипащены много раз.
Код в case '=' не работает, так как срабатывает одно из условий выше. Поставь там echo с выводом знаечний перемнных и может увидишь.
>>861592
Потому что в блоке switch срабатывает одно из более ранних условий и до знака равно не доходит.
>>861593
> if ($op == "+") {
> $result = $result + $number;
Вот эти вот условия по 2 раза повторяются, плохо.
В остальном верно.
>>861735
> $op=$char;
> $number = 0;
Это по прежнему повторяется много раз.
не ленись прокрутить до 4-5 страницы и найдешь тред.
>>861758
Вроде никаких особых различий нет. От версии ОС может зависеть список поддерживаемых аудио/видеокодеков, но в ИЕ8 их (как и HTML5) еще нет. Если выбирать что-то одно, я бы ставил под Win7 как более распространенную.
>>861768
Вообще, тут переменная $oversum лишняя и ее можно убрать. Также, хорошо бы избавиться от if/else где почти 2 одинаковых копии кода.
>>861996
Мне тоже в голову не приходит, но надежнее всеже проверять и использовать одно и то же выражение.
>>862718
нет
>>862733
Никак
>>862736
Не знаю, может и норимально. Но вряд ли удобно работать с таким кодом, где неизвестна структура массива.
не ленись прокрутить до 4-5 страницы и найдешь тред.
>>861758
Вроде никаких особых различий нет. От версии ОС может зависеть список поддерживаемых аудио/видеокодеков, но в ИЕ8 их (как и HTML5) еще нет. Если выбирать что-то одно, я бы ставил под Win7 как более распространенную.
>>861768
Вообще, тут переменная $oversum лишняя и ее можно убрать. Также, хорошо бы избавиться от if/else где почти 2 одинаковых копии кода.
>>861996
Мне тоже в голову не приходит, но надежнее всеже проверять и использовать одно и то же выражение.
>>862718
нет
>>862733
Никак
>>862736
Не знаю, может и норимально. Но вряд ли удобно работать с таким кодом, где неизвестна структура массива.
http://dkab.github.io/jasmine-tests/?spec=4
Как передать аргументы во внутреннюю функцию?
Первое решение это получать массив аргументов внешней ф-ии. Можно передавать его аргументом, а можно и нет, все равно он будет доступен. Но внутренняя ф-ия должна уметь с ним работать. Например ф-ия add из примера не работает с массивом:
function add(a, b) {
return a + b;
}
Второй вариант, это попробовать сформировать строку, а потом превратить ее в функцию.
> Выставлено, так сказать, значение по умолчанию, не совсем понимаю почему это странно.
У тебя, если выбран женский пол, то получится HTML код
<input type="radio" name ='sex' value="<?=Student::GENDER_MALE?>" required checked='checked'>
<input type="radio" name ='sex' value="<?=Student::GENDER_FEMALE?>" required checked='checked'>
То есть в группе радиокнопок обе будут отмеченными. Это неправильно.
> Я так понимаю, что радикнопки изначально предполагают выбор или или, так что к блоку.
Лучше не гадать, а проверять официальную документацию или стандарт:
https://www.w3.org/TR/html5/forms.html#the-required-attribute
> For radio buttons, the required attribute is satisfied if any of the radio buttons in the group is selected.
> To avoid confusion as to whether a radio button group is required or not, authors are encouraged to specify the attribute on all the radio buttons in a group.
То есть да, достаточно указать required хотя бы на одной радиокнопке и она примняется к блоку в целом. стоит всегда проверять такие спорные вещи по стандарту, а не надеяться на "авось работает".
> Гугл говорит что тип YEAR корректно работает с промежутком 1901-2155. Как это лучше обойти?
Либо использовать другой тип (вроде MEDIUMINT), либо запретить 1900 год в валидации. Странно для типа с названием YEAR иметь такие дурацкие ограничения. 1900-й был не так и давно.
>>863362
Нет. attribute_name слишком длинный для первичного ключа, лучше attribute_id. Вообще, там EAV реализована неправильно, изучи для начала этот паттерн.
>>863413
Читать тяжеловато, надо сделать промежутки между колонками.
> count($lines)+10;
Откуда взялось 10? Что еще за магическое число? Нужно определять максимальную длину строки, а не подбирать наугад.
> if ($symbols[$i]==' '){
> echo " ";
не очень понятно, зачем тут if.
> $symbol = preg_split('//u', $lines[$i], -1, PREG_SPLIT_NO_EMPTY);
переменная $symbol не используется.Ошибка в этой строке из-за того, что ты обращаешься к несуществующим элементам массива $lines.
> Ошибка при обращении к несуществующему элементу массива проявляется. Может кто подскажет как её обойти?
Не обращаться к несуществующим элементам.
> Выставлено, так сказать, значение по умолчанию, не совсем понимаю почему это странно.
У тебя, если выбран женский пол, то получится HTML код
<input type="radio" name ='sex' value="<?=Student::GENDER_MALE?>" required checked='checked'>
<input type="radio" name ='sex' value="<?=Student::GENDER_FEMALE?>" required checked='checked'>
То есть в группе радиокнопок обе будут отмеченными. Это неправильно.
> Я так понимаю, что радикнопки изначально предполагают выбор или или, так что к блоку.
Лучше не гадать, а проверять официальную документацию или стандарт:
https://www.w3.org/TR/html5/forms.html#the-required-attribute
> For radio buttons, the required attribute is satisfied if any of the radio buttons in the group is selected.
> To avoid confusion as to whether a radio button group is required or not, authors are encouraged to specify the attribute on all the radio buttons in a group.
То есть да, достаточно указать required хотя бы на одной радиокнопке и она примняется к блоку в целом. стоит всегда проверять такие спорные вещи по стандарту, а не надеяться на "авось работает".
> Гугл говорит что тип YEAR корректно работает с промежутком 1901-2155. Как это лучше обойти?
Либо использовать другой тип (вроде MEDIUMINT), либо запретить 1900 год в валидации. Странно для типа с названием YEAR иметь такие дурацкие ограничения. 1900-й был не так и давно.
>>863362
Нет. attribute_name слишком длинный для первичного ключа, лучше attribute_id. Вообще, там EAV реализована неправильно, изучи для начала этот паттерн.
>>863413
Читать тяжеловато, надо сделать промежутки между колонками.
> count($lines)+10;
Откуда взялось 10? Что еще за магическое число? Нужно определять максимальную длину строки, а не подбирать наугад.
> if ($symbols[$i]==' '){
> echo " ";
не очень понятно, зачем тут if.
> $symbol = preg_split('//u', $lines[$i], -1, PREG_SPLIT_NO_EMPTY);
переменная $symbol не используется.Ошибка в этой строке из-за того, что ты обращаешься к несуществующим элементам массива $lines.
> Ошибка при обращении к несуществующему элементу массива проявляется. Может кто подскажет как её обойти?
Не обращаться к несуществующим элементам.
https://github.com/ghp26/Students/tree/master/public/tpl
Почему шаблоны в публичной папке? Чтобы их можно было открыть браузером напрямую и просмотреть их код? Также, не стоит смешивать в одной папке css и html, лучше разнести в разные.
> if (iconv_strlen($formValues['name'], "UTF-8")>50
Лучше может mb_strlen? Ей не требуется указывать кодировку, если она задана в mb_internal_encoding().
> Вот это не понял. валидатор заточен для работы с формой и больше ни для чего другого не используется.
Идея ООП в том, чтобы разбивать код на максимально несвязанные части, так, чтобы каждый класс можно было рассматривать и редактировать в отдельности, особо не думая о других классах. Заодно это облегчает использование этих классов.
Если твой валидатор можно было бы использовать только с формой, то этот принцип нарушался бы. Но на самом деле, я тут не вижу привязки к форме, просто ты данные передаешь массивом. Это имеет такие недостатки:
- надо долго изучать код, чтобы понять, какого формата надо передать
- в массиве могут оттсутствовать любые поля. Тяжело писать код, когда не уверен что поле есть в массиве.
Лучше будет сделать валидатор, который валидирует модель абитурента независимо от того, откуда она получена, и не знает ничего про форму. Это не всегда возможно, например в каких-то формах могут быть дополнительные поля, которых нет в модели, или дополнительные правила валидации, но в данной задаче это нетрудно сделать. Как бонус, мы получаем например возможность перепроверить внесенные в базу данные с помощью этого валидатора. Модель абитуриента у тебя уже есть.
> Да, у меня расчет что массив POST содержит все нужные поля, и это не безосновательно, потому что все поля POSTa проверяются валидатором и если в них есть ошибки, то код не поломается, а выведет странцу на которой будет указанно(подчеркнуто красным и написано текстом) что именно введено не правильно
Нет. Посмотрим на код:
> $errorsArray = $validator->validate($_POST);
> ....
> public function validate($formValues)
> if (iconv_strlen($formValues['name'], "UTF-8")>50)
Если в $_POST нет ключа name, то обращение к $formValues['name'] вызовет ошибку. Кстати, если вместо массива передавать в валидатор объект-модель студента, то проблемы не будет - в объекте всегда есть описанные в классе поля.
https://github.com/ghp26/Students/blob/master/src/DBGateway.php
тут PDO правильнее не создавать в классе, а передавать с помощью dependency injection, читай урок https://github.com/codedokode/pasta/blob/master/arch/di.md
Класс сохранения абитуриентов в БД не должен заниматься поиском настроек или установкой соединения.
Папку .idea надо убрать из репозитория, внести в .gitignore, вернуть. папку vendor тоже. В репозитории должен быть твой код, а не устаревшие копии сторонних библиотек.
Кстати, раз уж ты используешь композер, зачем вручную делать require автозагрузчика твига? Исопльзуй композер и для автозагрузки своих классов тоже.
> "WHERE `birth` LIKE %текст_на_кирилице%" выдает ошибку SQL General error: 1271 Illegal mix of collations for operation 'like'
> Что с этим делать так и не придумал, поэтому поиска по дате пока нет. Вообще совершенно внезапно прога начала выдавать эту ошибку.
Я что-то вспоминаю, это из-за того, что оно типа DATE. Если открыть мануал на англ., то видно:
> Implicit conversion of a numeric or temporal value to string produces a value that has a character set and collation determined by the character_set_connection and collation_connection system variables. (These variables commonly are set with SET NAMES. For information about connection character sets, see Section 11.1.4, “Connection Character Sets and Collations”.)
Числа и даты при преобразуются в строку (а это происходит при исплоьзовании LIKE) с использованием кодировки и collation (правил сортировки строк по алфавиту), которые заданы в настройках соединения с mysql (обычно это делается через SET NAMES).
У тебя не задана кодировка соединения и используется какая-то, заданная в конфиге mysql. Очевидно, что она не совместима с кодировкой, используемой в поисковом запросе. Ты можешь узнать какие конкретно там кодировки и collation запросами (их надо делать из php скрипта):
SELECT CHARSET('%пример запроса%');
SELECT COLLATION('%пример запроса%');
SELECT CHARSET(birth) FROM students LIMIT 1; // + то же самое с COLLATION
Попробуй сделать и посмотреть, что выведется. В таблице у тебя utf8, а вот какая кодировка соединения - непонятно.
Скорее всего там будут несовместимые значения. Чтобы это исправить, надо задать кодировку соединения с БД utf8.
https://github.com/ghp26/Students/tree/master/public/tpl
Почему шаблоны в публичной папке? Чтобы их можно было открыть браузером напрямую и просмотреть их код? Также, не стоит смешивать в одной папке css и html, лучше разнести в разные.
> if (iconv_strlen($formValues['name'], "UTF-8")>50
Лучше может mb_strlen? Ей не требуется указывать кодировку, если она задана в mb_internal_encoding().
> Вот это не понял. валидатор заточен для работы с формой и больше ни для чего другого не используется.
Идея ООП в том, чтобы разбивать код на максимально несвязанные части, так, чтобы каждый класс можно было рассматривать и редактировать в отдельности, особо не думая о других классах. Заодно это облегчает использование этих классов.
Если твой валидатор можно было бы использовать только с формой, то этот принцип нарушался бы. Но на самом деле, я тут не вижу привязки к форме, просто ты данные передаешь массивом. Это имеет такие недостатки:
- надо долго изучать код, чтобы понять, какого формата надо передать
- в массиве могут оттсутствовать любые поля. Тяжело писать код, когда не уверен что поле есть в массиве.
Лучше будет сделать валидатор, который валидирует модель абитурента независимо от того, откуда она получена, и не знает ничего про форму. Это не всегда возможно, например в каких-то формах могут быть дополнительные поля, которых нет в модели, или дополнительные правила валидации, но в данной задаче это нетрудно сделать. Как бонус, мы получаем например возможность перепроверить внесенные в базу данные с помощью этого валидатора. Модель абитуриента у тебя уже есть.
> Да, у меня расчет что массив POST содержит все нужные поля, и это не безосновательно, потому что все поля POSTa проверяются валидатором и если в них есть ошибки, то код не поломается, а выведет странцу на которой будет указанно(подчеркнуто красным и написано текстом) что именно введено не правильно
Нет. Посмотрим на код:
> $errorsArray = $validator->validate($_POST);
> ....
> public function validate($formValues)
> if (iconv_strlen($formValues['name'], "UTF-8")>50)
Если в $_POST нет ключа name, то обращение к $formValues['name'] вызовет ошибку. Кстати, если вместо массива передавать в валидатор объект-модель студента, то проблемы не будет - в объекте всегда есть описанные в классе поля.
https://github.com/ghp26/Students/blob/master/src/DBGateway.php
тут PDO правильнее не создавать в классе, а передавать с помощью dependency injection, читай урок https://github.com/codedokode/pasta/blob/master/arch/di.md
Класс сохранения абитуриентов в БД не должен заниматься поиском настроек или установкой соединения.
Папку .idea надо убрать из репозитория, внести в .gitignore, вернуть. папку vendor тоже. В репозитории должен быть твой код, а не устаревшие копии сторонних библиотек.
Кстати, раз уж ты используешь композер, зачем вручную делать require автозагрузчика твига? Исопльзуй композер и для автозагрузки своих классов тоже.
> "WHERE `birth` LIKE %текст_на_кирилице%" выдает ошибку SQL General error: 1271 Illegal mix of collations for operation 'like'
> Что с этим делать так и не придумал, поэтому поиска по дате пока нет. Вообще совершенно внезапно прога начала выдавать эту ошибку.
Я что-то вспоминаю, это из-за того, что оно типа DATE. Если открыть мануал на англ., то видно:
> Implicit conversion of a numeric or temporal value to string produces a value that has a character set and collation determined by the character_set_connection and collation_connection system variables. (These variables commonly are set with SET NAMES. For information about connection character sets, see Section 11.1.4, “Connection Character Sets and Collations”.)
Числа и даты при преобразуются в строку (а это происходит при исплоьзовании LIKE) с использованием кодировки и collation (правил сортировки строк по алфавиту), которые заданы в настройках соединения с mysql (обычно это делается через SET NAMES).
У тебя не задана кодировка соединения и используется какая-то, заданная в конфиге mysql. Очевидно, что она не совместима с кодировкой, используемой в поисковом запросе. Ты можешь узнать какие конкретно там кодировки и collation запросами (их надо делать из php скрипта):
SELECT CHARSET('%пример запроса%');
SELECT COLLATION('%пример запроса%');
SELECT CHARSET(birth) FROM students LIMIT 1; // + то же самое с COLLATION
Попробуй сделать и посмотреть, что выведется. В таблице у тебя utf8, а вот какая кодировка соединения - непонятно.
Скорее всего там будут несовместимые значения. Чтобы это исправить, надо задать кодировку соединения с БД utf8.
Не нужно заменять ключи, лучше сделать отдельный массив с заголовками. Также, там бы не помешало немного ООП, плохая идея передавать массивы непонятных форматов, в которых непонятно, есть ли нужные ключи.
>>863612
> Уплачено = 62738.720457972
Неправильный ответ, должно быть 61270.
>>863674
Ответ пока что неправильный. Попробуй рассчитать выплату по кредиту на 4000 - должно получиться 6123 всего выплачено.
>>863765
> for ($k=0;$k<33;$k++){
Откуда взялось число 33? Если мы поменяем текст, надо вручную персчитывать это число? Зачем тогда вообще компьютер нужен, если все делается вручную?
Найти максимальную длину строки в массиве несложно. При желании это делается в 1 строку с помощью array_map и mb_strlen.
> if($doubleArray[$r][$k]==' '){
> echo " |";
зачем для пробела делать особый случай? Это такой же символ, как и другие.
Вместо $k и $r лучше использовать те же $i и $j.
> for ($j=0; $j<count($symbol); $j++) {
> $doubleArray[$i][$j] = $symbol[$j];
Тут не нужен цикл. Копирование массива делается одной строчкой.
Надо дорабатывать программу и получше разобраться в работе с массивами.
> Попытался сделать с разметкой как у опа, но я слишком ньюфаг для этого.
там всего лишь надо немного пробелов добавить.
>>863902
Хорошо бы поменять тип колонок на числовые (например через добавление и переименование), чтобы не беспокоиться о точках и запятых.
Не нужно заменять ключи, лучше сделать отдельный массив с заголовками. Также, там бы не помешало немного ООП, плохая идея передавать массивы непонятных форматов, в которых непонятно, есть ли нужные ключи.
>>863612
> Уплачено = 62738.720457972
Неправильный ответ, должно быть 61270.
>>863674
Ответ пока что неправильный. Попробуй рассчитать выплату по кредиту на 4000 - должно получиться 6123 всего выплачено.
>>863765
> for ($k=0;$k<33;$k++){
Откуда взялось число 33? Если мы поменяем текст, надо вручную персчитывать это число? Зачем тогда вообще компьютер нужен, если все делается вручную?
Найти максимальную длину строки в массиве несложно. При желании это делается в 1 строку с помощью array_map и mb_strlen.
> if($doubleArray[$r][$k]==' '){
> echo " |";
зачем для пробела делать особый случай? Это такой же символ, как и другие.
Вместо $k и $r лучше использовать те же $i и $j.
> for ($j=0; $j<count($symbol); $j++) {
> $doubleArray[$i][$j] = $symbol[$j];
Тут не нужен цикл. Копирование массива делается одной строчкой.
Надо дорабатывать программу и получше разобраться в работе с массивами.
> Попытался сделать с разметкой как у опа, но я слишком ньюфаг для этого.
там всего лишь надо немного пробелов добавить.
>>863902
Хорошо бы поменять тип колонок на числовые (например через добавление и переименование), чтобы не беспокоиться о точках и запятых.
>> Попытался сделать с разметкой как у опа, но я слишком ньюфаг для этого.
>там всего лишь надо немного пробелов добавить.
не работает в современных браузерах. Пробелы все удаляются же.
Нет, если ты записываешь в строку пробелы, а они не выводятся, значит или что-то не так в коде, или пробелы ты на самом деле не записал или ideone опять шатают, но это маловероятно.
Чтобы переносы строк (и пробелы) нормально работали и в браузере и в ideone (и в консоли), можно использовать для этого \n, а в начале программы поставить
header("Content-Type: text/plain; charset=utf-8");
Это заставит браузер воспринимать то, что выводит твоя программа, как обычный текст, а не HTML, и уважать переносы строк и пробелы в нем (так как в языке HTML перенос строки и любое число пробелов равносилен 1 пробелу).
Иначе перенос строки и пробелы будут в исходном коде страницы (его можно увидеть нажав Ctrl + U), но на самой странице их не будет.
С комментариями конечно становится понятнее. Однако, не стоит ссылаться на номера строк, так как ои могут меняться при редактировании и тебе придется возвращаться и править комментарий. Лучше просто разбить комментарий на части и написать их перед относящейся к ним командой.
Например, так:
// проверка определяет есть ли нужная купюра номиналом $i в банкомате
$check[$k] = $check[$k - $nominals[$i]];
Комментарии должны описывать алгоритм и ход мыслей автора, а не пересказывать содержимое каждой строчки. Вот этот комментарий несет мало пользы:
$tic = true;
> также переменная $tic становится true
Я понимаю, что ты описывал ход выполнения программы, но в данном случае ты описал его слишком подробно. Лучше было бы написать, для чего она предназначена, а то, что ей присваивается true, легко увидеть в коде. И надо дать ей нормальное имя, так как я не понимаю, что значит "tic". Что за тик?
Я вижу комментарий "переменная, которая позволяет или запрещает добавить одну банкноту к истинному решению, в зависимости от истинности выражения в строке ", но он мало что проясняет. Наверно надо написать "переменная, показывающая, найден ли способ выдачи суммы в $k рублей"
> $bestNominal
Тоже непонятно, что значит "лучший номинал"? По каким критериям он лучший?
> $solutionsStorage
> Значение массива $solutionsStorage под ключём n - лучшее(меньшее) количество банкнот, которым можно выдать число n.
Тогда массив правильнее назвать $minNotesForSum. В этом случае код будет гораздо очевиднее и потребует меньше комментариев.
Массив $check тоже назван не очень удачно так как непонятно что он "проверяет". Не описано нигде, что он хранит.
В общем, вот как надо сделать:
- описать перед переменными их назначение (очевидные вещи вроде счетчика цикла можно не писать)
- дать переменным название, которое соответствует комментарию
- описать в начале алгоритм в общих чертах, не пересказывая ход выполнения программы, а описывая именно принцип работы алгоритма. Ну например:
/*
Мы используем алгоритм <название> <ссылка>.
Мы берем последовательно суммы от 1 до до запрошенной суммы (6600)
и для каждой определяем минимальное количество и оптимальный
набор банкнот, которыми ее можно выдать. При этом на каждом шаге
мы используем решения для предыдущих шагов, добавляя к ним 1 купюру.
Ну например, если мы хотим выдать сумму в 900 руб., у нас есть
купюры номналом 100, 200, 500, и ранее мы рассчитали, что:
- сумму в 800 руб. (900 - 100) можно выдать 3 купюрами (500 + 200 + 100)
- сумму в 700 руб. (900 - 200) можно выдать 2 купюрами (500 + 200)
- сумму в 400 руб. (900 - 500) можно выдать 2 купюрами (200 x 2)
То мы перебираем эти варианты, пробуем к каждому добавить по 1 купюре
и выбираем лучший <по таким критериям>.
Очевидно, что сумму в 900 руб. оптимальнее всего выдать 3 купюрами,
добавив 200р. к варианту выдачи для 700. Однако, мы должны учитывать и запас
купюр. Если у нас имеется в запасе лишь 2 купюры номиналом 200,
то мы можем прибавить 500-рублевую купюру к варианту выдачи 400 рублей.
Как только мы дойдем до запрошенной суммы, мы получим решение задачи.
При этом мы должны учитывать оставшийся запас купюр. <описание, как это
учитывается>.
Если сумму не получается выдать <описание ситуаций,
когда выдать сумму невозможно, например для суммы вроде 1 рубль>.
*/
Хорошие комментарии и описание очень важны, если ты хочешь работать в команде над каким-то большим приложением, так как твоим колллегам будет проще разобраться в коде и сложнее допустить ошибку. Но даже если ты работаешь один, понятный код сэкономит тебе самому немало времени.
Заметь, что я постарался избегать дословного пересказа кода.
Кстати, почему $check хранит оставшийся запас купюр, а не использованные номиналы? Так не проще было бы?
> $nominals = array(100, 200, 500, 1000, 2000, 5000);
> $check[0] = array(
> 100 => 0,
> 200 => 3,
nominals наверно можно получить из check.
> for ($i = 0; $i < count($nominals); $i++){
> $nominals[$i]
Тут надо было применить foreach. Не надо копипастить выражение $nominals[$i] 10 раз.
> for ($k = 1; $k < $amount + 1; $k++){
Возможно, переменную надо было назвать как $testAmount или как-то так, чтобы было понятно, что в ней хранится.
> $k - $nominals[$i] >= 0
Может лучше писать $k >= $nominals[$i]
> $solutionsStorage[$k] = $solutionsStorage[$k - $nominals[$i]];
Вот тут я не понимаю, почему у нас решение для большей суммы требует столько же купюр, сколько и для меньшей. Почему не прибавляется единичка?
перемнную $tic правильнее очищать не в начале программы, а в начале цикла для суммы $k. Тогда это можно будет делать 1 раз и будет нагляднее видно, что она используется только внутри итерации цикла.
Я так понимаю, ты там определяешь лучший вариант и прбавляешь единицу позже. Но не лучше ли сразу прибавлять эту единицу, чтобы не возникало вопросов? А то у тебя какое-то время в $solutionsStorage хранится неверное значение. В случае с массивом $check, можно новую комбинацию тоже сразу считать и записывать в $check.
Вместо 9999 наверно лучше использовать константу INF - бесконечность. С ней нельзя делать математические операции (получится та же бесконечность), но можно делать сравнения.
Почему в алгоритме определения $bestNominal ты считаешь лучшей именно купюру с макс. номиналом?
В общем я вижу, что ты разобрался в алгоритме, но важно еще донести информацию читателю твоего кода, а с этим пока не очень.
> Мне нужны были в цикле не только значения номиналов(100, 200, 500), но и их ключи для более простой записи(они используются в цикле где инициализирована переменная $i), но если возможно использовать один массив, при этом не сильно усложняя запись кода - так и сделаю.
Можно сделать переменную с начальным запасом купюр, ее скопировать в $check и по ней определить номиналы, отсортировав их.
> у каждой суммы, которую можно выдать - свой запас банкнот, который хранится в $check[n], где n - сумма, которую нужно выдать. При этом используются только те элементы массива $check, при котором возможно выдать сумму n используемыми номиналами, если сумму выдать невозможно, в элементе массива $check[n] будет NULL.
Это надо написать в комментарии к массиву и переименовать его.
С комментариями конечно становится понятнее. Однако, не стоит ссылаться на номера строк, так как ои могут меняться при редактировании и тебе придется возвращаться и править комментарий. Лучше просто разбить комментарий на части и написать их перед относящейся к ним командой.
Например, так:
// проверка определяет есть ли нужная купюра номиналом $i в банкомате
$check[$k] = $check[$k - $nominals[$i]];
Комментарии должны описывать алгоритм и ход мыслей автора, а не пересказывать содержимое каждой строчки. Вот этот комментарий несет мало пользы:
$tic = true;
> также переменная $tic становится true
Я понимаю, что ты описывал ход выполнения программы, но в данном случае ты описал его слишком подробно. Лучше было бы написать, для чего она предназначена, а то, что ей присваивается true, легко увидеть в коде. И надо дать ей нормальное имя, так как я не понимаю, что значит "tic". Что за тик?
Я вижу комментарий "переменная, которая позволяет или запрещает добавить одну банкноту к истинному решению, в зависимости от истинности выражения в строке ", но он мало что проясняет. Наверно надо написать "переменная, показывающая, найден ли способ выдачи суммы в $k рублей"
> $bestNominal
Тоже непонятно, что значит "лучший номинал"? По каким критериям он лучший?
> $solutionsStorage
> Значение массива $solutionsStorage под ключём n - лучшее(меньшее) количество банкнот, которым можно выдать число n.
Тогда массив правильнее назвать $minNotesForSum. В этом случае код будет гораздо очевиднее и потребует меньше комментариев.
Массив $check тоже назван не очень удачно так как непонятно что он "проверяет". Не описано нигде, что он хранит.
В общем, вот как надо сделать:
- описать перед переменными их назначение (очевидные вещи вроде счетчика цикла можно не писать)
- дать переменным название, которое соответствует комментарию
- описать в начале алгоритм в общих чертах, не пересказывая ход выполнения программы, а описывая именно принцип работы алгоритма. Ну например:
/*
Мы используем алгоритм <название> <ссылка>.
Мы берем последовательно суммы от 1 до до запрошенной суммы (6600)
и для каждой определяем минимальное количество и оптимальный
набор банкнот, которыми ее можно выдать. При этом на каждом шаге
мы используем решения для предыдущих шагов, добавляя к ним 1 купюру.
Ну например, если мы хотим выдать сумму в 900 руб., у нас есть
купюры номналом 100, 200, 500, и ранее мы рассчитали, что:
- сумму в 800 руб. (900 - 100) можно выдать 3 купюрами (500 + 200 + 100)
- сумму в 700 руб. (900 - 200) можно выдать 2 купюрами (500 + 200)
- сумму в 400 руб. (900 - 500) можно выдать 2 купюрами (200 x 2)
То мы перебираем эти варианты, пробуем к каждому добавить по 1 купюре
и выбираем лучший <по таким критериям>.
Очевидно, что сумму в 900 руб. оптимальнее всего выдать 3 купюрами,
добавив 200р. к варианту выдачи для 700. Однако, мы должны учитывать и запас
купюр. Если у нас имеется в запасе лишь 2 купюры номиналом 200,
то мы можем прибавить 500-рублевую купюру к варианту выдачи 400 рублей.
Как только мы дойдем до запрошенной суммы, мы получим решение задачи.
При этом мы должны учитывать оставшийся запас купюр. <описание, как это
учитывается>.
Если сумму не получается выдать <описание ситуаций,
когда выдать сумму невозможно, например для суммы вроде 1 рубль>.
*/
Хорошие комментарии и описание очень важны, если ты хочешь работать в команде над каким-то большим приложением, так как твоим колллегам будет проще разобраться в коде и сложнее допустить ошибку. Но даже если ты работаешь один, понятный код сэкономит тебе самому немало времени.
Заметь, что я постарался избегать дословного пересказа кода.
Кстати, почему $check хранит оставшийся запас купюр, а не использованные номиналы? Так не проще было бы?
> $nominals = array(100, 200, 500, 1000, 2000, 5000);
> $check[0] = array(
> 100 => 0,
> 200 => 3,
nominals наверно можно получить из check.
> for ($i = 0; $i < count($nominals); $i++){
> $nominals[$i]
Тут надо было применить foreach. Не надо копипастить выражение $nominals[$i] 10 раз.
> for ($k = 1; $k < $amount + 1; $k++){
Возможно, переменную надо было назвать как $testAmount или как-то так, чтобы было понятно, что в ней хранится.
> $k - $nominals[$i] >= 0
Может лучше писать $k >= $nominals[$i]
> $solutionsStorage[$k] = $solutionsStorage[$k - $nominals[$i]];
Вот тут я не понимаю, почему у нас решение для большей суммы требует столько же купюр, сколько и для меньшей. Почему не прибавляется единичка?
перемнную $tic правильнее очищать не в начале программы, а в начале цикла для суммы $k. Тогда это можно будет делать 1 раз и будет нагляднее видно, что она используется только внутри итерации цикла.
Я так понимаю, ты там определяешь лучший вариант и прбавляешь единицу позже. Но не лучше ли сразу прибавлять эту единицу, чтобы не возникало вопросов? А то у тебя какое-то время в $solutionsStorage хранится неверное значение. В случае с массивом $check, можно новую комбинацию тоже сразу считать и записывать в $check.
Вместо 9999 наверно лучше использовать константу INF - бесконечность. С ней нельзя делать математические операции (получится та же бесконечность), но можно делать сравнения.
Почему в алгоритме определения $bestNominal ты считаешь лучшей именно купюру с макс. номиналом?
В общем я вижу, что ты разобрался в алгоритме, но важно еще донести информацию читателю твоего кода, а с этим пока не очень.
> Мне нужны были в цикле не только значения номиналов(100, 200, 500), но и их ключи для более простой записи(они используются в цикле где инициализирована переменная $i), но если возможно использовать один массив, при этом не сильно усложняя запись кода - так и сделаю.
Можно сделать переменную с начальным запасом купюр, ее скопировать в $check и по ней определить номиналы, отсортировав их.
> у каждой суммы, которую можно выдать - свой запас банкнот, который хранится в $check[n], где n - сумма, которую нужно выдать. При этом используются только те элементы массива $check, при котором возможно выдать сумму n используемыми номиналами, если сумму выдать невозможно, в элементе массива $check[n] будет NULL.
Это надо написать в комментарии к массиву и переименовать его.
> Да, в задаче сказано сколько человек в классе и сколько слогов в считалочке, но ничего не сказано о том, сколько человек должно в итоге остаться пить чай.
Как только их останется столько же, сколько слогов в считалочке, подсчет заканчивается и они идут пить чай.
>>864328
Если "this guy" так много работает, ему наверно не до девушек. Не о чем беспокоиться.
>>864340
Все так. Хотя лучше бы не работать с числом, как со строкой, а использовать математику.
>>864399
Сериализация нужна, если ты хочешь сохранить в файл например массив. Файл это ведь строка по сути и чтобы записать туда массив, надо его как-то обратимо преобразовать в строку, для этого служит сериализация.
>>864422
Это он так шутит
>>864625
Это был комментарий про загрузку пользователяи файлов, а не про кеш. В кеше можно использовать md5, но мне не нравится что по хешу нельзя понять исходный ключ, это неудобно.
Мы перешли в новый тред >>864640 (OP)
Этот тред закрыт. Не пишите здесь больше.
я тот анон, что просил у вас помощи по фильтрам. В общем я уже подошел к концу своего тз и опять прочитав задания понял, что нихуя не понял что от меня хотят собственно вот:
Создать два базовых класса описывающих сотрудника с почасовой оплатой, второй, описывающий сотрудника с месячной ставкой. Вычисление оплаты труда для сотрудников с почасовой оплатой будет иметь следующую формулу: количество часов * сумму за один час. Для сотрудников со ставкой метод расчета возвращает месячную ставку. Реализовать следующую функциональность:
ну собственно дальше функциональность всю запилил, что они хотели.
Я не глупый, шарю в опп, но хоть убей не пойму что они от меня хотят.
как именно описать сотрудника?, типа при выводе всех сотрудников определять тип сотрудника и переводить его в нужный объект, который просто пересчитает его зп и закинет все параметры в свойства. По типу метода фабрики.
В общем кто из более опытных анонов понял в чем дела, прошу объяснить.
Мы уже в новом треде.
Задача решена верно, хотя я бы не ставил echo в функцию, а сделал бы чтобы она просто возвращала строку.
Это копия, сохраненная 8 ноября 2016 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.