Это копия, сохраненная 16 марта 2016 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
Почему PHP? Потому что фейсбук и википедия на нем написаны, и вакансий море, и учить легко.
Это тред для начинающих. Не написал за свою жизнь ни одной программы? Ты наш человек.
Устанавливать пока что ничего не требуется, разве что редактор кода вроде Sublime Text 3, Notepad++, Netbeans PHP или PhpStorm (с ним будет удобнее).
Предыдущий тред был тут: >>664784 (OP) (почти 1000 постов!)
Что самое главное для программиста? Умение аккуратно оформлять код (читай второй пост).
Правила: ведем себя воспитанно, помогаем новичкам, постим ссылки на решения задачек, ОП их проверяет и дает советы и замечания. ОП отвечает даже на самые нубские вопросы. ОП заходит где-то раз в 2-3 дня, не жди его, решай задачки дальше.
У нас есть уроки по основам PHP, они собраны и выложены по адресу http://archive-ipq-co.narod.ru/ Это учебник для изучающих с нуля, то есть если ты вообще ничего не знаешь, то надо начать с него. Он простой и понятный (по крайней мере в начале). Там есть задачи, их надо решать обязательно (чтобы стать программистом, надо писать код — иначе никак). Пости ссылки на решения в тред, мы их проверим, напишем замечания и дадим советы по улучшению.
Если не знаешь как решать, запости код, напиши в каком месте остановился и попроси подсказку.
Учебник дает основы языка PHP, но чтобы делать сайты, этого недостаточно. Если ты его прошел, то надо переходить в более серьезным задачкам, которые научат тебя как выдавать страницы в браузер, работе с таблицами в БД, работе с формами, MVC.
- Для начала установи Апач + PHP (советы ниже) и читай туториал http://php.net/manual/ru/tutorial.php
- Учи HTML/CSS и SQL, хотя бы основы
- Далее простая, но полезная задача сделать список студентов, в ней много полезных советов: https://github.com/codedokode/pasta/blob/master/student-list.md
- Более сложная задача сделать файлообменник на микрофреймворке Slim: https://gist.github.com/codedokode/9424217
- Еще более сложная и долгая задача на Yii/Yii2: https://gist.github.com/codedokode/8733007
- После нее можно изучать автоматизированное тестирование
- Если ты все решил, переходи к Symfony 2/Doctrine 2
Чтобы делать эти задания, тебе надо установить Апач + PHP (можно заодно сразу и MySQL) на компьютер. Вот полезные инструкции:
https://gist.github.com/codedokode/10774100
https://gist.github.com/codedokode/7054af4a03865c4cc863
Может тебе понадобится пользоваться командной строкой, вот гайд https://gist.github.com/codedokode/10539568
Вот небольшой туториал по тому как начать использовать PHP на сервере для отдачи странички в браузер: https://php.net/manual/ru/tutorial.php Увы, уроков плавно подводящих к тому, как сделать задачи выше, пока нет, так что если что, задавай вопросы.
Решения задач лучше показать мне, особенно на ООП,так как сам ты вряд ли увидишь все ошибки. Пости свой код на гитхаб и вкидывай ссылку в тред по мере решения. Я прокомментирую и укажу на ошибки.
Также, у нас есть задачи которые позволят тебе изучить или подтянуть до нормального уровня знания JS/HTML/CSS/SQL. Решай их параллельно с задачами выше.
- HTML/CSS: https://gist.github.com/codedokode/58ebc90bd006baf4b35c
- JS: https://gist.github.com/codedokode/ce30e7a036f18f416ae0
- SPA (сложно): https://github.com/codedokode/pasta/blob/master/js/spa.md
- Проверялка решений на JS: http://dkab.github.io/jasmine-tests/
- MySQL: https://gist.github.com/codedokode/10539213
Что почитать
- Мануал по PHP — http://www.php.net/manual/ru/langref.php
- Сайт phptherightway (перевод на русский: http://getjump.me/ru-php-the-right-way/ )
- По PHP: Профессиональное программирование на PHP Джордж Шлосснейгл
- По PHP: Мэтт Зандстра — PHP: Объекты, шаблоны, методики программирования
- JS: learn.javascript.ru
- Про Git: https://git-scm.com/book/ru/v1
Нужен ли ООП, фреймворки, MVC? — Да, однозначно. Посмотри любую вакансию.
Сайт опять упал!!!!! — Не паникуй, а открой http://rghost.net/45000175 и получи личную немного устаревшую копию сайта
Оформляй код аккуратно!!! — например пропусти через phpformatter.com . Также, если ты пользуешься IDE вроде PhpStorm, Netbeans, Eclipse, то в них эта опция встроена, подробнее: https://gist.github.com/codedokode/8759492
ОП, сделай за меня мою работу или домашнее задание? — Это конечно, хорошая идея, но нет.
Подскажи сайты для поиска работы, я не умею гуглить? — 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/php-fig/fig-standards/blob/master/accepted/ru/PSR-1-basic-coding-standard.md
PSR-2: https://github.com/php-fig/fig-standards/blob/master/accepted/ru/PSR-2-coding-style-guide.md
------------------
Итак, ты зашел в тред и решил помочь какому-то анону, дав ему совет или подсказку. Спасибо! Но прочти сначала эти напоминания, чтобы твоя помощь действительно была полезной.
Будь доброжелателен
Не годится: «Ты мануал хоть раз в жизни открывал, обезьяна?»
Не годится: «В гугле забанили?»
Не годится: «Твой код плохой»
Хорошо: «Вот, как можно улучшить этот код: ...»
Хорошо: «Ты неправильно используешь функцию 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/php-fig/fig-standards/blob/master/accepted/ru/PSR-1-basic-coding-standard.md
PSR-2: https://github.com/php-fig/fig-standards/blob/master/accepted/ru/PSR-2-coding-style-guide.md
------------------
Итак, ты зашел в тред и решил помочь какому-то анону, дав ему совет или подсказку. Спасибо! Но прочти сначала эти напоминания, чтобы твоя помощь действительно была полезной.
Будь доброжелателен
Не годится: «Ты мануал хоть раз в жизни открывал, обезьяна?»
Не годится: «В гугле забанили?»
Не годится: «Твой код плохой»
Хорошо: «Вот, как можно улучшить этот код: ...»
Хорошо: «Ты неправильно используешь функцию abc(). Вот ее описание: ссылка, и как видишь ей надо передать строку, а не массив»
Не придирайся к знанию английского языка.
Объясняй
Не очень хорошо: «сделай как в этом коде»
Хорошо: «если ты вставляешь текст от пользователя в SQL запрос, то получается SQl-инъекция, которая позволяет взломать твой сервер (ссылки). Чтобы этого избежать, надо вставлять данные с помощью плейсхолдеров (ссылки)»
Хорошо: «Помни, что код пишется для людей. Если писать такие большие функции, то в них становится трудно разобраться...»
Не проповедуй
Мы учим использованию самых распространненных подходов, стандартов, библиотеки фреймворков. Если ты не любишь ООП, пробелы в коде, jQuery, сам PHP, то рассказать об этом стоит в каком-нибудь другом треде.
Не придирайся к знанию английского языка, анон пишет как умеет.
Ах да. Если тебе кажется, что что-то в учебнике или задачах можно сделать лучше — пиши, обратная связь всегда очень полезна.
>непрограммисты живут довольно бедно
Лол.
В Америке программисты и админы считаются средними профессиями для всяких индусов и арабов эмигрантов. И платят программистам там довольно среднюю зарплату, которая куда ниже зарплаты врача или адвоката. А в России ты можешь устроиться в бодишоп который работает на зарубежных клиентов и жить как король.
|
|
+--subclass - тут у меня класс наследующий класс /classes/Class.php с именем Subclass
|
|
+index.php - а тут я создаю экземпляр Subclass
Как мне сделать, чтобы всё это автоматически подключалось и не нужно было бы при добавлении новых классов писать бесконечные include?
Почитай про пространства имен и автозагрузку с помощью них.
https://github.com/codedokode/pasta/blob/master/php/autoload.md
> которая куда ниже зарплаты врача или адвоката
Только не факт что ты попадешь на рыбное место - а оплачивать дорогущее обучение надо. http://www.nytimes.com/2015/04/27/business/dealbook/burdened-with-debt-law-school-graduates-struggle-in-job-market.html?_r=0
Вообще это платное обучение выглядит как обман.
Есть кредиты на обучение, но я не хочу начинать чат уже в начале треда. Погугли если интересно.
>в СФ минимальная з/п $12.15, а в других штатах может быть 6-8 в час
Не, в СФ наоборот экономят вроде. Читал программиста, который уехал туда работать, он пишет, что хочет все равно уйти к яблочникам, хоть там и ЗП меньшую предложили. Тупо хочет в эппле поработать, мечта у человека.
>куда ниже зарплаты врача или адвоката
Сравнил профессии. Адвокат и врач - это пиздец как долго и дорого, плюс ответственности больше. Еще бы чинушей из правительства привел в пример.
Анон, стоит смотреть курсы, например, линду, Борисова? Они представляют какую-либо ценность в обозримой перспективе?
$test = array();
$test[452] = 5;
Избежать ошибки?
Notice: Undefined offset:
Вообще возможно ли динамически добавлять значения в ассоциативный массив?
Странно. Notice выдаётся только при обращении к неопределённому индексу. Посмотри на какую строку ругается PHP, возможно ошибка в другом месте.
> при обращении к неопределённому индексу
А он и не определен. Я создаю пустой массив и далее хочу его динамически наполнять $test[$key] = $value;
Криво выразился. Имеется ввиду что-то типа
$test = array();
echo $test[452]; // тут возникает Notice.
То, что делаешь — в PHP абсолютно нормально.
Задание 1 -
Задание 1 -
Задание 1 -
Задание 1 - https://jsfiddle.net/a0a7e51v/
Задание 2 - https://jsfiddle.net/aeqp2pq5/
Задание 4 - https://jsfiddle.net/j3hsp8bg/
Задание 5 - https://jsfiddle.net/smpwuf8k/
Задание 6 - https://jsfiddle.net/t03a2v4q/ что-то я не смог справиться без вот этого селектора * { } в рекомендациях написано его не использовать, но а как скинуть все стандартные отступы?
Только если ты совсем нуб, который не может ни слова понять из документации (у меня так было год назад).
В общем, для новичка представляют, но надо понимать что это самые основы, этого совсем недостаточно чтобы работать.
Ну это понятно, что после просмотра видоса не станешь йоба-про.
Просто хотел поинтересоваться, потеря это времени или нет. Хотя, в принципе, оказалось, что длина этих курсов не такая и большая, вполне можно за эти выходные все посмотреть. Я думал, что там сотни часов лекций, лол.
Очевидно - не обращайся к ключам которых нет в массиве. Например нумеруй их последовательно, чтобы там всегда были ключи от 0 до N.
А зачем их "скидывать"? Ты же наверняка даже не можешь перечислить, на что повлияет такой "сброс".
Нужно делать селектор для конкретно тега, который нужен в данном случае.
Убрать поля и отступы у body и html? Напиши правило
html, body { margin:0; padding: 0}
Тяжело?
Нужно переопределить отступы у параграфов?
Переопредели явно
p { margin: 10px; }
> я не смог справиться без вот этого селектора
Зачем тебе сбрасывать все оступы? Чтобы когда ты текст захочешь добавить или список, они шли сплошной стеной без абзацев? Так? Ну ты сам подумай.
Тебе не надо сбрасывать все отступы. Только на некоторых элементах, где это требуется для верстки.
>>678297
ресет инструмент быдловерстальщика. Сейчас это поняли даже на западе, где их и придумали. Я кстати никогда их не использовал и у меня все прекрасно версталось и работало в разных браузерах.
>Изучал бы уже 2-ю версию.
Я реалистично настроен, и понимаю, что в 80% случаев придется иметь дело со всякими "легаси"-проектами, написанными с использованием несвежих технологиях.
В моей мухосрани все вообще упрямо сидят на первом зенде.
Так что ты не прав, знание косяков первого yii думаю очень сильно пригодится. Так конечно было бы здорово учить что хочешь и использовать только любимые инструменты.
>Лучше не использовать тут сессии так как сессия одна на много вкладок.
Я тоже об этом подумал, когда разбирался с устройством компонента user в yii. Но уж если разработчики yii пошли таким путем, то и мне можно (жираф большой, ему видней).
>Это именно что кривой костыль
И не просто костыль, он в итоге еще и не работает.
Если пользователь со страницы /a попытается перейти на /b, где его отредиректит на /c, то в экшене для /c в реферере окажется как раз /a, а не /b как мне нужно.
Решил другим костыльным способом: на странице /b сохранять ее url в сессию, а на странице /c (логина) уже после рендера удалять эти данные из сессии.
$this->render('login'); Yii::app()->user->удалить_из_сессии.
Но "твой" способ (че-то я сомневаюсь, что вот прям сейчас это сам изобрел) действительно самый оптимальный. Если не учитывать замусоренность полученного урл.
>все из-за непоимания того как работает протокол HTTP
Как сказать. Теорию я неплохо знаю, все эти заголовки, методы. Помню пару месяцев назад мы вскрывали эту тему, ты мну даже заставлял формировать post запросы руками. С курлом знаком, с guzzle.
Тут скорее тупо не додумался, что можно было нужные данные отправить в виде гет-параметров. Наверняка это какой-нибудь паттерн, которому даже дали глубокомысленное имя. Например алгоритм обработки форм, который мы использовали в задачах на сайт вуза и файлообменник, это оказывается PRG https://ru.wikipedia.org/wiki/Post/Redirect/Get
Кстати у способа с гет-параметрами есть недостаток в том, что пользователь может нажать кнопку "назад", его в истории перекинет опять на страницу с сообщением.
Ну ладно, хвалю себя за дотошность в этом вопросе.
>Изучал бы уже 2-ю версию.
Я реалистично настроен, и понимаю, что в 80% случаев придется иметь дело со всякими "легаси"-проектами, написанными с использованием несвежих технологиях.
В моей мухосрани все вообще упрямо сидят на первом зенде.
Так что ты не прав, знание косяков первого yii думаю очень сильно пригодится. Так конечно было бы здорово учить что хочешь и использовать только любимые инструменты.
>Лучше не использовать тут сессии так как сессия одна на много вкладок.
Я тоже об этом подумал, когда разбирался с устройством компонента user в yii. Но уж если разработчики yii пошли таким путем, то и мне можно (жираф большой, ему видней).
>Это именно что кривой костыль
И не просто костыль, он в итоге еще и не работает.
Если пользователь со страницы /a попытается перейти на /b, где его отредиректит на /c, то в экшене для /c в реферере окажется как раз /a, а не /b как мне нужно.
Решил другим костыльным способом: на странице /b сохранять ее url в сессию, а на странице /c (логина) уже после рендера удалять эти данные из сессии.
$this->render('login'); Yii::app()->user->удалить_из_сессии.
Но "твой" способ (че-то я сомневаюсь, что вот прям сейчас это сам изобрел) действительно самый оптимальный. Если не учитывать замусоренность полученного урл.
>все из-за непоимания того как работает протокол HTTP
Как сказать. Теорию я неплохо знаю, все эти заголовки, методы. Помню пару месяцев назад мы вскрывали эту тему, ты мну даже заставлял формировать post запросы руками. С курлом знаком, с guzzle.
Тут скорее тупо не додумался, что можно было нужные данные отправить в виде гет-параметров. Наверняка это какой-нибудь паттерн, которому даже дали глубокомысленное имя. Например алгоритм обработки форм, который мы использовали в задачах на сайт вуза и файлообменник, это оказывается PRG https://ru.wikipedia.org/wiki/Post/Redirect/Get
Кстати у способа с гет-параметрами есть недостаток в том, что пользователь может нажать кнопку "назад", его в истории перекинет опять на страницу с сообщением.
Ну ладно, хвалю себя за дотошность в этом вопросе.
> Кстати у способа с гет-параметрами есть недостаток в том, что пользователь может нажать кнопку "назад", его в истории перекинет опять на страницу с сообщением.
Я не считаю это чем-то неожиданным, браузер вернул пользователя на ту страницу где он был. Более того, если пользоатель нажмет "назад" еще несколько раз - скорее всего браузер покажет закешированную страницу где он был еще разлогинен (и возможно именно это пользователю и требуется).
HTTP изначально ориентировался на "stateless" режим работы, без сохранения состояния, когда содержимое страницы определяется ее URL. С добавлением залогиненности появляется состояние и появляются расхождения с этой моделью.
http://brtrg.by/blog/post/97
Как к этому алгоритму приделать ограничение числа банкнот.
т.е. есть набор банкнот 5р - 10шт 10р - 50шт 100р-1шт
надо нам выдать 200р
Этот алгоритм выдаст оптимальный вариант 2х100, он не учитывает количество банкнот и то, что есть не оптимальный вариант 1х100 10х10
Это банкомат сбербанка.
>Если я не совсем понимаю этот алгоритм, то дальше можно и не продолжать изучать PHP?
Нужно просто разобраться.
Можно начать с более простого (но менее эффективного) алгоритма:
- перебираем все возможные комбинации купюр (таких комбинаций (b1 + 1) x (b2 + 1) x .. (bN + 1), где b1 .. bN - это запасы купюр разных номиналов )
- оставляем из них те которые в сумме дают нужный результат
Если сделать последовательный перебор, то видно что он будет не очень эффективен, так как он будет перебирать комбинации подряд:
0 0 0 1
0 0 0 2
0 0 0 3
...
0 0 1 0
...
Можно его оптимизировать, определяя начальные значения жадным алгоритмом и уменьшая их то есть примерно в таком порядке:
4 ? ? ?
4 6 ? ?
4 6 2 ? - не подходит, недостаточно купюр меньшего номинала
3 ? ? ?
3 10 ? ?
3 10 2 ?
3 10 2 1 - подошло
В случае с алгоритмом из задачи по ссылке. Надо разобраться, можно ли его доработать чтобы не рассматривать невозможные сочетания.
В первую очередь тебе конечно надо понять как он вообще работает.
Там в задаче функция F возвращает число банкнот нужное для выбачи суммы, вроде того что если F(100) = 5 то это значит что 100 меньше чем 5 банкнотами не выдать. Функция определяется рекуррентно, через саму себя.
Нам нужна другая функция, которая возвращает не число, а комбинацию, такого вида:
F(100) = { 2 3 0 0 }
То есть каким набором купюр выдается эта сумма. Но трюк в том что одну сумму можно выдать разными наборами (в той задаче это значения не имеет так как там нужен только вариант с наименьшим числом купюр, а их число не ограничено). Подойдет ли этот алгоритм к нашей задаче?
Можно начать с более простого (но менее эффективного) алгоритма:
- перебираем все возможные комбинации купюр (таких комбинаций (b1 + 1) x (b2 + 1) x .. (bN + 1), где b1 .. bN - это запасы купюр разных номиналов )
- оставляем из них те которые в сумме дают нужный результат
Если сделать последовательный перебор, то видно что он будет не очень эффективен, так как он будет перебирать комбинации подряд:
0 0 0 1
0 0 0 2
0 0 0 3
...
0 0 1 0
...
Можно его оптимизировать, определяя начальные значения жадным алгоритмом и уменьшая их то есть примерно в таком порядке:
4 ? ? ?
4 6 ? ?
4 6 2 ? - не подходит, недостаточно купюр меньшего номинала
3 ? ? ?
3 10 ? ?
3 10 2 ?
3 10 2 1 - подошло
В случае с алгоритмом из задачи по ссылке. Надо разобраться, можно ли его доработать чтобы не рассматривать невозможные сочетания.
В первую очередь тебе конечно надо понять как он вообще работает.
Там в задаче функция F возвращает число банкнот нужное для выбачи суммы, вроде того что если F(100) = 5 то это значит что 100 меньше чем 5 банкнотами не выдать. Функция определяется рекуррентно, через саму себя.
Нам нужна другая функция, которая возвращает не число, а комбинацию, такого вида:
F(100) = { 2 3 0 0 }
То есть каким набором купюр выдается эта сумма. Но трюк в том что одну сумму можно выдать разными наборами (в той задаче это значения не имеет так как там нужен только вариант с наименьшим числом купюр, а их число не ограничено). Подойдет ли этот алгоритм к нашей задаче?
Ой, я привел плохой пример оптимизированного алгоритма. Там логика такая: для каждого номинала мы сначала берем максимально возможное число, которое бы не превышало требуемую сумму. Если не получается - отходим назад (бектрекинг) и уменьшаем число купюр на 1. И получается такая последовательность:
4 ? ? ? (если взять 5 то будет перебор, потому 4)
4 6 ? ? (4 7 дадут слишком много потому 6)
4 6 2 ? - не подходит, не хватает купюр меньшего номинала, откатываемся на 1 шаг
4 5 12 ? - не подходит, не хватает купюр меньшего номинала, откатываемся на 1 шаг
4 4 12 ? - не подходит, не хватает купюр меньшего номинала, откатываемся на 1 шаг
....
4 0 12 ? - дальше уменьшать 0 некуда, потому отходим на 2 шага и уменьшаем число старших купюр с 4 до 3
3 ? ? ?
3 10 ? ?
3 10 2 ?
3 10 2 1
Тут правда тоже есть не очень эффективный момент, где мы уменьшаем число второго вида купюр на 1, каждый раз натыкаясь на ту же проблему. Это можно исправить, если учитывать общую сумму купюр меньшего номинала.
То есть логика оптмизированного алгоритма такая:
- допустим у нас выбрано несколько купюр более старшего номинала, и нам надо перебрать все варианты более младших купюр.
Допустим у нас уже есть комбинация 4 6 ? ? и надо проверить какие возможны комбинации для третьей купюры (выделена).
Мы определяем 2 значения:
- макс. число купюр этого номинала которое не превысит искомую сумму (max)
- минимальное число купюр, которое позволяет добить остаток суммы более маленькими купюрми (min)
Допустим у нас получилось min = 2 и max = 10. Значит мы должны проверить все значения от
4 6 10 ?
до
4 6 2 ?
Если не найдем - значит комбинация 4 6 ? ? не годится и надо отступить на шаг, например к комбинации 4 7 ? ?
Я не автор вопроса.
ОП мне ответил невпопад, вот я и указываю на это.
Больше в эту ветку ничего не пишу
вторая для ИД + номер группы + кол-во баллов?
или надо сделать огромное количество таблиц типа:
ИД + год рождения
ИД + имя
ИД + фамилия
ИД + кол-во баллов
?
Объясни по какой логике ты решил так разложить данные? Например, почему номер группы и кол-во баллов в одной таблице?
пикрандом для привлечения внимания
Я много возился с БД(но, видимо, недостаточно), просто начинаю тупить и это дико выводит из себя. Т.е. делать как тут сказал (скажи лишь да/нет, прошу тебя) >>678777 ?
Разве не достаточно одной таблицы для этого?
Parse error: syntax error, unexpected '$i' (T_VARIABLE) in C:\OpenServer\domains\localhost\models\News.php on line 38
Анончики выше правы - там хватит и одной таблицы. Ты же будешь обращаться к полям по запросам, и вернуть ты можешь лишь, то, что тебе сейчас надо.
Кун с пикчей выше твоего поста.
Т.е. одна огромная таблица ИД + имя + фамилия + номер группы + год рождения.... и т.д.?
Да не, я просто уточняю. Читал в инетах, что этого лучше избегать и делать много таблиц спаренных с ключом (id), но если всё ок, то мне же легче
Да, но допустим тебе надо отобразить имя, фамилию, баллы.Тогда пишем.
'SELECT first_name, second_name, marks FROM students ORDED BY marks DESC'
Не выкладывай куски скриншотов, выкладывай код (все содержимое файла News.php, не фрагмент) на http://ideone.com
и давай ссылку в тред.
По тексту ошибки: где-то пропущена точка с запятой, или скобка. По фрагменту кода на рисунке не видно где ошибка, скорее всего выше или ниже.
Еще нужно использовать подготовленные выражения http://php.net/manual/ru/pdo.prepare.php
fetch используется для извлечения одной строки, используй fetchAll чтобы получить все записи, без этих странных манипуляций с циклами и ключами массивов.
Вместо select x можно (и нужно) указывать имена колонок, тогда не нужно будет их специально выбирать.
SELECT x пишут только в документации (ради обобщения) и быдлокодеры (потому что лень писать имена колонок и потому что бездумно копируют из документации).
И "новость" это объект, значит и возвращать fetchAll должен массив объектов, а не массив массивов. У тебя же есть класс News?
http://php.net/manual/ru/pdostatement.setfetchmode.php
>>678815
Группа это другая сущность. Группу лучше сделать отдельной таблицей. Но в этом задании наверное можно все занести в одну таблицу.
>>678821
Это (объединение таблиц, джойны) появится позже, когда кол-во классов будет больше. Например в блоге есть новости, есть пользователи-авторы, у новостей есть комментарии, у комментариев (и статей) лайки. Тогда под каждый класс отдельную таблицу и ссылки через внешний ключ.
Вы просто бог пхп, скопировал в идеоне код и там после запроса стояла точка, хотя я не мог ее разглядеть, удалил вставил обратно и заработало.
А замечания обязательно учту.
Вот мой код: http://ideone.com/UjE2KF
Дальше к сути.
Более конкретно:
1) Как я изначально понял, то эта функция добавляет вопрос в массив с вопросами, отсюда я уже ошибся в следующем:
а) Массив создаётся в функции и не является глобальным(?).
б) Всё можно реализовать более простым образом, но я всё испортил. Да, я знаю про __construct
2) Изначально думал, что внутри этой функции есть конструктор, который по вводным данным создаёт несколько вопросов и засовывает их в массив, но потом понял, что выйдет слишком много данных, которые нужно указать в input'е функции.
3) Дальше я увидел, что вопросы прописываются уже в функции, но в примере вопрос №1 и вопрос №2 обозначаются одной переменной $q. Это же для простоты или я тупой?
4) Нужно ли указывать ключ при создании такого массива в рамках этой функции или всё можно отдать автоматическому назначению?
5) Но тогда какой толк от этой функции, если так собрать все вопросы в массив можно и без самого создания функции.
Надеюсь, нестыковки, с которыми я столкнулся, понятны.
Я не тролль.
Есть какой-то особенный урок, я его пропустил? Как совмещать html и php файлы? Что вообще делать.
Я в панике
Не в кассу вообще. Его техническая часть интересует, а не архитектура приложений.
Далее, ОП, нужна задача по сокетам и написанию демона. Можешь придумать, пожалуйста? Ну и хорошими и добрыми ссылками покидать по этой теме. Я уже гуглил и читал, но вдруг ты знаешь, где понятнее и грамотнее расписана теория.
А модель содержит классы, но это не значит, что нужно советовать гуглить мвц человеку, спрашивающему про ООП.
я их все сделал в январе где-то. Так они же на чистый ХТМЛ были, там ни слова про взаимодействие с php
Я тут один такой непонимающий? Как вы преодолели тепличные условия учебника, где можно аутировать и решать задачки и выход на студенты, где в пояснениях сыпятся слова типа "используй шаблон", "паттерны", взаимодействие разных файлов php и html+css, фреймворки. Как вы перескочили? У меня какая-то паническая атака начинается
Я просто гуглил много.
input там помнишь такое? Button, checkbox и т.п.
Вот это позволяет что-то вводить с каким-нибудь результатом.
Любую задачу из первых уроков можно перевести в html, на месте основных данных поставить разные input'ы - всё будет работать внутри html.
>>678883
Да это ерунда, я просто до этого клепал сайтики на чистом html, вставлял туда калькулятор на php, ничего сложного.
РНР тем и хорош, что легко вставляется в HTML, всё работает на странице.
А JS потом будет динамику отображения создавать.
Так вот. Как заставить себя сесть дописать ебаный движок? Уже видеть этот PHP не могу.
Вот как у анона с переводом чисел в пропись: http://blankionline.ru/servisy/summ-propis.html
Там тот же скрипт, который мы и должны были написать при решении задачи, но встроен в html-страницу просто, а на месте основных переменных - инпуты для ввода текста.
>>678887
А что будет, если не сдашь сайт?
Дык вот так: >>678875
Ты как с луны свалился.
Просто так и вставлен, а инпуты и аутпуты отвечают за ввод/вывод.
Вот тут посмотри: http://htmlbook.ru/html/output
Только там на JS код в аутпуте, а ты можешь подключить РНР, вставив ссылку на файл или просто сам код, как подключаешь CSS.
>А что будет, если не сдашь сайт?
Непочет и неуважение.
Меня отрекомендовал друг, поэтому там вообще некрасиво получается.
Интересно, за 2 года я впервые вижу этот тег. Я обычно ява скриптом писал в дивы или спаны. И кстати нигде этот тег и не встречал. Почему его не используют?
А как тогда ты делал задачи на HTML/CSS, там в нескольких это всё встречается!
Или ты про output?
А ты много смотрел сайтов, на которых инфа сразу вот так выдаётся?
Обычно он для этого и нужен.
Так-то input везде, когда надо и-мейл вводить, ФИО, адрес и прочее, там output и ни к чему.
Мотивация же, не?
Я не тот анон, который спрашивал про взаимодействие хтмл и пхп. И да я про output. Ну хз, 2 года работая в студии, я такого тега ниразу не видел. За этот вечер я хоть что-то новое узнал. Спасибо анон.
Код надо разбивать на функции ради удобочитаемости, чтобы вся программа не шла сплошной стеной. Потому та часть которая создает массив вопросов, вынесена в функцию.
>>678840
Официальный мануал смотрел?
>>678851
Мануал http://php.net/manual/ru/tutorial.php
http://php.net/manual/ru/language.basic-syntax.php
>>678920
Это тег HTML5, плохо что не знаешь его.
https://www.w3.org/TR/html-markup/elements.html
https://developer.mozilla.org/en-US/docs/Web/HTML/Element
https://w3c.github.io/html/fullindex.html#index-elements
Там еще много тегов вообще-то (ссылки на англ)
Хорошо, но почему я обычно вижу под формой какой нибудь span с id="test" и ява скрипт, реагирующий на изменение инпута, вместо output Я вижу различие только в тегах. Семантика?
В IE не работает, наверное, JSом надёжнее.
Спасибо
Допустим, у меня такой код внутри метода:
if (!$mysqli->query('INSERT INTO table (something) VALUES ("something")) {
throw new Exception('Бля, в снег упал');
}
Есть сработает эксепшн, кто будет делать $mysqli->close(), а? Мне снаружи его не видать.
В комментариях к документации, например, советуют вешать $cnx->close() в __destruct(), иначе память течет.
Ну понятно, просто опять я о таком в первые слышу. Просто на примере сокет сервера, который ждет подключения клиентов и посылает запросы в базу. Так вот мускуль отсоединяется через какое-то время, даже если скрипт не закончил выполнение, и приходится заново подключаться, что тоже некрасиво.
Это нормально. У тебя все равно одно соединение на скрипт и при завершении оно закроется. Если бы было много - имело бы смысл заморочиться.
>>678963
Зависит от ситуации. Совет в общем довольно глупый, так как при автоматической сборке мусора нет гарантий когда будет вызван деструктор. Если тебе надо что-то освобождать лучше делать это явно.
>>678969
> мускуль отсоединяется через какое-то время
Потому что там есть таймаут. Надо сделать скрипт устойчивым к этому и обрабатывать событие разрыва соединения.
Оп, пока ты тут, ты мне сегодня ответишь или попозже? А то я в ожидании.
Напиши что-нибудь интересное для себя, без MySQL. Я начал учить PHP еще в эпоху PHP4. Тогда было популярно в небольших проектах использовать текстовые файлы вместо БД. Сейчас это совсем просто, file_get_contents, file_put_contents.
Не бросай. Разбей задачу на под задачи. Сверстай шаблоны страниц, потом сделай так что бы у тебя просто выводило таблицу с списком по запросу. Потом сделаешь вставку данных с формы.
Да у меня нет проблемы с mysql особо, у меня главное непонимание - что программа состоит из многих файлов, какие-то .php , какие-то .html и каким-то образом они должны взаимодействовать и вообще.
И само условие задачи написано так, что видимо люди, дошедшие до туда уже шарят и в терминах и понимают, я же в полном ступоре.
Короче, смотри сюда.
HTML - это тупо текст с вкраплениями тегов. PHP позволяет интерактивно генерировать теги и текст.
PHP - язык программирования, HTML - не язык программирования, а язык разметки текста.
PHP исполняется на сервере. А HTML-файлы статичны, они вообще не исполняются. Твои PHP файлы должны использовать HTML-шаблоны как съемную кожу, костюм, обличие для данных.
Ты запросил один любой файл, и, если ему нужно, он подтянет другие файлы. Те, которые ты сам запрограммировал. Можно написать программу хоть в одном файле, хоть вперемешку с HTML.
в теории я это понимаю (я сделал все задачи ОПовские на html+css в январе ещё, но на практике я в каком-то параличе.
со стороны смотрюсь как обиженка какая-то, наверное... Видно, проведу ночь в гуглении всего на свете спасибо, что пытаешься объяснить и подбодрить
Ну и успокойся.
Я в свое время понял парадигму ООП только с третьего-четвертого раза, и то, после долгих-долгих размышлений. В целом между попытками постичь ООП прошел целый год, если не два.
Быть тугодумом - норм.
Есть ли для PHP что-то вроде JavaRush, для полных нубов?
учебник ОПа.
>так себе годнота
По описанию на сайте вроде вообще великолепно. Правда, пока не увидел, платно ли это.
>зачем она тебе
Андроид жи есть
там до 10-го уровня бесплатно, потом придётся платить(но не много). Я в своё время тоже прошёл до 10-го, но не срослось и теперь я с вами. Поначалу кажется годно, потом меня не покидало чувство, что автор помешанный и где-то наёбывает своим оптимизмом.
1. Как сабмитить форму, если её обрабатывает ajax функция, а параметра name у ней само собой нет.
2. Как запускать парсер раз в сутки например? Наверняка в этом случае надо использовать cron, но я никак не могу найти описания как с ним работать. Он уже стоит на самом хостинге, как с ним можно взаимодействовать?
Вопросы могут показаться нубскими, они такие и есть, но сейчас для меня это самые важные вещи, и я нигде не могу найти на них ответы, может кто может подсказать, если не сложно?
это в HTML файле, забыл добавить. Просто файлы php работают нормально, а когда в HTML код вставляю, как будто не работают
Потому что сервер не пропускает файлы html через интерпретатор PHP. Если хочешь чтобы код работал, подключай HTML файлы в PHP скрипте через include.
Хм... А как же ОПовская ссылка http://www.phpinfo.su/articles/practice/shablony_v_php.html, где вовсю вставляют php в html?
А ты посмотри как потом эти html файлы используют.
Кстати, там еще есть специальный формат .phtml, это специально для HTML файлов которые используют PHP код, но я думаю лучше обойтись простым html и загружать его инклюдами.
http://ideone.com/NW7mgR тоже переделал по рекомендациям любимых анонов
http://ideone.com/eGEybu палиндром
http://ideone.com/uWTryH изменение номера телефона в нужный формат
http://ideone.com/dD5gD8 поиск и авто замена разных вариаций слова дурак
http://ideone.com/sW56Qy вывод всех встречающихся емейлов в тексте
http://ideone.com/ze39mQ Grammar Nazi поиск ошибок в тексте
http://ideone.com/mamPIM авто замена ошибок найденных в тексте
http://ideone.com/ap17y2 поиск "неумышленных" опечаток
проверьте, пожалуйста
хм, спасибо. Сейчас пойду читать в гугл про include.
>>678142
ОП, спасибо, читаю кинутые тобой доки, в который раз понимая свое неумение гуглить и важность сначала посмотреть на сайте авторов апача/пыха, а не на васянских.
Только я не совсем понимаю:
1) Есть ли какая-нибудь разница между
<VirtualHost _default_:80> и <VirtualHost :80>
Результат работы какой-то одинаковый у обеих.
2) Если :80 или _default_:80 указаны НЕ самым первым виртуальным хостом, но по умолчанию (например, по 127.0.0.1 или белому ip) все равно откроется тот виртуальный хост, что прописан первым, а не этот дефолтный. Какой тогда смысл? Перезагружал, три раза.
3) Я хотел попробовать разместить разные сайты на разных портах (один виртуал хост на 80ом, другой на 81ом), но соснул хуйца. Это из-за того, что 81ый порт не слушается апачем или потому, что он закрыт? Как исправить? Можно ли наоборот вообще запретить апачу и мускулу работать с внешней сетью, будучи доступными только для локалки (типа безопасность тестового сервера)?
если ты ещё тут, анон, то ответь пожалуйста. Я правильно понимаю, что я создаю php файл, и в него путём include включаю html файл и пропускаю(запускаю, инициирую) работу именно .php файла и он в свою очередь показывает и хтмл через этот инклюд?
а в самом html файле в тегах <? php> то, что я пропишу будет работать как раз-таки из-за того, что я инициирую файл .php?
>наоборот вообще запретить
Это как для отдельного vhost'а, так и для всего сервера глобально.
И еще вот: я тестирую и не понимаю, а разница между ServerName и ServerAlias есть какая-нибудь? Попробовал вообще убрать нэйм и вместо него сделать два алиаса - нихуя не поменялось, все как работало, так и работает.
Да, так и работает. Все что указано в include будет так же проходить через PHP интерпретатор как и обычные .php файлы, когда в случае с .html файлами сервер просто отдает клиенту обычную страницу с разметкой.
>>679050
Cпасибо.
вот оно как, оказывается. И так всегда делается с html страницами, что содержат php скрипты?
Во всех нормальных шаблонизаторах используется свой синтаксис для создания логики отображения, поэтому если использовать какой-нибудь Twig, то в таком случае html страницы совсем не будут содержать php скриптов.
Задавай вопросы, что непонятно.
>>678872
В документации по этим продуктам наверно. Возьми и попробуй найти объяснение каждой опции в твоем конфиге для начала.
> нужна задача по сокетам и написанию демона
А ты асинхронщину освоил или начнем с простых вещей? Давай наверно с простых.
Речь ведь о berkley sockets, а не вебсокетах? Все равно надо для начала изучить обычные.
Напиши скачиватель - программу, которая получает URL на вход и скачивает содержимое URL в этот файл по протоколу HTTP. Для облегчения задачи давай пока не будем разбирать HTTP ответ, а просто сохраним все как есть, с заголовками и возможной кодировкой.
Пример использования:
php download.php 'http://example.com/' > response.txt
[1s] Resolving example.com ... 1.2.3.4
[0.2s] Connect to 1.2.3.4:80
[3s] Send request
[12s] Downloading data
Вывод идет в поток ошибок, чтобы не замусоривать сам файл. Не забудь проверяь успешность записи в файл, чтобы при переполнении диска например вывелась ошибка.
Не забудь обрабатывать все возможные ошибки соединения, передачи и записи данных с помощью исключений.
Далее, насчет демона. Тут конечно сложнее, плохо представляю где может быть польза от синхронного демона. Ну давай напишем что ли свой мемкеш. Изучи протокол мемкеша и напиши синхронный (то есть обрабатывающий один запрос за раз) демон, который реализует этот протокол. Необходимо поддерживать такие команды:
SET
ADD
REPLACE
APPEND
PREPEND
GET
GETS
STAT (минимальный набор данных)
FLUSH_ALL
VERSION
Проверь что твой демон работает с каким-ниьудь клиентом мемкеша. Поддержка UDP протокола бьудет плюсом. Грамотно оформи свой код, разбив его на классы.
Далее можно изучать написание АПИ и протоколов (сериализуемый бинарно протокол, поверх JSON-RPC, поверх HTTP) а также асинхронщину.
Задавай вопросы, что непонятно.
>>678872
В документации по этим продуктам наверно. Возьми и попробуй найти объяснение каждой опции в твоем конфиге для начала.
> нужна задача по сокетам и написанию демона
А ты асинхронщину освоил или начнем с простых вещей? Давай наверно с простых.
Речь ведь о berkley sockets, а не вебсокетах? Все равно надо для начала изучить обычные.
Напиши скачиватель - программу, которая получает URL на вход и скачивает содержимое URL в этот файл по протоколу HTTP. Для облегчения задачи давай пока не будем разбирать HTTP ответ, а просто сохраним все как есть, с заголовками и возможной кодировкой.
Пример использования:
php download.php 'http://example.com/' > response.txt
[1s] Resolving example.com ... 1.2.3.4
[0.2s] Connect to 1.2.3.4:80
[3s] Send request
[12s] Downloading data
Вывод идет в поток ошибок, чтобы не замусоривать сам файл. Не забудь проверяь успешность записи в файл, чтобы при переполнении диска например вывелась ошибка.
Не забудь обрабатывать все возможные ошибки соединения, передачи и записи данных с помощью исключений.
Далее, насчет демона. Тут конечно сложнее, плохо представляю где может быть польза от синхронного демона. Ну давай напишем что ли свой мемкеш. Изучи протокол мемкеша и напиши синхронный (то есть обрабатывающий один запрос за раз) демон, который реализует этот протокол. Необходимо поддерживать такие команды:
SET
ADD
REPLACE
APPEND
PREPEND
GET
GETS
STAT (минимальный набор данных)
FLUSH_ALL
VERSION
Проверь что твой демон работает с каким-ниьудь клиентом мемкеша. Поддержка UDP протокола бьудет плюсом. Грамотно оформи свой код, разбив его на классы.
Далее можно изучать написание АПИ и протоколов (сериализуемый бинарно протокол, поверх JSON-RPC, поверх HTTP) а также асинхронщину.
> Есть ли какая-нибудь разница между
> <VirtualHost _default_:80> и <VirtualHost :80>
> The string _default_, which is an alias for *
Написано что default то же самое что звездочка и значит "любой IP кроме определенных в других блоках". Это для фильтрации по IP адресам, например ты можешь сделать один сайт на 127.0.0.1, другой на 127.0.0.2 и тд. Не рекомендую так делать, только запутаешься.
> Если :80 или _default_:80 указаны НЕ самым первым виртуальным хостом, но по умолчанию (например, по 127.0.0.1 или белому ip) все равно откроется тот виртуальный хост, что прописан первым,
Это фильтрация по IP (на которых слушается порт) а не по именам. Имена задаются директивой ServerName и ServerAlias
> Это из-за того, что 81ый порт не слушается апачем или потому, что он закрыт? Как исправить?
Надо указать его еще и в Listen
> Можно ли наоборот вообще запретить апачу и мускулу работать с внешней сетью, будучи доступными только для локалки (типа безопасность тестового сервера)?
Надо слушать порт только на лупбек-интерфейе 127.0.0.1.
http://httpd.apache.org/docs/current/bind.html
> мускулу
Это надо смотреть my.cnf, там есть аналогичное правило.
> https://httpd.apache.org/docs/current/vhosts/name-based.html#alg
Тут вроде не написано что есть разница.
Тут написано что алиас может содержать зведочку https://httpd.apache.org/docs/current/mod/core.html#serveralias
https://httpd.apache.org/docs/current/mod/core.html#servername
Вот почитай еще это и сам попробуй найти отличия.
Спасибо, няша! Вроде бы более-менее разобрался, только теперь я не совсем понимаю,
>Надо слушать порт только на лупбек-интерфейе 127.0.0.1.
а по ссылке так вообще какой-то ужас: 192.0.2.1
Это что, это как вообще? Ну, я понимаю, слушать разные порты локалхоста, например 80 и 8000, но как апач может слушать какой-то посторонний для него совершенно ip-адрес?
И да, Listen - это же глобальное правило, а если я хочу, чтобы один вхост был доступен из локалки и из сети, а другой только из локалки, например?
>>679071
И за это спасибо, сейчас буду курить.
Пасты в помощь
- Архитектура серверов https://gist.github.com/codedokode/ffd520440a970c07c1c6
- куски диалога про сокеты https://gist.github.com/codedokode/21a432321fe7bc435dab
http://pastebin.ru/dnO7PZfq
http://pastebin.ru/KO4E1mB4
> а если я хочу, чтобы один вхост был доступен из локалки
Тогда в виртуалхост пропиши IP локального интерфйеса.
>>679077
В компьютере несколько сетевых интерфейсов. Они идентифицируютcя по IP, набери ipconfig в виндоуз и увидишь список.
Как минимум там будет интерфейс сетевой карты с реальным IP, внутренний лупбек интерфейс с адресами 127.x.x.x. Если у тебя есть например вайфай, у карточки тоже будет свой интерфейс со своим IP.
Соотетственно ты указываешь на каком интерфейсе слушать порт (или на всех).
http://xgu.ru/wiki/Сетевой_интерфейс
http://citforum.ru/operating_systems/linux/HOWTO/mini/IP-Subnetworking/x51.shtml
http://pastebin.ru/KO4E1mB4
https://ru.wikipedia.org/wiki/Loopback#.D0.92.D0.B8.D1.80.D1.82.D1.83.D0.B0.D0.BB.D1.8C.D0.BD.D1.8B.D0.B9_.D1.81.D0.B5.D1.82.D0.B5.D0.B2.D0.BE.D0.B9_.D0.B8.D0.BD.D1.82.D0.B5.D1.80.D1.84.D0.B5.D0.B9.D1.81
Как правило если у компьютера боьше одной сетевой карты, то они имеют разные IP и подключены к разным сетям. Правила маршрутизации на компьютере определяют как выбирается интерфейс для отправки пакетов и разрешена ли пересылка пактов с одной сети в другую (в этом случае узел является маршрутизатором). При маршрутизации узел также может осуществлять трансляцию адресов - NAT. Например, роутер одним интерфейсом находится в сети провайдера, а другим -в домашней сети и натит пакеты из домашней сети в провайдерскую (а тот натит их из своей сети в интернет).
>Тогда в виртуалхост пропиши IP локального интерфйеса.
Куда именно? В сам <>? Если да, то смешение нэйм и ип-бэйсед вызывает какие-то тупняки
>у карточки тоже будет свой интерфейс со своим IP.
Это которые 192.168.х.х - локальная сеть?
По поводу ServerName и ServerAlias, я так понял, второй разрешает юзать ? и *, а первый определяет главное имя, например, для сертификатов HTTPS.
Это древняя форма форумов, работающая поверх электронной почты.
https://www.debian.org/MailingLists/index.ru.html
Подписываешься (отправкой письма) и начинаешь получать все письма из этого списка, можешь отвечать на них (если конечно сервер это позволяет).
Также есть похожая система под названием newsgroups. Вот например группы новостей php http://news.php.net/php.general
Ну то есть основная функция списка рассылки - это пересылка входящих писем всем участинкам. То есть там обычно есть такие функции:
- подписка (присылаешь письмо с определенным текстом и тебя добавляют в список)
- отписка (аналогично)
- пересылка (любой участник направляет письмо в список рассылки и оно пересылается всем)
Это как видишь довольно простые алгоритмы, потому списки рассылки были еще до интернет-сайтов. Также почта имеет то преимущество что она накапливается даже если пользователь не в сети, и с ней можно работать оффлайн.
Более продвинутые программы делали также дайджесты - вместо пересылки писем всех подряд как-то их группировали и рассылали например дайджест за сутки.
Ну и смежная технология - это newsgroups, там есть сервер, хранящий сообщения, клиент может подсоединяться и скачивать их или писать новые.
Это все еще было до сайтов, вы, молодежь, наверно и не слышали про это. А ведь интернет существует с 80-х годов (а первый браузер вышел в 1990). Была почта (причем в те времена были еще и так называемые релеи - для передачи почты в закрытые сети или для передачи через нестабильные каналы), был FTP, незащищенный telnet, и куча уже умерших протоколов.
Ну и вообще раньше у многих людей не было постоянного доступа в сеть. Например, были модемы, которые передавали данные при помощи звука по телефонной сети. Предельная скорость была 56 кбит/с на заре эпохи и это в иделальных условиях, то есть чуть реже чем никогда. У первых модемов вообще было что-то в районе 300 бит/с. Cоединение могло рваться. Сам интернет был дорогущий, с оплатой поминутно, платить надо было и за телефон и провайдеру. Ночью было дешевле.
Ну наконец были еще какие-то ограниченные виды интернета, когда тебе давали не прямое соединение с сетью, а доступ в командную строку на линукс-сервере с соединением к интернету (в учебных заведениях например).
Какие форумы? Только почта и группы новостей и работали в таких условиях. Соединился, скачал письма, отсоединился, читаешь, пишешь ехидные комментарии (я впрочем никогда модемом не пользовался,хотя один из них есть в моем ноутбуке).
1. Делаю задачку про студентов, еще много чего надо сделать, пока что вожусь с бд, а потом хочу подключить куки, htmlspecials и прочее.
Так вот, имеется страничка регистрации, там пользователь вводит данные, если все ок, то должна выполнится функция с сохранением в бд и переадресация на страницу с поздравлениями.
Вот только в бд почему-то не сохраняет, а только переадресовывает. Почему так? Никаких ошибок не выдает, ничего не пишет, почему, понять не могу.
Класс бд: https://github.com/luptidu/students.com/blob/master/components/Database.php
Та самая функция которая ничего не записывает, а должна:
https://github.com/luptidu/students.com/blob/master/models/Student.php#L32
Это главный вопрос.
И еще вопросы в данный момент менее важные:
2. Когда использоваться include, а когда include_once, как работает я знаю, но не могу понять в каких ситуациях первая функция может вызвать проблемы? То же самое и c require и require_once. Да и зачем вообще нужна require, если везде можно юзать инклюд? По идее
3. Можно ли в свойствах класс модели создать переменную дб и уже юзать ее в функциях и не писать в каждой функции одну и ту же строчку кода? Хотя что-то мне подсказывает, что типо так не делают, потому что даже при использовании функции где не используется бд все равно придется слать запрос к бд, что уменьшает скорость обработки
4. Я немного не понимаю суть ООП в плане, почему не сделать все функции статическими и выполнять их без создания обьекта. Можешь привести примеры где нужно будет обязательно создавать обьект и без него никак? Желательно где это обязательно в этой задаче
5. Зачем нужно постоянно импортировать бд или создавать вручную если хочешь потестить чей-то сайт? Почему бы не написать просто код который проверяет наличие бд и таблиц и если они отсутствуют, то просто создает их.
6. Также почему когда люди выкладывают свой сайт на тест, то выкладывают его без фреймворка и его тоже нужно устанавливать руками? Ведь можно просто скинуть папочку с фреймворком и не париться.
1. Делаю задачку про студентов, еще много чего надо сделать, пока что вожусь с бд, а потом хочу подключить куки, htmlspecials и прочее.
Так вот, имеется страничка регистрации, там пользователь вводит данные, если все ок, то должна выполнится функция с сохранением в бд и переадресация на страницу с поздравлениями.
Вот только в бд почему-то не сохраняет, а только переадресовывает. Почему так? Никаких ошибок не выдает, ничего не пишет, почему, понять не могу.
Класс бд: https://github.com/luptidu/students.com/blob/master/components/Database.php
Та самая функция которая ничего не записывает, а должна:
https://github.com/luptidu/students.com/blob/master/models/Student.php#L32
Это главный вопрос.
И еще вопросы в данный момент менее важные:
2. Когда использоваться include, а когда include_once, как работает я знаю, но не могу понять в каких ситуациях первая функция может вызвать проблемы? То же самое и c require и require_once. Да и зачем вообще нужна require, если везде можно юзать инклюд? По идее
3. Можно ли в свойствах класс модели создать переменную дб и уже юзать ее в функциях и не писать в каждой функции одну и ту же строчку кода? Хотя что-то мне подсказывает, что типо так не делают, потому что даже при использовании функции где не используется бд все равно придется слать запрос к бд, что уменьшает скорость обработки
4. Я немного не понимаю суть ООП в плане, почему не сделать все функции статическими и выполнять их без создания обьекта. Можешь привести примеры где нужно будет обязательно создавать обьект и без него никак? Желательно где это обязательно в этой задаче
5. Зачем нужно постоянно импортировать бд или создавать вручную если хочешь потестить чей-то сайт? Почему бы не написать просто код который проверяет наличие бд и таблиц и если они отсутствуют, то просто создает их.
6. Также почему когда люди выкладывают свой сайт на тест, то выкладывают его без фреймворка и его тоже нужно устанавливать руками? Ведь можно просто скинуть папочку с фреймворком и не париться.
upd:
Разобрался, оказывается забыл скобочку в sql запросе поставить.
Все заработало.
Но новая проблема и раз уж я здесь, то спрошу.
А все остальное заработало, раз уж я здесь, то спрошу.
Получил вот такое, почему кириллица так изуродовалась? При создании таблицы указал кодировку utf8_general_ci.
Что еще нужно было сделать?
https://github.com/foobar1643/student-list
> function runApp($app) {
>Тайп хинт бы сюда.
Какой тайпхинт? В эту функцию я передаю несколько контроллеров, чтобы удобнее было ловить исключение. Я могу конечно сделать для этих контроллеров интерфейс, а потом сделать тайпхинт на этот интерфейс, но не будет ли это усложнением?
>> } catch(PDOException $e) {
> } catch(FatalException $e) {
>Хотелось бы комментарий чем исключение этого типа отличается от других
>Почему тут только эти 2 исключения ловятся? Как ты составил список этих исключений, по каким принципам? Что делать с исключениями других классов?
Чтобы не копипастить catch блоки с одинаковым содержимым я сделал для двух исключений один интерфейс FatalException и ловлю его. Других исключений, кроме PDOException там быть не может, но если вдруг они будут, можно будет добавить еще один блок catch. Если можно это как-нибудь по другому сделать, подскажи пожалуйста.
>По идее ссылки надо экранировать через htmlspecialchars, в частности символ & в них
Вот это тоже не совсем понял, но все равно сделал. Это из-за того что символ & может сломать разметку?
Искренне, дай б-г тебе здоровья
ОП, я не понял как скачивать содержимое страницы, file_get_contents? Я имел ввиду запуск сокет сервера (для его работы же нужен демон?) и запуск сокет клиента на ява скрипте. А ты о чем? Про мемкеш тоже не понял, что за команды. Ты наверное переоценил мои возможности, или же мы друг друга не поняли.
SELECT
`visits`.timeIn,
`visits`.timeOut,
`visits`.date,
CONCAT_WS(' ',`visits`.date, `visits`.timeIn) AS datetimeIn,
CONCAT_WS(' ',`visits`.date, `visits`.timeOut) AS datetimeOut,
TIMEDIFF(datetimeIn, datetimeOut) AS DiffDate
FROM `visits`
WHERE `territory` = '1'
AND `date` = '2016-03-07'
Ошибка Unknown column 'datetimeIn' in 'field list'
Неужели так нельзя?
Да тут дело в том, что все васянские движки сейчас-то бросают кучи заглушаемых DEPRECATED и STRICT, а на 7 версии вообще работать не будут.
Только вот ни в мануале о них ничего, ни в самой задаче. Есть только str_pad, которая работает по другому принципу. В чём подвох?
Хз, как мне кажется, тебе должны предоставить макет сайта. Т.е., сначала должен поработать дизайнер в фотошопе, нарисовать всю хуйню, а тебе прийти файл psd, с которым у тебя уже будет половая жизнь.
Не пойму, куда у меня внешний ключ пропал в дампе базы?
Я просто ползаю по другим сайтам, беру от туда фишечки, подбираю 2-3 основных цвета и от этого прыгаю дальше.
Это правильно, но у меня не получается рисовать дизайны, да и не хочу я это делать если честно, я хочу заниматься именно веб-программированием, ну и вёрсткой ещё если это нужно, и это более менее получается, но рисование макетов у меня просто не получается.
Это я уже делал, но когда в задании стоит создать сайт на вордпресс, необходим хороший дизайн
Что-то ты лишнего там наподключал. Если ты установливал фреймворк через композер, то второй строчки достаточно. Удаляй 3ю и 4ю строки.
Я еще один пример hello world'а нашел, там так было. А если с new \Slim\Slim() такая же проблема.
Ебать ШГ
Странно, автозагрузчик не работает почему-то. Попробуй require "/vendor.autoload.php" или require __DIR__."/vendor/autoload.php", хотя вряд ли дело в этом, раз 2я строчка подключается без ошибок
Немного прояснилось. Там документация на слим2, у меня слим 3.2. Хэлло ворлд для новой версии тут http://www.slimframework.com/docs/. И он опять же не работает, лол. А вообще с какой версией лучше работать? Начал файлообменник из шапки.
Так ты заходи по адресу /hello/name у тебя же для него только маршрут в коде определен.
Если у тебя file-sharing это корневая директория, то зачем ты пишешь её в коде роутера?
Вообщем попробую 2.x версию поставить, посмотрел у других анонов файлообменники, там 2.x версии. Там и информации на русском больше по ней в рунете.
Подожди, ответь на вопросы выше. Зачем в роутере $app->get
file-sharing? Убери его оттуда и проверь работоспособность.
Убирал, результат такой же.
Блин, затупил, да.
Не обязательно.
http://ideone.com/WFlK6J
Банкомат все осилили или я тут один такой туповатый?
Ну кидай скриншот, откуда мне знать. Каждый раз когда я говорю тебе пофиксить что-то, ты трогаешь в коде что-нибудь еще.
Бамп
Есть еще такой вариант http://ideone.com/9sAV08 но он на некоторых вариантах впадает в ступор. Хотя в массиве $minBanknotes путь для решения есть.
К примеру если задать
$amount = 66;
$banknotes = array (
2 => 3,
5 => 1,
20 => 4,
50 => 1
);
Если начать поиск ответа с 20 отработает правильно, но как это рассчитать, непонятно
> не число, а комбинацию, такого вида:
> F(100) = { 2 3 0 0 }
Поскольку F определяется рекуррентно то уже при числах порядка 50000 уходит ОООЧЕНЬ много времени.
В Задаче о размене конкретно прописано http://goo.gl/uOz8AQ
Каждый предмет может быть выбран любое число раз. Задача выбрать количество предметов каждого типа так, чтобы минимизировать количество взятых предметов.
Так что этот алгоритм для решения задачи про банкомат с ограничением банкнот не подходит.
У меня появилась теория, что мой .htaccess просто не работает. Ведь если я добавлю в него строку This is garbage line будет ошибка 500, так? Ничего не происходит при любых рандомных строках в нем.
*503
ОП, я написал.
https://ide.c9.io/fxsloker/test
Решил сделать в разрекламированной cloude ide в прошлом треде. Вроде права паблик, не знаю откроется ли у тебя. Мне понравилось, работает быстро, да и ты можешь легко протестить мой скрипт, найти баги.
Аноны, проверьте тоже, пока ОПа нет, можете ли вы просматривать мой проект?
Залогинься с гитхаба. Тут все равно ОПу гитхаб потом показывают.
ОП, по поводу мемкеша. Я не совсем понимаю как я с терминала буду взаимодействовать с пхп скриптом. А так я погуглил, даже попользовался мемкешом, интересная вещь. И вообще с чего начать?
Вернее не так сказал, как я с терминала буду подавать сигналы демону? Я умею пока только в такие ./daemon start|stop etc, использующие стандартный набор функций в библиотеки в линуксе. Мне надо что-то свое на баше писать?
1) Как в регекспе вставить "перенос строки", "табуляция" и подобные символы как часть паттерна?
2) Если я как-то участвую в чужих проектах на гитхабе, предлагаю патчи, например, создаю тикеты - это все где-то отмечается в статистике и можно будет потом посмотреть или как-то вообще в истории остается? Ну, например, для работодателя. Да и вообще приятно знать, что вот, приложил руку.
У тебя в профиле вся история твоих контрибов и собственных проектов отображается. Даже статистику ведет по дням.
Не справляюсь же, потому и очередь. Спасибо тем анонам кто помогает новичкам в очередной раз решить задачу про айфон.
>>679274
Видимо в TIMEDIFF там нельзя использовать алиасы. Алсо, я не понимаю зачем ты дату и время разбил отдельно (и нарушил принципы нормализации). Без этого было бы проще.
>>679357
Их надо написать самому. Если ты дошел до последнйе главы это не должно быть проблемой.
str_pad не умеет правильно считать символы, она считает байты, потому не годится.
>>679425
Можно купить тему причем уже с версткой - гугли template monster. Можно даже найти бесплатную. Но их скорее всего придется доделывать, они обычно плохие.
Также, можно "скопировать" дизайн с других сайтов. Если не копировать один в один, это не будет нарушением авторского права.
Можно заказать у знакомого дизайнера (а он может тебе подкидвыать заказы на программирование).
И часто дизайн уже есть.
>>679461
Зачем ты пишешь require Slim? Во-первых такой папки рядом с index.php там все равно нет (ты бы хоть путь проверил), во вторых композер берет автозагрузку на себя и вручную инклдить слим не надо.
Алсо почитай мой урок на гитхабе про автозагрузку и PSR-4 и выучи наизусть. я вижу у тебя тут пробелы.
Также можешь найти файл vendor/autoload.php и изучить его внимательно. Пусть это будет тебе домашним заданием, разобраться как он работает.
>>679475
Тогда купи готовый.
>>679493
В первом случае запускаеся Слим и выводит 404 так как нет обработчика для главной.
Во втором случае надо смотреть что у тебя за веб-срвер и как он настроен. По надписи "phpstorm" я этого понять не могу, узнай какой веб сервер исплоьзуется и как он настроен (в документации на пхпшторм).
Не справляюсь же, потому и очередь. Спасибо тем анонам кто помогает новичкам в очередной раз решить задачу про айфон.
>>679274
Видимо в TIMEDIFF там нельзя использовать алиасы. Алсо, я не понимаю зачем ты дату и время разбил отдельно (и нарушил принципы нормализации). Без этого было бы проще.
>>679357
Их надо написать самому. Если ты дошел до последнйе главы это не должно быть проблемой.
str_pad не умеет правильно считать символы, она считает байты, потому не годится.
>>679425
Можно купить тему причем уже с версткой - гугли template monster. Можно даже найти бесплатную. Но их скорее всего придется доделывать, они обычно плохие.
Также, можно "скопировать" дизайн с других сайтов. Если не копировать один в один, это не будет нарушением авторского права.
Можно заказать у знакомого дизайнера (а он может тебе подкидвыать заказы на программирование).
И часто дизайн уже есть.
>>679461
Зачем ты пишешь require Slim? Во-первых такой папки рядом с index.php там все равно нет (ты бы хоть путь проверил), во вторых композер берет автозагрузку на себя и вручную инклдить слим не надо.
Алсо почитай мой урок на гитхабе про автозагрузку и PSR-4 и выучи наизусть. я вижу у тебя тут пробелы.
Также можешь найти файл vendor/autoload.php и изучить его внимательно. Пусть это будет тебе домашним заданием, разобраться как он работает.
>>679475
Тогда купи готовый.
>>679493
В первом случае запускаеся Слим и выводит 404 так как нет обработчика для главной.
Во втором случае надо смотреть что у тебя за веб-срвер и как он настроен. По надписи "phpstorm" я этого понять не могу, узнай какой веб сервер исплоьзуется и как он настроен (в документации на пхпшторм).
Смотря насколько у тебя хайлоад и какие задачи.
>>679555
Не советую. Бери лучше новую. Плюс это будет хорошая практика по освоению незнакомого фреймворка.
Для начала разберись как работает сервер в phpstorm.
>>679822
Да, разберись что там за сервер используется.
>>679868
Ты дал не совсем тот УРЛ - ты дал ссылку на ИДЕ, где требуется логин, а надо дать ссылку вроде
https://c9.io/codedokode/foobar1643-student
(по ней можно посмотреть описание проекта и файлы но нельзя зайти на сайт)
либо, если у тебя сайт, то ссылку вида
https://foobar1643-student-codedokode.c9users.io/
(она появляется в консоли после того как ты выберешь run with - apache )
Если ты даешь вторую ссылку то сайт будет доступен только пока у тебя открыта ИДЕ.
Так что твоя ссылка могла бы выглядеть как https://test-fxsloker.c9users.io/
Но если у тебя скрипт для командной строки то проще наверно давать ссылку на гитхаб - склонировать с гитхаба на cloud9 это дело одной минуты.
> "GET ".$this->host."
Там указывается не хост, а только путь - почитай про HTTP. Полный URL указывается только если это прокси.
> User-Agent: Mozilla/5.0
Что ж ты скромничаешь, вписал бы имя своего скрипта
> or die("Can't open file");
В ООП надо использовать исключения
fwrite и fclose тоже могут выдавать ошибки
> socket_write($socket, $headers, strlen($headers)
Ты думаешь что одного пакета достаточно для отправки запроса - это не обязательно так. socket_write не гарантирует что он отправит все данные за раз.
> while($read = socket_read($socket, 1024)) {
А что если вернется строка "0"?
> catch(Exception $er) {
> print(sprintf("Eror gett
Ты не понимаешь идею исключений
Ну и я думаю, лучше сделать запись потоково. Что если в ответ дадут 100 Мб файл? Лучше не писать его в память, а потоково записывать в файл.
И я тут подумал, в целях лучшего изучения HTTP давай сделаем вторую версию скачивателя. Пусть она сохраняет в файл только тело ответа. Заголовки пусть выводит в поток ошибок. Она должна поддерживать передачу gzip файлов и transfer-encoding: chunked.
Насчет задачи на мемкеш, можно ее упростить, подумай сам, например можно часть команд убрать, хотя мне кажется там не очень и сложно.
По поводу вебсокетов. Тут путь изучения такой:
устройство интернета, IP, DNS -> TCP/IP, сокеты, порты -> HTTP -> вебсокеты -> { протоколы поверх веб-сокетов вроде WAMP, также почитать про JSON-RPC, асинхронное программирование на PHP }
Ты сейчас на шаге "TCP/IP и сокеты".
Смотря насколько у тебя хайлоад и какие задачи.
>>679555
Не советую. Бери лучше новую. Плюс это будет хорошая практика по освоению незнакомого фреймворка.
Для начала разберись как работает сервер в phpstorm.
>>679822
Да, разберись что там за сервер используется.
>>679868
Ты дал не совсем тот УРЛ - ты дал ссылку на ИДЕ, где требуется логин, а надо дать ссылку вроде
https://c9.io/codedokode/foobar1643-student
(по ней можно посмотреть описание проекта и файлы но нельзя зайти на сайт)
либо, если у тебя сайт, то ссылку вида
https://foobar1643-student-codedokode.c9users.io/
(она появляется в консоли после того как ты выберешь run with - apache )
Если ты даешь вторую ссылку то сайт будет доступен только пока у тебя открыта ИДЕ.
Так что твоя ссылка могла бы выглядеть как https://test-fxsloker.c9users.io/
Но если у тебя скрипт для командной строки то проще наверно давать ссылку на гитхаб - склонировать с гитхаба на cloud9 это дело одной минуты.
> "GET ".$this->host."
Там указывается не хост, а только путь - почитай про HTTP. Полный URL указывается только если это прокси.
> User-Agent: Mozilla/5.0
Что ж ты скромничаешь, вписал бы имя своего скрипта
> or die("Can't open file");
В ООП надо использовать исключения
fwrite и fclose тоже могут выдавать ошибки
> socket_write($socket, $headers, strlen($headers)
Ты думаешь что одного пакета достаточно для отправки запроса - это не обязательно так. socket_write не гарантирует что он отправит все данные за раз.
> while($read = socket_read($socket, 1024)) {
А что если вернется строка "0"?
> catch(Exception $er) {
> print(sprintf("Eror gett
Ты не понимаешь идею исключений
Ну и я думаю, лучше сделать запись потоково. Что если в ответ дадут 100 Мб файл? Лучше не писать его в память, а потоково записывать в файл.
И я тут подумал, в целях лучшего изучения HTTP давай сделаем вторую версию скачивателя. Пусть она сохраняет в файл только тело ответа. Заголовки пусть выводит в поток ошибок. Она должна поддерживать передачу gzip файлов и transfer-encoding: chunked.
Насчет задачи на мемкеш, можно ее упростить, подумай сам, например можно часть команд убрать, хотя мне кажется там не очень и сложно.
По поводу вебсокетов. Тут путь изучения такой:
устройство интернета, IP, DNS -> TCP/IP, сокеты, порты -> HTTP -> вебсокеты -> { протоколы поверх веб-сокетов вроде WAMP, также почитать про JSON-RPC, асинхронное программирование на PHP }
Ты сейчас на шаге "TCP/IP и сокеты".
А это? http://c9.io/fxsloker/test открывается? Там правда все равно ничего интереного нет.
Лучше бы анон конечно кд на гитхаб выложил (кстати с c9 можно пушить и пуллить с гитхаба).
>>679997
Либо учись либо ищи работу джуниором и набирай опыт.
>>680024
Чтобы тестировать приложение тебе нужен TCP клиент которым можно соединиться с указанным портом и пересылать данные.
Под линуксом: ставь netcat и socat (почитав мануал ты удивишься что она умеет)
Эти же программу умеют быть TCP сервером и позволяют тестировать клиенты или даже руками отдать страничку в браузер.
Под виндоус такие варианты:
telnet example.com 80 - хотя телнет и не является чистым TCP клиетом. но если не передавать спецсимволы то протокол телнета это фактически передача данных как есть. Попроьуй сделать например
telnet ya.ru 80 < request.txt
Скачать putty/kitty - это SSH клиент но если выбрать режим raw то он просто передает данные как есть.
Если тебе нужно тестировать SSL/HTTPS (передау данных с шифрованием), скачай openssl и исплоьзуй команду
openssl s_client -connect ya.ru 443 < request.txt
А это? http://c9.io/fxsloker/test открывается? Там правда все равно ничего интереного нет.
Лучше бы анон конечно кд на гитхаб выложил (кстати с c9 можно пушить и пуллить с гитхаба).
>>679997
Либо учись либо ищи работу джуниором и набирай опыт.
>>680024
Чтобы тестировать приложение тебе нужен TCP клиент которым можно соединиться с указанным портом и пересылать данные.
Под линуксом: ставь netcat и socat (почитав мануал ты удивишься что она умеет)
Эти же программу умеют быть TCP сервером и позволяют тестировать клиенты или даже руками отдать страничку в браузер.
Под виндоус такие варианты:
telnet example.com 80 - хотя телнет и не является чистым TCP клиетом. но если не передавать спецсимволы то протокол телнета это фактически передача данных как есть. Попроьуй сделать например
telnet ya.ru 80 < request.txt
Скачать putty/kitty - это SSH клиент но если выбрать режим raw то он просто передает данные как есть.
Если тебе нужно тестировать SSL/HTTPS (передау данных с шифрованием), скачай openssl и исплоьзуй команду
openssl s_client -connect ya.ru 443 < request.txt
О! Ты идешь прямо на грабли и хочешь придумать очередной велосипед.
Обвязку которая "демонизирует" твой процесс писать не надо. Пиши обычную программу которая запускается, слушает порт и обрабатывает запросы. А чтобы сделать из нее полноценного демона, используй программу-супервизор. Почитай про:
xinetd - самый простой демонизатор
supervisord
runit
systemd (да он для этого годится)
Также сделай обзор программ упомянутых тут https://en.wikipedia.org/wiki/Process_supervision
Напиши какая лучше подходит для твоих целей и почему.
Также, неплохо бы научиться реагировать на сигналы вроде SIGTERM.
Я видел случаи когда люди пытались на PHP написать демона целиком - кривой код с кучей ошибок. Не стоит идти по этому пути.
также прочитай тут ответ
http://stackoverflow.com/questions/3095566/linux-daemonize/3095624#3095624
https://www.digitalocean.com/community/tutorials/how-to-configure-a-linux-service-to-start-automatically-after-a-crash-or-reboot-part-1-practical-examples
https://www.digitalocean.com/community/tutorials/how-to-configure-a-linux-service-to-start-automatically-after-a-crash-or-reboot-part-2-reference
О! Ты идешь прямо на грабли и хочешь придумать очередной велосипед.
Обвязку которая "демонизирует" твой процесс писать не надо. Пиши обычную программу которая запускается, слушает порт и обрабатывает запросы. А чтобы сделать из нее полноценного демона, используй программу-супервизор. Почитай про:
xinetd - самый простой демонизатор
supervisord
runit
systemd (да он для этого годится)
Также сделай обзор программ упомянутых тут https://en.wikipedia.org/wiki/Process_supervision
Напиши какая лучше подходит для твоих целей и почему.
Также, неплохо бы научиться реагировать на сигналы вроде SIGTERM.
Я видел случаи когда люди пытались на PHP написать демона целиком - кривой код с кучей ошибок. Не стоит идти по этому пути.
также прочитай тут ответ
http://stackoverflow.com/questions/3095566/linux-daemonize/3095624#3095624
https://www.digitalocean.com/community/tutorials/how-to-configure-a-linux-service-to-start-automatically-after-a-crash-or-reboot-part-1-practical-examples
https://www.digitalocean.com/community/tutorials/how-to-configure-a-linux-service-to-start-automatically-after-a-crash-or-reboot-part-2-reference
Средства взаимодействия программ называются IPC
https://ru.wikipedia.org/wiki/Межпроцессное_взаимодействие
Вот основные:
- сигналы unix
- unix domain сокеты
- интернет (IP) сокеты
- пайпы
- named пайпы
Обычно исплоьзуют либо сигналы либо упрвление демоном через unix сокет.
1) \n или \t
http://php.net/manual/ru/regexp.reference.escape.php
Также \s включает оба этих символа.
2) в профиле на гитхабе это есть, например https://github.com/codedokode/
SET NAMES наверно. Ты при соединении с mysql не указываешь в какой кодировке передаешь данные.
> При создании таблицы указал кодировку utf8_general_ci.
Это вкакой кодировке они внутри таблицы хранятся. А кодировка соединения это другое дело.
ОП, даю ссылку:
http://stackoverflow.com/questions/7712256/php-socket-read-only-gets-the-first-byte-of-the-stream
Там написано в первом ответе:
I would strongly recommend that you don't use the ancient socket_ functions, but instead the fsockopen and fread instead.
Почему их не стоит использовать, или может он ошибается?
Есть один игровой сервер, запускается и управляется через собственную консоль.
Можно ли с помощью php вбивать в неё команды?
Если нет, то на каком языке это можно это реализовать?
Алсо еще знаю C# немного.
Ну для таких целей в любом случае лучше взять шарп или плюсы. PHP все таки для других целей предназначен.
А как проверять? вот определился победитель в этот день, потом кто-то другой голосует и таскать каждый раз данные из таблицы, проверять временные срок и есть ли в них победители?
>А как проверять?
Что именно? Есть-ли сегодня победитель? Легко
SELECT*FROM winners WHERE data = Сегодняшнее число
спс
Пока реквестирую ваше резюме. Обезличьте плз, мне интересны вот какие моменты:
1) Курсы и вебинары всякие вы записываете в резюме?
2) Книги?
3) Как оформляли портфолио проектов своих?
4) Смотрят ли на качество кода этих проектов?
А резюме в целом нужно для понимания как программист себя представляет на рынке.
Еще дополню этот свой пост предыдущего треда (ну он в шапке /pr висел я в нем и отписывал, кто знал что вечеринка уехала)
Про конструкцию try-catch. В книге, что я купил по мусклю и пхп (Кевин Янк - гуглится легко) эти конструкции повсеместно. Так ли уместно их использование? Я к тому, что ошибка так и так вывалится, а в книге аргумент, мол, ошибку нужноперехватывать.
Хотя в статьях про pdo этот способ описывают как "прилежно-хомячковый" и так лучше не делать.
Спасибо, анончик
мимо-сеошник/верстальщик-переходящий-в-кодеры
Почитай пока мой урок про исключения https://gist.github.com/codedokode/65d43ca5ac95c762bc1a
И паста
### Исключения
Как надо обрабатывать исключения:
- записать информацию в лог
- показать пользователю заглушку
- на заглушке выставить HTTP 503 код ответа для роботов
- на компьютере разработчика (при display_errors = 1) показать подробности и стектрейс
Что будет если использовать catch + echo:
- в лог ничего не фиксируется, ты не узнаешь об ошибках
- пользователь видит непонятную белиберду на английском
- отдается код 200
Как будет если просто не ловить исключение:
- информация пишется в лог (ок)
- на компьютере разработчика выводятся подробности (ок)
- пользователь видит белую страницу (не ок)
- отдается код 200 (не ок)
Почитай также урок https://gist.github.com/codedokode/65d43ca5ac95c762bc1a
### Исключения 2
Давай начнем с теории. Знаешь ли ты зачем придуманы исключения? Читал ли урок https://gist.github.com/codedokode/65d43ca5ac95c762bc1a
Если нет, прочитай.
До исключений мы должны были после каждой функции писать иф и проверять ее результат, не было ли ошибки. Исключения позволили отказаться от этого. Так как исключение автоматически выходит из вложенных вызовов функций наверх, нам достаточно одного-единственного обработчика исключений на самом верху:
try {
$app->run();
} catch (..) {
$app->showErrorPage();
}
Более того, мы можем и этого не делать, так как пхп сам ловит непойманные исключения, логгирует их, выводит пустую страницу в браузер и завершает скрипт.
Ловить исключения где-то еще надо если у нас есть способ обработать их. Ну например мы можем ловить ошибку соединения с удаленным сервером чтобы сделать еще несколько попыток. Очевидно что в этом случае мы ловим не все подряд, а конкретное исключение, отвечающее за ошибку соединения с сервером.
Почитай пока мой урок про исключения https://gist.github.com/codedokode/65d43ca5ac95c762bc1a
И паста
### Исключения
Как надо обрабатывать исключения:
- записать информацию в лог
- показать пользователю заглушку
- на заглушке выставить HTTP 503 код ответа для роботов
- на компьютере разработчика (при display_errors = 1) показать подробности и стектрейс
Что будет если использовать catch + echo:
- в лог ничего не фиксируется, ты не узнаешь об ошибках
- пользователь видит непонятную белиберду на английском
- отдается код 200
Как будет если просто не ловить исключение:
- информация пишется в лог (ок)
- на компьютере разработчика выводятся подробности (ок)
- пользователь видит белую страницу (не ок)
- отдается код 200 (не ок)
Почитай также урок https://gist.github.com/codedokode/65d43ca5ac95c762bc1a
### Исключения 2
Давай начнем с теории. Знаешь ли ты зачем придуманы исключения? Читал ли урок https://gist.github.com/codedokode/65d43ca5ac95c762bc1a
Если нет, прочитай.
До исключений мы должны были после каждой функции писать иф и проверять ее результат, не было ли ошибки. Исключения позволили отказаться от этого. Так как исключение автоматически выходит из вложенных вызовов функций наверх, нам достаточно одного-единственного обработчика исключений на самом верху:
try {
$app->run();
} catch (..) {
$app->showErrorPage();
}
Более того, мы можем и этого не делать, так как пхп сам ловит непойманные исключения, логгирует их, выводит пустую страницу в браузер и завершает скрипт.
Ловить исключения где-то еще надо если у нас есть способ обработать их. Ну например мы можем ловить ошибку соединения с удаленным сервером чтобы сделать еще несколько попыток. Очевидно что в этом случае мы ловим не все подряд, а конкретное исключение, отвечающее за ошибку соединения с сервером.
ну модх вполне гибкая система, на ней можно что угодно построить и без костылей,
ну а вордпресс надо допиливать под нужны, если они чуть отходят от стандартного функционала или сразу искать тему с нужными тебе функциями.
поэтому исходить здесь тебе следует только от того, с чем тебе удобнее будет работать
> Ты не понимаешь идею исключений
Ну а что не так? Без try catch пишет непойманное исключение.
> Ты думаешь что одного пакета достаточно для отправки запроса - это не обязательно так. socket_write не гарантирует что он отправит все данные за раз.
Поправил.
> Там указывается не хост, а только путь - почитай про HTTP. Полный URL указывается только если это прокси.
Поправил.
> Что ж ты скромничаешь, вписал бы имя своего скрипта
ОП, давай разъясняться понятнее, пожалуйста. Я не совсем понимаю.
> fwrite и fclose тоже могут выдавать ошибки
Поправил.
> Ну и я думаю, лучше сделать запись потоково. Что если в ответ дадут 100 Мб файл? Лучше не писать его в память, а потоково записывать в файл.
Где почитать? Я правда сейчас еще погуглю и напишу что-нибудь.
ух, от половины учебника голова лопается, а тут еще сколько инфы, спасибо ОП, добра
Анон. Помоги.
Fatal error: Call to a member function fetch() on boolean in C:\OpenServer\domains\localhost\studList\models\Student.php on line 19
http://ideone.com/P7CvSt
Не смотрите, что говнокод страшный, в дальнейшем запрос будет записываться в массив объекты типа student.
Тебе ж английским языком написано - вызываешь метод fetch() у переменной-буля, а не объекта.
А у тебя написано studets в $db->query.
Я все таки считаю у него возвращается попросту FALSE из-за studets вместо students.
http://ideone.com/8msxR4
Только не надо код кидать. Алгоритм помогите понять.
Я правльно понимаю, что надо сперва введенную сумму разделить по модулю на самый крупный номинал, потом мельче мельче и т.д.?
этого. не можыд. быт
Нет, твой алгоритм — ленивый, и не будет работать в некоторых случаях правильно. Решений задачи по всему гуглу миллион, она довольно классическая.
> ленивый
Ой, блядь, жадный. Хотя, доля правды там есть, потому что программисту «лень» пердолиться с графом вариантов выдачи купюр и так далее.
Если функция работы с базой возвращает false значит произошла какая-то ошибка. Ты не написал что исплоьзуешь?
PDO - надо включить режим выброса исключений при ошибке
mysqli - надо проверять результат каждой операции на ошибку как описано в мануале
В любом случае ты поступил неправильно. Ты не изучил мануал, не прочитал про обработку ошибок, а спешишь писать код. Не включил вывод информации об ошибках и ждешь что аноны телепатически залезут в твой компьютер и поймут причины.
Если учебник по которому ты учился не упоминает это - выкинь его и найди что-нибудь получше. Это вещь которую надо изучать в первую очередь.
Алсо покажи потом код на проверку. Я сразу скажу что тут будут советы по каждой второй строчке, и совет за статические методы.
Я не хочу гуглить. Я хочу понять. Поясни плиз.
Включил отображение ошибок. Вылетело.
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42S02]: Base table or view not found: 1146 Table 'students.studets' doesn't exist' in C:\OpenServer\domains\localhost\studList\models\Student.php:15 Stack trace: #0 C:\OpenServer\domains\localhost\studList\models\Student.php(15): PDO->query('SELECT * FROM s...') #1 C:\OpenServer\domains\localhost\studList\controllers\StudentController.php(13): Student::getStudentList() #2 [internal function]: StudentController->actionList() #3 C:\OpenServer\domains\localhost\studList\components\Router.php(101): call_user_func_array(Array, Array) #4 C:\OpenServer\domains\localhost\studList\index.php(37): Router->run() #5 {main} thrown in C:\OpenServer\domains\localhost\studList\models\Student.php on line 15
Спасибо анон, ну я и ТУГОЙ. Как так вообще можно.
сотни нефтей тебе.
error_reporting(-1);
function HomoCredit($creditSum, $payout){
$totalPayout =0;
for(;;){
$creditSum = ($creditSum1.04)+500;
if ($creditSum<=5000) {
$totalPayout = $totalPayout + $creditSum;
break;
}
$totalPayout = $totalPayout + $payout;
}
return $totalPayout;
}
function Softbank($creditSum, $payout){
$totalPayout =0;
for(;;){
$creditSum = ($creditSum1.03)+1000;
if ($creditSum<=5000) {
$totalPayout = $totalPayout + $creditSum;
break;
}
$totalPayout = $totalPayout + $payout;
}
return $totalPayout;
}
function StrawberryBank ($creditSum, $payout){
$totalPayout =0;
for(;;){
$creditSum = ($creditSum*1.02);
if ($creditSum<=5000) {
$totalPayout = $totalPayout + $creditSum + 7777;
break;
}
$totalPayout = $totalPayout + $payout;
}
return $totalPayout;
}
$creditSum = 39999;
$payout = 5000;
$HomoCreditTotal = HomoCredit($creditSum, $payout);
$SoftbankTotal = Softbank($creditSum, $payout);
$StrawberryBankTotal = StrawberryBank($creditSum, $payout);
echo "1 - {$HomoCreditTotal}";
echo "2 - {$SoftbankTotal}";
echo "3 - {$StrawberryBankTotal}";
ideone и codepad пишут таймаут. нигде ошибки не вижу.(Это если что задача про айфон в кредит и функции)
error_reporting(-1);
function HomoCredit($creditSum, $payout){
$totalPayout =0;
for(;;){
$creditSum = ($creditSum1.04)+500;
if ($creditSum<=5000) {
$totalPayout = $totalPayout + $creditSum;
break;
}
$totalPayout = $totalPayout + $payout;
}
return $totalPayout;
}
function Softbank($creditSum, $payout){
$totalPayout =0;
for(;;){
$creditSum = ($creditSum1.03)+1000;
if ($creditSum<=5000) {
$totalPayout = $totalPayout + $creditSum;
break;
}
$totalPayout = $totalPayout + $payout;
}
return $totalPayout;
}
function StrawberryBank ($creditSum, $payout){
$totalPayout =0;
for(;;){
$creditSum = ($creditSum*1.02);
if ($creditSum<=5000) {
$totalPayout = $totalPayout + $creditSum + 7777;
break;
}
$totalPayout = $totalPayout + $payout;
}
return $totalPayout;
}
$creditSum = 39999;
$payout = 5000;
$HomoCreditTotal = HomoCredit($creditSum, $payout);
$SoftbankTotal = Softbank($creditSum, $payout);
$StrawberryBankTotal = StrawberryBank($creditSum, $payout);
echo "1 - {$HomoCreditTotal}";
echo "2 - {$SoftbankTotal}";
echo "3 - {$StrawberryBankTotal}";
ideone и codepad пишут таймаут. нигде ошибки не вижу.(Это если что задача про айфон в кредит и функции)
> Решений задачи по всему гуглу миллион
Но там один очень существенный момент - количество банкнот не ограниченно.
В этом случае да, все просто, методом динамического программирования, хуяк-хуяк два цикла и ответ готов. Подогнать задачу про банкомат к задаче про рюкзак с ограничениями не получается. В задаче про рюкзак больше входных данных, учитывается цена и вес элемента.
На пикче алгоритм задачи рюкзака без ограничений (с ограничением отличается одним условием) Кто может пояснить при каких i, j F = 0
Решил. Подозреваю, что проблема в бесконечном цикле. Но там я так же решал, при выплате выходил из цикла через break
>Но там я так же решал, при выплате выходил из цикла через break
Я сомневаюсь что ОП такое одобрил бы.
Не понимаю. Если ты её решил, ты бы не написал такой код. У тебя там бесконечный цикл, в котором сумма кредита только увеличивается. Это не сработало бы в прошлой задаче, не сработает и здесь. К тому же если бы ты её решил, в этой задаче нужно просто подставить код из предыдущей в тело функции.
А насколько опасно для базы данных давать пользователю возможность форматировать текст, который он вводит в форму с помощью чистого html?
у меня не осталось кода от той задачи,я не сохраняю его. Сейчас поищу ошибку, спасибо.
Если используешь PDO и его prepared statements то по идее совсем безопасно. Но если ты даешь возможность пользователю вводить html теги, то тогда открывается другая уязвимость - XSS.
Почитай урок ОПа.
https://github.com/codedokode/pasta/blob/master/security/xss.md
>у меня не осталось кода от той задачи
Это не страшно, если ты её решил, ты напишешь этот код заново минут за 10. Я бы хотел посмотреть на решение.
Ладно, я передумал это делать.
Стоп, а как можно переслать админскую печеньку на другой сервер? Есть же Same Origin Policy. Стыкался с таким, когда дергал three.js. Там картинки пересылались по XmlHttpRequest
Это грустно.
Сайт на Wordpress? Хотя, это не имеет значения.
Посмотри в консоли браузера ошибки доступа к ресурсам, откуда сайт при загрузке запрашивает данные.
Нет, пытаюсь пилить студентов ручками.
Not allowed to load local resource: file:///C:/OpenServer/domains/localhost/studList/views/template/css/bootstrap.min.css
Not allowed to load local resource: file:///C:/OpenServer/domains/localhost/studList/views/template/css/style.css
DAY(date) == '8'
не работает, даже приведение к (int) обеих переменных не делает их равными, хотя они оба 8 втф?
>>file:///C:/OpenServer/domains/localhost/studList/views/template/css
Там есть эта папка вообще?
>>Not allowed
Ну это значит, что твой сервер неправильно настроен и отправляет ошибку 403 not allowed при попытке доступа к папке
Заменил на localhost/studList/views/template/css/bootstrap.min.css
и
localhost/studList/views/template/css/bootstrap.min.css
консоль выдала :
Resource interpreted as Stylesheet but transferred with MIME type text/html: "http://localhost/studList/index.php/localhost/studList/views/template/css/bootstrap.min.css".
неа
Анон выше написал что сервер неправильно настроен, должен отдавать MIME type text/css.
В Апаче это кажется опция AddType в .htaccess:
AddType text/css .css
Если бы здесь использовался Apache, тогда в файле httpd-vhosts.conf можно было бы поставить
<Directory "C:/OpenServer/domains/localhost/studList">
AllowOverride All
Order Allow,Deny
Allow from all
Require all granted
</Directory>
Мне казалось, что это настроено по умолчанию.
Ну и правильно подключать css так:
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" integrity="sha384-fLW2N01lMqjakBkx3l/M9EahuwpSfeNvV63J5ezn3uZzapT0u7EYsXMjQV+0En5r" crossorigin="anonymous">
А OpenServer использует Apache. Ковыряй его конфиги, но лучше было бы чтобы ты поставил апач, пхп и базу данных с нуля и по отдельности, так научишься настраивать и решать проблемы как у тебя сейчас.
Судя по сайту, он использует Apache.
Но я не хочу быть админом.
Мне тоже так казалось, но я недавно видел сервер на nginx который все файлы отдавал как text/html.
Ну и у него написано там что
>Resource interpreted as Stylesheet but transferred with MIME type text/html
> Ну и правильно подключать css так:
- снижается нажежность сайта
- так как ЦДН за бугром, увеличиваетяс время загрузки
- информация о посетителях сайта сливается за рубеж
Что вообще в этом хорошего? Надо думать своей головй, взвешивать плюсы и минусы а не бездумно копировать советы.
ЦДН используют обычно чтобы снизить расходы на трафик. В данном случае такой проблемы нет. Есть проблема разобраться с HTMl, HTTP и настройкой сервера. Нужны советы по этим темам. А не это.
Не пашет.
У меня openserver, стоит апач 2.4
Джва вопроса:
1. Почему \n не переносит строку? Использую Апач+пхп, т.е. запускаю файлы с программой в броузере.
2. Зачем в еcho переменные пишутся в скобках: echo "Foo {$bar}" ?
использую двойные кавычи (в одинарных команда выводится с текстом, в двойных не выводится, но и на новую строку не переносит)
Вывод ещё не сделал, но, анон, посмотрите ООП пожалуйста.
ОП, вообще я тут еще подкрутил кое-что.
Теперь поточно записывает, НО сейчас почему-то приходит со всех сайтов один и тот же ответ:
> HTTP/1.1 400 Bad Request
> Server: nginx
> Date: Tue, 08 Mar 2016 16:26:06 GMT
> Content-Type: text/html
> Content-Length: 166
> Connection: close
> <html>
> <head><title>400 Bad Request</title></head>
> <body bgcolor="white">
> <center><h1>400 Bad Request</h1></center>
> <hr><center>nginx</center>
> </body>
> </html>
Вторая проблема, я там поставил функции memory_get_usage перед чтением и записыванием и после. Память возрастает почему-то все равно. Не могу понять.
1. Что бы работал перенос, браузеру нужно сказать, что бы от отображал данные как обычный текст. Т.е. обробатывал \n как символ переноса строки. Для этого мы должны послать ему http-заголовок перед отправкой данных:
header("Content-Type: text/plain");
2. Что бы при парсинге строки обрабатывались сложные выражения их заключают в фигурные скобки.
Подробно:
http://php.net/manual/en/language.types.string.php#language.types.string.parsing
А и еще, код какой-то тяжелочитаемый стал. Вроде уже как мог на функции разбил.
Первый вопрос починил.
ОП, не бросай меня пожалуйста
Бамп
> Если да, то смешение нэйм и ип-бэйсед вызывает какие-то тупняки
Сомневаюсь. Скорее ты забыл в listen что-нибудь дописать. Покажи конфиг.
> В этом случае да, все просто
Да и в твоём — тоже. Берешь и динамически отсеиваешь динамическим программированием неподходящие решения, ёпт.
В этом случае надо делать через while.
Мне кажется, что за всё время их и сделали-то человек 10, от силы.
А файлообменник - человек 5.
после студентов работу можно искать уже? Не хотелось бы в девках так долго сидеть
И сложно достаточно для новчика, и синдром хеллоуворльдщика - типа кажется, что можно ебошить уже собственный фейсбук, а по сути только в простых скриптах можешь разбираться.
>>680883
Можно и до учебника ОПушки.
Я хз, после ФО лучше, больше соображения появится.
>в девках так долго сидеть
Смотря какую работу, ну ты понял.
хуева.
/n не робит, а <br> в апаче то выводит норм, но в ideone - нет.
Вообще надо избегать такого сумбура.
В двойных кавычках просто всё это поставь.
Чем проще, тем лучше поддерживать такой код.
Одинарные выводят переменные как есть, не интерпретируя, а двойные интерпретируют.
Или нет, я хз.
>>680918
Проверил проверяй.
Неправильное решение.
> слово1 слово2 слово3
> слово1 слово2 слово3
> Я слово4 слово5
- вот так должно быть.
Скрипт должен два раза выдать одну строку, а потом один раз другую. Попробуй сделать через цикл.
И да, из какой жопы ты вылез со своим нижним подчёркиванием в переменных и кучей ненужных кавычек? Залезь обратно Так не надо делать, юзай camelCase. Так чище и понятнее.
>Скрипт должен два раза выдать одну строку, а потом один раз другую.
Точнее сгенерить два раза рандомную но одну и ту же строку?
>И да, из какой жопы ты вылез со своим нижним подчёркиванием в переменных и кучей ненужных кавычек?
Ну это да, сейчас отрефакторю.
>Точнее сгенерить два раза рандомную но одну и ту же строку?
Yep. То, что по сути своей не отличается, лучше и делать с меньшей работой кода, компактнее, избегая копипаста.
>Точнее сгенерить два раза рандомную но одну и ту же строку?
Да, строка одна и та же, но значения у неё меняются. Циклом такое сделать можно.
Табуляцию не поставил, каюсь.
Всё верно.
>array_rand($word5,1)
Не обязательно ставить 1, если берёшь только одно рандомное значение.
>echo $line3Word1," ", $line3Word2;
Так а "Я" почему ты не вставил и как ты его вставишь, чтобы было чистенько?
>echo $line1Word1," ", $line1Word2," ",
>echo "Я ",$line3Word1," ", $line3Word2;
Лучше вот так:
>echo "$line1Word1 $line1Word2";
>echo "Я $line3Word1 $line3Word2";
Проще, понятнее.
Наверное да.
Ладно, буду делать дальше задачки.
Алсо, тут уже спрашивал раза 2, но оба так и не понял, поясните как реализовать сайт с админкой чтобы я в админке писал текст и загружал картинку, а мне на главной странице сайта была гиперссылка (неважно с текстом-заголовком или картинкой) на страницу с этой статьей(которая тоже создается по идее с админки же). Вообще, как на гитхабе искать подобное, чтоб глянуть? А то идей что-то нету. Говорили что через БД надо делать( в треде советовали).
http://www.hackingwithphp.com/15/0/0/networks
Интересное заявление, sockets are files, ведь сокеты это всего лишь идентификаторы соединения. Но они и правда вроде такие же как и с файлами.
Тут зачем-то яву с пхп мешают, это вообще может быть полезно?
http://www.hackingwithphp.com/14/2/0/bringing-java-into-the-mix
Ого, на пхп можно и флеш генерить.
http://www.hackingwithphp.com/11/5/0/creating-flash
Мне показалось, что там есть не мало интересного подчерпнуть. Что скажешь, ОП?
функция ucfirst не работает с кириллицей?
когда пытаюсь обойти как в mb_ucfirst меняет регистр не только у заглавной буквы, вот пример
http://ideone.com/5jTOnf
Нужно было чинить строки c html-кодом - типа незакрытых тегов и прочих непотребств. Tidy на хостинг не завезли. Погуглил функции от васянов - даже на stackoverflow полный пиздец на регулярках, для которого тысяча случаев, где оно не работает.
И я, за два часа, блядь. Написал парсер html, блядь. На строковых функциях, блядь. И на цикле блядь. Я король. Закрывает все теги. Удаляет любые непотребства.
Если кому-то понадобится работать с русскими html-тегами, лол, то функции можно заменить на mb_аналоги. Любой юникод вне названий тегов на работу метода не влияет.
http://ideone.com/AZIVW9
Ты про DOM не слышал?
Алсо твой код плохо читаемый и идет одной огромной стеной. Как проверить что в нем нет ошибок и уязвимостей?
Для начала можно бы проверить на списке конструкций отсюда https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
Тогда получается ты написал парсер который неизвестно безопасен ли (может конечно это и не требуется) и который написан стеной кода даже без комментариев и разбиения на части с 5 уровнями вложенности. Что скажет человек, которому надо будет проверить или доработать этот код?
Если ты делаешь рабочую задачу, не надо изобретать велосипед. Если ты делаешь это в учебных целях, надо делать правильно.
Вдуплил, кажется. Все, как у меня сейчас, только ветвление не по булям, а сначала в таблице по булям определяется состояние, и выполняется определенный блок кода.
Да, так было бы красивее.
>>681064
>неизвестно безопасен ли (может конечно это и не требуется)
Парсер парсит html не от пользователя. В базе хранятся новости с html-разметкой. Надо выводить краткую аннотацию.
>Что скажет человек, которому надо будет проверить или доработать этот код?
Он просто использует DOM, кек.
Я послушал, а на хостинге мой скрипт стал падать с ошибкой Too many connections.
Хех.
У меня куплена VPS (FreeBSD) несколько лет назад. Мне как дали ее с PHP 5.2, так там 5.2 и стоит.
В сосноли ничего умнее ls не знаю, но по инструкции вбить команды смогу (когда-то даже iconv так умдурился поставить).
Так вот. Как накатить 7.0, есть подробный манул, для таких, как я?
да.
контейнер>роу
вообще я давно не верстал и подзабыл, посмотри какой-нибудь йоба шаблон на бутстраппе через средства разработчика.
action="?$action"
input type="text" value="$value" placeholder="$value"
input type="submit" value="$value"
можешь формы хоть на лету генерировать
Вроде выполнил все шаги, но переменная $_POST - пустой массив. Как вычислить, на каком этапе ошибка? Не могу разобраться
У тега <input> должен быть указан аттрибут name.
http://www.w3schools.com/tags/att_input_name.asp
я это знаю и всё так и делаю, но $_Post всё равно пустой
бамп проблеме. Так и не решил её.
Напиши куда ты передаёшь и как ты получаешь переменную. Скорее всего на этих этапах у тебя ошибка.
Значит дело в скрипте. Выкладывай, посмотрим.
Какая идея с конфочкой? Тут разве что кидали ссылки на конфу в слаке, но они никакого отношения к этому треду не имели.
PHP конфа в телеграме была. Я там был. Там в основном только прон кидали. Я ливнул. Хотелось бы узнать как там всё и куда всё переросло?
https://github.com/toppestkek/CodelgniterTest
Да и вообще непонятно как правильно спозиционировать тот же логотип. Можно сделать ему маржин-топ, можно сделать родителю паддинг-топ, можно позишн: абсолют/релатив. Допустим, я выбрал через маржин-топ. По направляющим видно что надо добиться либо 50рх до нижнего края букв либо 29рх до верхнего. И как же правильнее это сделать, просто margin-top:29px или $logo-font-size:21px; margin-top:50 - $logo-font-size; в SASS?
Прозреваю что так каждый блок придется облеплять подобными костылями.
Надо ли стремиться к pixel perfect или тут дизайнер налепил говна? И что если мне на собеседовании дадут заверстать подобное?
спасибо
require('./sql_bd.php');
function gogogo() {
--быдлофункция с коннектом к базе--
}
На выходе
Call to a member function query() on a non-object
Ps всё работало до тех пор пока запилил код в функцию.
Pss всё заработает если добавлю коннект в функции
Мне что теперь в каждую функцию коннект плодить?
я всё. понял я мудак.
Вот я только недавно стал задрачивать на клаваорг и думаю в шторме нужно по лучше разобраться.
Что почитать по этой теме?
И что значит 'программировать мышкой'?
Там мой код только в контроллере, вью и модели, если что, это фреймворк.
Алсо, определять переменные и работать с классами, методами (приватные, публичные) я научился только после джавы, т.к. там все это необходимо, а в пхп похуй на это.
На хабре выложили перевод: https://habrahabr.ru/post/278655/
бамп проблеме, первые пять страниц в гугле не помогли
большая часть моего кодинга, эта вначале копипаст мышкой, какого то шаблона или каркаса, возможно куска написанного до этого, потом приведение мышкой этого в приличный вид и только потом написание нового.
Это норма?
не знаю, я стараюсь писать всё сам
Не совсем. Почитай про отправку форм методом POST в протоколе HTTP.
Думать что данные иф формы магическим образом оказываются в массиве POST неправильно. Там естьт протокол HTTP, и запрос который браузер отправляет на сервер. Разберись как это работает.
> Как вычислить, на каком этапе ошибка? Не могу разобраться
Изучить HTTP, после этого в отладчике браузера Ctrl + Shift + I нп вкладке netwoek посмотреть что именно и куда отправляется.
вот код:
<?php
include ('page.html');
page.html - эта же страница с формой. С $_GET всё работает.
var_dump выдаёт
array (size=0)
empty
>>681387
щито это?
if ($this->mysqli instanceof mysqli) {
$this->mysqli->close();
}
в деструкторе объекта у меня иногда вылетает PHP Warning: mysqli::close(): Couldn't fetch mysqli in blabla.php on line 124
Собственно, причина ясна - иногда я закрываю соединение еще до уничтожения объекта.
Вопрос: есть ли у mysqli свойство или метод, через который можно чекнуть, поднято ли сейчас соединение? Чтобы не закрывать протухшие коннекты.
> Думать что данные иф формы магическим образом оказываются в массиве POST неправильно. Там естьт протокол HTTP, и запрос который браузер отправляет на сервер
>магическим образом оказываются в массиве POST
вот тут сказано, что всё из <form method="post"> оказывается в переменной $_POST http://php.net/manual/ru/tutorial.forms.php
Про протокол - расскажи, я перерыл много страниц гугла, впервые слышу (я полный нубас в этом всём)
Фу, там ети геттеры сеттеры. Ужос.
Скорее всего прон опять спамят.
>Пости свой код на гитхаб и вкидывай ссылку в тред по мере решения.
Но его же придется скачивать чтобы запустить. Почему тогда архивами нельзя? Просто помню кто-то ругался, что нахуй эти архивы выкачивать. Просто прошу пояснить.
ОПу удобнее смотреть код на гихабе, при необходимости одной командой склонироать его. Скачать и распаковать архив нельзя одно командой, и просмотреть его не скачивая тоже нельзя.
А в чем проблема с гитхабом? Не нравится гитхаб, можно использовать битбакет например.
То есть если у тебя есть веские аргументы вроде слежки и приватности - можно подумть про альтернативы но если тебе просто лень изучать гит, то нет, это плохая идея. Да и гит не такой сложный, и книга по нему есть на русском.
Прочитал страницу опа по HTTP. Ответа на свой вопрос не нашёл
Если ты знаешь проблему, неужели сложно сказать?
А код ты давал в треде? Просто непонятно что именно не так по твоему вопросу, слишком много будет что не так если не видеть кода.
Как это тебе поможет решать такие проблемы в будущем? И я не телепат, я не знаю что у тебя не так.
Я написал выше уже по моему раза 2: открой девелопер тулз и посмотри какой запрос отправляет форма.
>>681325
Ты в классе well ищешь var_dump?
Не надо так делать.
GET вообще работает когда он в самом начале файла прописывается.
Вообще, если хочешь украсить и вывести - присваивай переменную и выводи её.
>Ты в классе well ищешь var_dump?
причём тут класс well? я просто вар-дампаю переменную в начале страницы.
>открой девелопер тулз
отправляет POST запрос
Да вот мамка пиздюлей дала, походил по днищевакансиям - понял, что ну нахуй. Разослал везде резюме на hh, на топтал. Ща прохожу собеседования, тестовые - вот это вот все. Апворк спамлю. По деньгам пусто.
Притом, что так делать не надо. GET не будет работать. Выведи его за пределы класса.
О чём ты? всё сделал же
>>681492
>$_SERVER["REQUEST_METHOD"]
даёт
'POST' (length=4)
>>681495
О чём ты вообще говоришь? какого класса? Ты про well? Это css класс, он тут вообще причём? У меня и без него не работает. Да и если на то пошло, я пишу, что GET работает, а POST нет. Ты троллишь?
>>681501
Get - это метод. Берёшь им переменную, в нём будут данные. Не берёшь - будет пустой дамп. Так понятней?
>>681501
я на всякий все прописал, чтоб проверять в чём подвох. CSS классы не при чём, без них то же.
>Var_dump($_GET["pwd"]);
повторяю, не работает POST. Аналогичная запись с ним ничего не даёт
>Get - это метод. Берёшь им переменную, в нём будут данные. Не берёшь - будет пустой дамп. Так понятней?
Что? Ты хотя бы с мануалом для начала ознакомься, прежде чем такое советовать.
$_GET это ассоциативный массив, никак не метод.
http://php.net/manual/en/reserved.variables.get.php
Сказал же,
>Аналогичная запись с ним ничего не даёт
т.е. null
короче, я тут полтреда засрал, а ответ так и не получил. Есть тут кто сталкивался? В чём вообще может быть причина?
Код вроде нормальный, и отправляет POST. Я думаю проблема где-то на сервере, возможно он настроен неправильно.
Ты сначала левйй код кидаешь, а потом какие-то вопросы задаёшь? Я тебе не ванга, не могу предугадать что ты делал, а что нет.
Попробовал. Сделал test.php include этот же файл:
...\1.html:10:
array (size=0)
empty
...\1.html:11:
array (size=0)
empty
...\1.html:12:
array (size=0)
empty
Ты уверен что тоде самое сделал?
Назвал файл test.php?
Положил его в htdocs?
Ввёл в поле данные?
Нажал отправить?
Скрины где?
Бамп вопросам, с главным вопросом я разобрался, остальные начиная со второго до сих пор не понимаю
Запости свой код еще раз (в коде var_dump($_POST ) должен идти до любых других действий) + скриншот подробностей запроса из дев тулз + какой УРЛ в браузере.
Неплохо бы узнать где он таки тестирует, на локальной машине? На апаче? На сборочке? На сервере?
Закинь на гитхаб и покажи что там у тебя.
Зайди на test.php?test=test
А в PHPstorm ьщжно в свои директории сувать и работает? Просто я привык всё в htdocs держать.
Ну вангую что что-то не так именно у PHPstorm.
Не получается. Прописал AllowOverride All в httpd.conf, все равно не реагирует .htaccess в phpstorm. Проверял строкой This is garbage line в нем, никаких ошибок нет при открытии в браузере.
А то в обьявлениях мб наёбывают.
Я так на С++ мидлом устроился.
гугли 'Что требуют, спрашивают на собеседование пхп'.
По таким шаблоном большинство контор собеседует.
После файлообменика ОПа вполне можно ходить по собеседованиям.
>Ну вангую что что-то не так именно у PHPstorm.
Ты был прав, анончик. Нашёл у них целую тему в интернете по этому поводу, где жалуются на эту проблему. Ну и параша, пиздец, кто бы мог подумать. Всё, поставил на шторм апач и теперь всё работает.
>$text1 = preg_replace("!(\ )+!iu", " ", $text); //Убираем лишние проблемы
>$text2 = preg_replace("!(\ )?\,(\ )?!iu", ", ", $text1); //Делаем пробел после запятой
>$text3 = preg_replace("!(\ )?\.(\ )?!iu", ". ", $text2); //и после точки
Так не годится, слишком много копипасты.
Надо сделать массивы с регулярками и заменами, пропустить через одну функцию preg_replace.
я не знаю как сделать что бы в одной функции, без лишнего текста, заменяло запятую на запятую с пробелом, а точку на точку с пробелом и так с остальными знаками
Возможно ли найти работу, если слово битрикс у тебя в блеклисте? То есть я автоматом скипал лубую вакансию и оффер, если там это слово встречалось.
Вот интересно, там пишут, что функции и методы должны быть написаны верблюжьим, но в большинстве гайдов по фреймворкам геттеры и сеттеры пишутся андерскопом, как так?
Хорошо. Тогда давай всё то же самое БЕЗ phpstorm.
ставь Убунту.
http://pro-prof.com/archives/1584
Никто и не выёбывается
Здесь главное — постоянство. Т.е. если выбрал один стиль, то придерживайся его во всём проекте.
Но ОП будет тебя дрючить, если не будешь соблюдать PSR
Послушай, но если я называю функции верблюжьим стилем, я все же не могу себя заставить писать get_ и set_ тоже верблюжьим, это просто режет глаза.
Есть форма, там вводятся данные, отправляются на сервер, этот метод получает данные и должен записать данные в бд.
Выполнения кода до этой функции доходит и выполняется дальше, вот только в самый бд где-то происходит ошибка и нихуя не записывается, при том, что все записывалось, а почему перестало работать хуй его знает, метод я не изменял, а работать перестал какого-то хуя, если этот метод выполняется но не записывает в бд, значит ошибка происходит в бд, значит проблема в sql запросе, а может и нет, но она точно находится в этом методе. А в чем собственно проблема блять? подключение к бд работает и проблема уж точно не в этом
Вот этот пидорский метод:
https://github.com/luptidu/students.com/blob/master/models/Student.php#L32
-------------------------------------------------------------------
И еще вопросы в данный момент менее важные:
2. Когда использоваться include, а когда include_once, как работает я знаю, но не могу понять в каких ситуациях первая функция может вызвать проблемы? То же самое и c require и require_once. Да и зачем вообще нужна require, если везде можно юзать инклюд? По идее
3. Можно ли в свойствах класс модели создать переменную дб и уже юзать ее в функциях и не писать в каждой функции одну и ту же строчку кода? Хотя что-то мне подсказывает, что типо так не делают, потому что даже при использовании функции где не используется бд все равно придется слать запрос к бд, что уменьшает скорость обработки
4. Я немного не понимаю суть ООП в плане, почему не сделать все функции статическими и выполнять их без создания обьекта. Можешь привести примеры где нужно будет обязательно создавать обьект и без него никак? Желательно где это обязательно в этой задаче
5. Зачем нужно постоянно импортировать бд или создавать вручную если хочешь потестить чей-то сайт? Почему бы не написать просто код который проверяет наличие бд и таблиц и если они отсутствуют, то просто создает их.
6. Также почему когда люди выкладывают свой сайт на тест, то выкладывают его без фреймворка и его тоже нужно устанавливать руками? Ведь можно просто скинуть папочку с фреймворком и не париться.
Есть форма, там вводятся данные, отправляются на сервер, этот метод получает данные и должен записать данные в бд.
Выполнения кода до этой функции доходит и выполняется дальше, вот только в самый бд где-то происходит ошибка и нихуя не записывается, при том, что все записывалось, а почему перестало работать хуй его знает, метод я не изменял, а работать перестал какого-то хуя, если этот метод выполняется но не записывает в бд, значит ошибка происходит в бд, значит проблема в sql запросе, а может и нет, но она точно находится в этом методе. А в чем собственно проблема блять? подключение к бд работает и проблема уж точно не в этом
Вот этот пидорский метод:
https://github.com/luptidu/students.com/blob/master/models/Student.php#L32
-------------------------------------------------------------------
И еще вопросы в данный момент менее важные:
2. Когда использоваться include, а когда include_once, как работает я знаю, но не могу понять в каких ситуациях первая функция может вызвать проблемы? То же самое и c require и require_once. Да и зачем вообще нужна require, если везде можно юзать инклюд? По идее
3. Можно ли в свойствах класс модели создать переменную дб и уже юзать ее в функциях и не писать в каждой функции одну и ту же строчку кода? Хотя что-то мне подсказывает, что типо так не делают, потому что даже при использовании функции где не используется бд все равно придется слать запрос к бд, что уменьшает скорость обработки
4. Я немного не понимаю суть ООП в плане, почему не сделать все функции статическими и выполнять их без создания обьекта. Можешь привести примеры где нужно будет обязательно создавать обьект и без него никак? Желательно где это обязательно в этой задаче
5. Зачем нужно постоянно импортировать бд или создавать вручную если хочешь потестить чей-то сайт? Почему бы не написать просто код который проверяет наличие бд и таблиц и если они отсутствуют, то просто создает их.
6. Также почему когда люди выкладывают свой сайт на тест, то выкладывают его без фреймворка и его тоже нужно устанавливать руками? Ведь можно просто скинуть папочку с фреймворком и не париться.
В двух массивах должны быть:
1. Регулярки.
2. Замены.
Порядок регулярок и замен в этих массивах должен соответствовать.
Далее просто подставляешь в функцию один массив на место регулярок, а другой на место замен - всё пошагово меняется.
Легко
1. Что php выдаёт? (в браузер или в логи)
3. Почитай эту пасту https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md
5. Обычно так и делают. Например, пишется скрипт (install.php), который пользователь запускает, забивает некие параметры (реквизиты БД, м.б. что-то ещё) и он сам всё инициализирует. С другой стороны, это может не отменять дампа БД, т.к. ты можешь в скрипте читать SQL-запросы из файлы и выполнять. Ты об этом?
>>680858
Вот, смотри
http://pastebin.com/N4xNU3jp
Удаленно подключаешься по умолчанию к mysite. Норм.
По 127.0.0.1 и server подключаешься к главной - окей.
А вот дальше - пиздец:
По mysite и test подключаешься все равно к главной - wtf?
А по localhost - наоборот, к mysite!
Пиздец.
Я тогда попробовал сделать вот так
http://pastebin.com/9xSB879h
И теперь вообще все коннекты идут к mysite. Пробовал менять секции с звезда:80 и 127.0.0.1:80 местами - не реагирует.
Няша, скажи пожалуйста: в ближайшее время еще есть смысл вкатываться в PHP в условиях заполонившего все на свете JavaScript (фронтенд, бэкенд, расширения для браузеров, игры, десктоп, мобильники)? Ведь он все больше разжирается, вокруг него все прыгают и т. д. Ниша php сильно сократится, зарплаты сильно упадут, конкуренция добьет начинающего?
ничего, открывается страничка с поздравлениями, но вот только в бд не добавляет, как я понял пхп похуй то есть ли ошибки в бд или нет и если он никакого ответы не ждет, то просто идет дальше.
3. Читал, но все равно нихуя не понял, если ты читал и понял, то ответь, пожалуйста, конкретно на мои вопросы.
5. Нет, я не про то, но я сам уже понял почему так не делают, ведь если сделать проверку на наличие бд, то выйдет, что при каждом запросе придется проверять есть ли бд, а это по идее замедлит скорость работы всего сайта.
>ничего, открывается страничка с поздравлениями
Ты редирект убирал перед этим?
По-моему у тебя там ошибка в передаче параметров. Посмотри документация на метод execute()
>3. Читал, но все равно нихуя не понял
Отвечаю на твой вопрос: да, можно. Видишь в пасте в конструктор класса NewsTableGateway передаётся PDO-объект? Это и есть твоя переменная. Также, это будет примером на четвёртый вопрос: в этом случае тебе не нужно в каждом методе писать Database::connect(), что сокращает код и делает его более устойчивым к ошибкам (например, ты просто не можешь забыть вызвать Database::connect()).
>5.
Да, плюс у тебя будут проблемы с типами данных.
Хочу ОПа послушать, что он скажет. По-мне так не так и долго, пару лет назад еще про эти все нод.жсы никто всерьез не говорил.
Снова выхожу на связь. Это же не апач, да? А как выбрать в пхпшторме апач?
Не сравнивай. Руби, хаскель, дэ, лисп, перл, го, бу - это все очень хипстота, а вот жс сейчас ну прямо-таки везде. И, что важно - фуллстак разрабом можно идти, зная только жс и его подмножества и фреймворки. Чего не скажешь о тех же С++, ПХП, Питоне или Джаве.
Я понимаю, что можно брать только ссылки из РСС, и дальше просто парсить сами новости, переходя по ссылкам, но это будет занимать больше времени, да и не совсем удобно, хоть и разметка на всём сайте примерно одинаковая.
Изучи cgi. Тоже интересная штука. У тебя разве новые слова не вызывают любопытства?
1. Редирект у меня после записи в бд.
Проверил в мануале, да, там в ключе нужно было добавить двоеточие типо ':name", а у меня было 'name'. Но все равно не записывает и в прошлом как-то записывало и без этого, но все же оставлю. А в остальном по идее все правильно.
3. Да, похоже что в статик функциях такое не получится реализоваться, ну и ладно, я считаю, что удобней будет каждый раз в методе писать соединение, чем каждый раз когда хочешь обратиться к бд создавать обьект.
По поводу четвертого, я кроме того, что шанс ошибок меньше я так и не понял зачем нужен обьект, нужен такой пример, где без обьекта не обойтись и нужно его использовать обязательно.
Не могу отправить, есть какое-то слово из спам листа в том что я написал
Так-то нормик.
Но лого съезжает при увеличении масштаба в Лисе.
Не адаптивное главное меню.
Шрифты какие-то не те, лучше засечки поменьше или вообще без них.
учи обязательно ангуляр и ноду, мне даже в вакансиях на пхп ангуляр и ноду присылают (смешанные с пхп).
Там же всё на вордпресс, из админки если что можно менять всё.
В США веб-скрейпинг может быть признан нарушением закона о причинении вреда имуществу: https://en.wikipedia.org/wiki/Web_scraping#Legal_issues
Там есть ссылки на конкретные делав судах, где суд приравнивал скачивание данных ботами к причинению вреда компьютерным сетям и серверам (аналогично по поводу рассылки спама).
Хотя с другой стороны, а как же Гугл скрейпит страницы без разрешения? Интересно конечно.
Так что думайте, прежде чем заниматься такими делами. Особенно если вам предлагают "скрейпить" сайт крупной американской компании.
>1. Редирект у меня после записи в бд.
Убери его. Если там warning или notice, PHP будет продолжать выполнение и дойдёт до него.
>3.
У тебя на каждый вызов функции создаётся соединение, например.
> зачем нужен обьект
Я так понимаю, ты уже прочитал вот это http://archive-ipq-co.narod.ru/l1/pasta.html ?
Погугли «зачем нужно ООП». Почитай про управление сложностью, разделение ответственности (сейчас у тебя этого нет), инкапсуляцию (очень важная тема), полиморфизм, наследование.
Не нашёл у ОПа паст на эту тему, если у кого есть годные ссылки, вбросьте
Или жди ОПа, он тебе лучше объяснит.
Вот есть у меня таблица в базе с файлами, в ней колонки id, name, uploader, upload_date, downloads. Искать мне нужно только в колонке name, конфиг сфинкса вот - http://pastebin.com/AU6m9nrw.
Как я понял из документации http://sphinxsearch.com/docs/latest/index.html sql_field_string - это полное текстовое поле, по которому идет поиск с помощью MATCH() в SphinxQL. Но когда я с помощью SphinxQL делаю SELECT * FROM index_files WHERE MATCH('1'), то получаю только один файл который содержит цифру 1 в самом начале имени (хотя таких файлов там далеко не 1). Далее, если я делаю MATCH с частью имени какого-нибудь другого файла, то не получаю совсем ничего. Почему так происходит? Конфиг неправильный или запрос? Читал про extended query syntax тут http://sphinxsearch.com/docs/current/extended-syntax.html но так и не нашел того что мне нужно.
Пик релейтед.
Нашел вот такую опцию http://sphinxsearch.com/docs/current/conf-expand-keywords.html
Если с этой опцией задать min_word_len = 1 и min_prefix_len = 1 (думаю все же поставить 3 - 4 символа, чтобы удобнее было когда записей в базе будет больше), тогда все работает как нужно, но все равно хотелось бы услышать комментарии от кого-нибудь кто работал с сфинксом, правильно ли я делаю?
- есть некий сайт, на нем есть Пользователи, Фото, Комментарии
- необходимо сделать возможность пользователям лайкать других пользователей, фото и комментарии
- 1 пользователь не может поставить 2 лайка одной и той же сущности (например одному и тому же фото)
- пользователь должен иметь возможность отозвать лайк
- нужно иметь возможность посчитать число лайков для той или иной сущности
Как бы вы это реализовали и почему? Сразу предупрежу, тут есть как минимум несколько вариантов. Оптимизировать под производительность ничего не требуется, внешние ключи желательны, следование принципам нормализации тоже по очевидным причинам.
Я бы с радостью,но все таки когда из-за искусственных проблем не можешь начать делать файлообменник и изучать новый фреймворк - как-то не весело.
Вот эти клоуны прислали мне приглашение на собеседование. Думаю пойти по фану и в конце сказать Я ВАМ ПЕРЕЗВОНЮ.
Извините, тредом ошибся.
Ну это очень условно, жс на беке отличается от жс на фронте.
Я вообще не виду проблемы в том что бы изучать несколько языков.
Хотя если жс захватит мир я не против, опять же перекат из языка в язык это не сложно и интересно
Сделал бы отдельную таблицу лайков, где один лайк = одна строка. В ней следующие поля: ид, ид юзера, ид сущности (комментарий, фото, юзер), дата. Была бы таблица для каждой сущности, где есть поле лайк. Может быть я еще бы и у таблицы юзер создал бы поле лайк. И при лайканьи менял/добавлял бы значение в трех местах базы. А вообще я наверное бы все это на монгодб сделал. И возможно бэкенд бы на сокетах реализовал.
А внешние ключи как сделать в твоей схеме? Не, тут есть несколько вариантов решения с нормальными внешними ключами.
> А вообще я наверное бы все это на монгодб сделал.
А чем она лучше, интересно? Там вроде много чего нет: SQL запросов, джойнов, транзакций. И блокировки говорят на всю коллекцию сразу при записи. Не очень понятно, в чем выгода от урезания возможностей.
>Сделал бы отдельную таблицу лайков, где один лайк = одна строка.
Аня сфотала сиськи и получила 10000 лайков.
У тебя в таблице 10 000 строк добавилось.
Найс.
Лайк - это одно числовое поле в таблице. Каждый лайк +1 к сумме в поле. Дизлайк -1 к сумме в поле.
Скорость. Частое взаимодействие с базой. Я просто знаю, что всякие чатики, лайки делают на монгодб, тк там много запросов.
Это всё-равно экспонента.
У тебя 2000 юзеров.
У каждого по 200 фотографий, у каждой фотографии в среднем по 15 лайков.
Итого 2000 200 15 =6000000.
При этом с возрастом системы Старые пользователи увеличивают количество фотографий, а новые добавляют новые.
В какой-то момент у тебя будет 6000000 записей в час.
Тогда надо уже даже не мускул, а что то свое и производительные писать, но я не знаю какой там порог у мускуля
>Как проверять на повторный лайк?
dskfjk.jpg 1 лайк
sddfasd.jpg 1 лайк
asdasd.jpg 1 лайк
Другими словами Записываешь каждому юзеру просмотренные фото. И отдельно ведёшь запись того что он лайкнул.
Ну или Можно послушать кого-нибудь кроме меня.
Ничем не подтвержденные заявления вряд ли хороший аргумент. То что кто-то что-то использует - может он это делает от скуки или ради лишнего слова в своем резюме.
>>682429
Ну от 6 млн майскул не развалится. И когда у тебя будет много пользователей, скорее всего у тебя будет и много денег на масштабирование (оно тебе понадобится независимо от выбранного хранилища).
>>682431
Пишут, да, кто-то свои хранилища на Си, как вконтакте, кто-то что-то опенсурсное прикручивает. Но в качестве основного хранилища данных внизу часто остается та же Mysql.
>>682432
Усложенение. Алсо прочитай уже про нормализацию и связи в Бд и перестань изобретать велосипеды.
Бамп.
Ну ок, сейчас аргументы и факты погуглю за монгу.
>В США веб-скрейпинг может быть признан
Потому американцы и идут с этими заказами на биржи к индусам, русским и прочим кодерам третьего мира.
Вот какой-нибудь володька панкратов из мухосрани спарсил каталог товаров из одного пиндосского магазина. И что, к нему теперь нагрянет интерпол и цру?
А так в штатах конечно авторские права бешено защищают, например тебе реально могут дать срок за скачивание пиратской музыки или программ. Но мы же не в штатах.
У меня кстати идеологическое отвращение к парсингу и подобным заказам. Я учился программированию чтобы быть "не таким как все", чтобы делать что-то интересное и сложное, возвышенное. А тут один барыга предлагает спиздить контент у конкурента. Я программист, а не грязекраб.
Хуже только работа с порносайтами.
По отдельной таблице лайков на отдельную сущность, многие ко многим.
likes_user_user (from_user, to_user)
likes_user_photo (from_user, to_photo)
likes_user_comment (from_user, to_comment)
Первичный ключ на обе колонки, внешние на каждую по отдельности.
>отозвать лайк
Ну видимо удаление, DELETE FROM likes_user_photo WHERE from_user = ? AND to_photo = ?
>1 пользователь не может поставить 2 лайка одной и той же сущности
PRIMARY KEY (from_user, to_photo)
>нужно иметь возможность посчитать число лайков для той или иной сущности
SELECT COUNT() FROM likes_user_photo WHERE from_user = ?
Другие варианты не очень идут в голову, потому не могу сказать почему выбрал этот вариант.
Ну допустим можно сложить все лайки в одну таблицу. Но тогда не будет возможности повесить внешние ключи. И придется делать доп.колонку 'тип сущности', чтобы можно было выбирать отдельно только лайки для фото или комментов.
Анимешник это как советский знак качества, только для программистов.
Вообще, это ведь задача на наследование. Если ты вспомнишь 3 паттерна наследования таблиц, то получишь как минимум 3 варианта (хотя я конечно не знаю, любой ли там паттерн подойдет).
>>682528
Я подозреваю там хайлоад уровня поставить кеш на редисе перед mysql + несколько серверов со нгинксом настроить для раздачи видео.
>как же Гугл скрейпит страницы без разрешения?
Там какое-то пользовательское соглашение есть при добавлении в аддурл. Может, это.
Хотя Гугл индексирует сайт и без добавления через аддурилку, по ссылкам из Твиттера и прочих соцсетей. Хотя с Твиттером вроде разорвано соглашение, я запамятовал. Так-то есть соглашение или нет - без разницы, всё равно проиндексирует быстрее, если живая ссылка из соцсети с переходами на сайт.
И где в случае с лайками наследование?
class или concrete ti подойдут если есть несколько классов, которые наследуются от общего. Приводят примеры со Спортсментами и их разновидностями, такими как Футболист, Крикетист и Боулер(?).
http://design-pattern.ru/patterns/concrete-table-inheritance.html
Или класс Транспорт, от которого наследуются Автомобиль, Мотоцикл или Грузовик.
У них у всех есть что-то общее, и есть отдельные уникальные характеристики.
Не понимаю как натянуть структуру лайков на cti, не вижу аналогии.
А чем плоха эта схема? >>682541
Запись, картинка, видео.
В талбице должны складываться все лайки юзеров и должны записываться их ID.
Больше одного лайка всё равно нельзя ставить.
Поэтому поставил лайк - твой ID записался, лайков стало на один больше.
Ну и такая же ерунда с дислайками, только если стоит лайк от этого же ID - он списывается.
Таблица для qwerty.jpg, like - 12345, ID - столько же айдишек лайкнувших, dislike - 54321, ID - столько же айдишек дислайкнувших.
Почему я не прав?
Только приступил к ООП, на БД даже не смотрел пока
>ID - столько же айдишек лайкнувших
Ты хочешь хранить ID всех лайкнувших в одной строке? Представь какого размера будет эта строка когда количество лайкнувших людей перевалит за 5 - 10к. Соответственно любые операции поиска\удаления в такой строке будут занимать очень много памяти и времени.
А обязательно иметь какие-то завязки и в графах таблицы? Почему нельзя просто кучу строк, как значений в массиве, сделать?
Например, вот такой массив:
$likes = array(
id123,
id234,
id345,
id456 ...
)
Чтобы найти нужное значение и чтобы его удалить, потребуются какие-то милисекунды.
Чому в таблице это не возможно?
Одна графа с картинкой/записью/видосом, графа с лайками - строки являются айдишками, графа с дислайками - строки с айдишками.
>Представь какого размера будет эта строка когда количество лайкнувших людей перевалит за 5 - 10к
Я представляю, сколько вообще в базе будет всего, когда столько или намного больше будет просто зарегистрировано.
Статистику проводить. В какой день больше лаков например или в какой час и так далее. Модульность.
Лайки разных видов можно унаследовать от общего предка. Или сущности которые лайкаются можно унаследовать. Смотри, сколько вариантов решения.
>>682603
Тем что ты даже не рассматривал другие варианты.
>>682620
Чтобы проектировать БД надо изучить теорию, например нормализацию (у меня тут есть список: https://gist.github.com/codedokode/10539213#Теория-по-проектированию-БД )
Без теории ты можешь придумать неправильное решение, например нарушающее принцип атомарности, и даже не понять почему оно неправильно.
>>682625
Это не главная пролема. Хуже то что по такой строке нельзя джойнить и нельзя делать перекрестные выборки вроде найти всех лайкнувших пост.
>>682632
Надо изучать теорию
>>682638
С внешними ключами твой вариант работает? Если нет, то не очень. Ну и хотелось бы не тыкать пальцем в небо а например рассмотреть какие вообще варианты возможны.
>>682641
Менеджерам и аналитикам нужна.
Лайки разных видов можно унаследовать от общего предка. Или сущности которые лайкаются можно унаследовать. Смотри, сколько вариантов решения.
>>682603
Тем что ты даже не рассматривал другие варианты.
>>682620
Чтобы проектировать БД надо изучить теорию, например нормализацию (у меня тут есть список: https://gist.github.com/codedokode/10539213#Теория-по-проектированию-БД )
Без теории ты можешь придумать неправильное решение, например нарушающее принцип атомарности, и даже не понять почему оно неправильно.
>>682625
Это не главная пролема. Хуже то что по такой строке нельзя джойнить и нельзя делать перекрестные выборки вроде найти всех лайкнувших пост.
>>682632
Надо изучать теорию
>>682638
С внешними ключами твой вариант работает? Если нет, то не очень. Ну и хотелось бы не тыкать пальцем в небо а например рассмотреть какие вообще варианты возможны.
>>682641
Менеджерам и аналитикам нужна.
>Лайки разных видов можно унаследовать от общего предка.
Каких "разных видов"?
Чем лайк фото отличается от лайка комментария? И у того и у другого одинаковые свойства (кто поставил, куда поставил).
Расширь условие пожалуйста.
Ну и вообще ты с колокольни своего опыта конечно можешь придумать множество вариантов и вспомнить сотни случаев практического применения. Но ты забываешь, что здесь большинство начинащих, кто и дня не работал.
Поэтому давай полное условие, я например не могу придумать какие могут быть "лайки разных видов", и зачем тут уперлось их наследовать.
Тупо подгонять под указанный тобой паттерн не буду без оснований.
>сущности которые лайкаются можно унаследовать
Пользователя от комментария? Фото от пользователя?
Зачем тебе свои эксперименты заливать в интернет? Я думаю что локального сервера хватит вполне.
Апач настроить не сложно, и лучше научится, потому что это полезный навык. А показывать друзьям ты можешь и с локального сервера, при условии что у тебя белый айпи.
>А показывать друзьям ты можешь и с локального сервера
А вот с этого места поподробнее. Это как вообще?
Можно апач настроить так, чтобы он был доступен из интернета. Для этого тебе нужен будет белый айпи (который не за НАТом) и открытый 80 порт на роутере.
inb4:
>глобалы, глобалы везде
Можно в любой момент засунуть массивы в сами функции или передать параметрами, но это будет не красиво.
>уродливые вложенные тернарники
Даже я (ньюфаг) разбираю чужие тернарники, как карточные дома. Тем более, что мои логично сконструированы, а не в собраны в одну строчку.
>PHP Notice: что-то там offset на произвольной строчке
Ебался много дней над этим, но, к сожалению, не пришел к какому-либо определенному ответу.
https://ideone.com/vXGibE
>не даем готовых ответов в задачках от ОПа
>каждый день тучи петушков оставляют тут свои решения, а ОП их комментирует и доделывает решение за них
Ну-ну, лол.
Попробуй включить фантазию.
На сайтах знакомств например. На сайтах по интересам.
Взаимный лайк значит, что люди нравятся друг другу, и можно приступать к общению/ебле и т.д.
Так что одна из самых важных функций.
>>682734
Оп как раз дает очень мутные советы, куда копать, что гуглить, и никогда не отвечает прямо.
В принципе это правильно, хотя иногда бесит. Особенно когда ничего не получается, а тебе вместо подсказки подсовывают очередную загадку.
> Чем лайк фото отличается от лайка комментария?
Лайк комментария ссылается на комменатрий, а лайк фото на фото.
> Ну и вообще ты с колокольни своего опыта конечно можешь придумать множество вариантов и вспомнить сотни случаев практического применения. Но ты забываешь, что здесь большинство начинащих, кто и дня не работал.
Это же тред обучения. Я хочу чтобы вы тоже умели.
> Расширь условие пожалуйста.
Ты предложил один вариант. Подумай какие еще варианты возможны, чтобы можно было сравнить их и выбрать наиболее подходящий.
Ну еще например в твоей модели, чтобы узнать все лайки пользователя, надо делать юнион по всем табицам лайков. Не факт что это плохо, но хотелось бы знать какие есть другие варианты, может они еще лучше.
>>сущности которые лайкаются можно унаследовать
> Пользователя от комментария? Фото от пользователя?
Можно унаследовать их от абстрактной ЛайкаемойСущности и лайкать ее. Хотя как мне кажется, тут это будет неудобно, наледование выглядит абсолютно навязанным, и неудобно будет добавлять лайки к новым таблицам. Лучше все же наследовать сами лайки.
>>682681
Плохая идея, надо комп держать включенным круглосуточно + всякой заразе снаружи удобнее атаковать тебя.
>>682674
Нормальная, но знай что есть бесплатные хостинги и даже домены. Но можешь и купить. Тогда лучше посмотреть - может у тебя и на полноценный VPS хватит? Там правда надо знать линукс и все настраивать самому зато ограничений намного меньше и у тебя права администратора.
> Чем лайк фото отличается от лайка комментария?
Лайк комментария ссылается на комменатрий, а лайк фото на фото.
> Ну и вообще ты с колокольни своего опыта конечно можешь придумать множество вариантов и вспомнить сотни случаев практического применения. Но ты забываешь, что здесь большинство начинащих, кто и дня не работал.
Это же тред обучения. Я хочу чтобы вы тоже умели.
> Расширь условие пожалуйста.
Ты предложил один вариант. Подумай какие еще варианты возможны, чтобы можно было сравнить их и выбрать наиболее подходящий.
Ну еще например в твоей модели, чтобы узнать все лайки пользователя, надо делать юнион по всем табицам лайков. Не факт что это плохо, но хотелось бы знать какие есть другие варианты, может они еще лучше.
>>сущности которые лайкаются можно унаследовать
> Пользователя от комментария? Фото от пользователя?
Можно унаследовать их от абстрактной ЛайкаемойСущности и лайкать ее. Хотя как мне кажется, тут это будет неудобно, наледование выглядит абсолютно навязанным, и неудобно будет добавлять лайки к новым таблицам. Лучше все же наследовать сами лайки.
>>682681
Плохая идея, надо комп держать включенным круглосуточно + всякой заразе снаружи удобнее атаковать тебя.
>>682674
Нормальная, но знай что есть бесплатные хостинги и даже домены. Но можешь и купить. Тогда лучше посмотреть - может у тебя и на полноценный VPS хватит? Там правда надо знать линукс и все настраивать самому зато ограничений намного меньше и у тебя права администратора.
Если непонятно так и напиши и попроси вторую подсказку. Но лучше конечно писать что именно непонятно.
> Плохая идея, надо комп держать включенным круглосуточно + всякой заразе снаружи удобнее атаковать тебя.
Не обязательно круглосуточно, он же для показывания друзьями. Включил, показал и выключил. Но для чего-нибудь посерьезнее лучше купить хостинг, конечно.
>Взаимный лайк
Вешаешь лайкоприемник на объект и делаешь условное сравнение с объектами пользователей, которым поставил лайки наш пользователь, если лайки есть, то выкидывай оповещение о обоюдном лайке.
>Оп как раз дает очень мутные советы, куда копать, что гуглить, и никогда не отвечает прямо.
В принципе это правильно, хотя иногда бесит. Особенно когда ничего не получается, а тебе вместо подсказки подсовывают очередную загадку.
Лол, как по мне, так он совершенно прямо отвечает, что нужно доделать или переделать.
Но я начинал не с задачек ОПа (по-моему, они сложноваты для нуба, хоть я и согласен, что нужно начинать с хардкора), а с задачек для новичка с киберфорума. Попробуй для начала зайти туда, или есть акк вбыдлятне, то там паблики поищи.
>>682831 калькулятор
>>682834 палиндром, калькулятор, верстка
>>682836 круг, калькулятор, верстка
>>682838 правописание, верстка
>>682839верстка
>>682842 резюме, исключения, переводы строк
Зайдите и найдите свой пост, если вы что-то там писали. Если я вас вдруг пропутсил - напомните о себе в этом треде.
Хорошо, попробуем подогнать систему лайков под какой-нибудь паттерн (чтобы проделав этот сизифов труд прийти к первоначальному решению)
Class Table Inheritance
http://design-pattern.ru/patterns/class-table-inheritance.html
Судя по картинке (а по чему еще судить? не вижу нигде подробного и внятного объяснения), предлагается вынести все общие свойства в одну таблицу (в примере это Player),
под каждый отдельный класс завести отдельную таблицу и хранить в ней уникальные для этого класса свойства, а также (наверное) внешний ключ на общую таблицу.
С трудом представляю, как подогнать наши лайки к этой схеме.
Допустим, создадим таблицы
likes_common (id PK, from_user FK)
likes_photo (photo_id FK, like_id FK)
likes_comment (comment_id FK, like_id FK)
likes_user (user_id FK, like_id FK)
Что дает эта странная схема?
+ Выбрать все лайки без юнионов тоже можно, непонятно правда зачем это может понадобиться (вывести в профиле список ссылок на лайкнутые объекты?), и как обозначить тип лайка (отдельной колонкой ENUM в таблице likes_common?).
- Довольно хитрый запрос на вставку, нужна транзакция.
Single Table Inheritance
Одна таблица, где создаются поля на все случаи жизни, под все возможные свойства.
В нашем случае что-то вроде
likes (id PK, from_user FK, type ENUM, photo_id FK, comment_id FK, user_id FK).
+ Одна таблица, никаких джойнов, юнионов, транзакций и т.п.
- Много пустых полей у каждой записи (не совсем понимаю как это влияет на производительность, но поговаривают что это плохо).
- Нужна миграция при появлении нового лайкабельного класса, поле под него нужно будет добавить. Впрочем под те две схемы тоже нужно будет создавать новые таблицы под каждый класс.
Concrete Table Inheritance
Для каждого класса информацию хранить в отдельной таблице, вместе с общими свойствами, в отличие от class table inheritance.
Да по-моему как раз соответствует тому, что я написал в первом посте, когда еще не слышал про этот паттерн. >>682541
+ В отличие от class ti не нужна транзакция при вставке, один инсерт в соотв. таблицу.
+ В отличие от sti нет вынужденных пустых полей.
- Нельзя выбрать все лайки для разных классов (одновременно для комментариев, фото, пользователей) без юнионов. Хотя не представляю, в какой ситуации это может понадобиться.
Больше критериев для сравнения не могу придумать. Пока побеждает concrete TI (если я правильно ее тут воплотил).
Хотя и sti тоже годится из-за простоты и отсутствия джойнов. Хотя я не знаю в цифрах, как влияют на производительность джойны, и как влияет большое кол-во пустых полей.
Хорошо, попробуем подогнать систему лайков под какой-нибудь паттерн (чтобы проделав этот сизифов труд прийти к первоначальному решению)
Class Table Inheritance
http://design-pattern.ru/patterns/class-table-inheritance.html
Судя по картинке (а по чему еще судить? не вижу нигде подробного и внятного объяснения), предлагается вынести все общие свойства в одну таблицу (в примере это Player),
под каждый отдельный класс завести отдельную таблицу и хранить в ней уникальные для этого класса свойства, а также (наверное) внешний ключ на общую таблицу.
С трудом представляю, как подогнать наши лайки к этой схеме.
Допустим, создадим таблицы
likes_common (id PK, from_user FK)
likes_photo (photo_id FK, like_id FK)
likes_comment (comment_id FK, like_id FK)
likes_user (user_id FK, like_id FK)
Что дает эта странная схема?
+ Выбрать все лайки без юнионов тоже можно, непонятно правда зачем это может понадобиться (вывести в профиле список ссылок на лайкнутые объекты?), и как обозначить тип лайка (отдельной колонкой ENUM в таблице likes_common?).
- Довольно хитрый запрос на вставку, нужна транзакция.
Single Table Inheritance
Одна таблица, где создаются поля на все случаи жизни, под все возможные свойства.
В нашем случае что-то вроде
likes (id PK, from_user FK, type ENUM, photo_id FK, comment_id FK, user_id FK).
+ Одна таблица, никаких джойнов, юнионов, транзакций и т.п.
- Много пустых полей у каждой записи (не совсем понимаю как это влияет на производительность, но поговаривают что это плохо).
- Нужна миграция при появлении нового лайкабельного класса, поле под него нужно будет добавить. Впрочем под те две схемы тоже нужно будет создавать новые таблицы под каждый класс.
Concrete Table Inheritance
Для каждого класса информацию хранить в отдельной таблице, вместе с общими свойствами, в отличие от class table inheritance.
Да по-моему как раз соответствует тому, что я написал в первом посте, когда еще не слышал про этот паттерн. >>682541
+ В отличие от class ti не нужна транзакция при вставке, один инсерт в соотв. таблицу.
+ В отличие от sti нет вынужденных пустых полей.
- Нельзя выбрать все лайки для разных классов (одновременно для комментариев, фото, пользователей) без юнионов. Хотя не представляю, в какой ситуации это может понадобиться.
Больше критериев для сравнения не могу придумать. Пока побеждает concrete TI (если я правильно ее тут воплотил).
Хотя и sti тоже годится из-за простоты и отсутствия джойнов. Хотя я не знаю в цифрах, как влияют на производительность джойны, и как влияет большое кол-во пустых полей.
Гитхаб раздает бесплатное имя и вдс
Тоже не не могу осилить. Говорят в треде, что жадное - не годится.
Вот ведь несправедливость: быдлокодеры в своих конторках пилят код за реальные деньги, а мы тут с академическими задачами ебемся, которые вообще решаются рекурсивно на другом языке.
Я эту задачу когда-то давно делал с рекурсией. Вообще в двух вариациях. С рекурсией и без.
Можно ее пропустить и попробовать сделать следующие? Мне просто уже не терпится SQL учить для маня-проектика.
Ты это я
Вообще ее можно на любом решить, сути там нет пхп это будет или яваскрипт, там именно математика нужна. Я гуглил решение, но сам я такое хуй напишу - математика для меня слишком абстрактна. Накупил книжек по терверу и статистике, но не осилил дальше 10-15 страниц, потому нахуй забыл все курсы математики и вышмата со школы и универа
очередной пхп-нюфаг
самое тупое решение что мне щас пришло просто прописать под каждое значение вплоть до 100 тысяч с помощью ООП, а после 100 тысяч идите нахуй, через кассу плез
тот-же-нюфаг
Без ограничений задача решается очень просто рекурентной формулой, как прикрутить к этому ограничения хуй знает.
Неужели в пхп нет библиотек для парсинга джейсона?
https://ideone.com/jDmpcI
Нахуй учить пыху, чтобы использовать ее в связке в джейсоном? Учил бы лучше ноду.
Базару нет, братишка, но если бы пока я учил математику мне платили бы хотя бы 10-15.т.р в месяц я бы блядь целый год посвятил этой царице наук. Но надо еще кушать, одеваться (работаю веб-макакой, сайтики поднимаю/продвигаю)
поэтому для меня полезнее сначала освоить пхп хотя бы на мидл+, достаточного для программиста, а не юниора. Тупо потому что это позволит мне работать с вордпрессами-юмлами на новом уровне.
Поэтому как только удастся освоить я сразу освою, а пока буду буксовать. В конце концов жизнь это всегда if / else
Зачем школьные? Ты же не школьник.
Посмотри программу какого-нибудь мехмата мгу и рекомендованные к ней учебники они как раз entry level и читай@делай задания.
Начинать по порядку или эти книжки самодостаточны? Просто я начал курить третью, а там такой поток высшего матана, что я просто охуел.
Я учился в гуманитарной гимназии, алгебра была раз в неделю. В аттестате три стоит. Ну ты представляешь уровень, да?
>>682974
Не пойму, вы общий вариант решить не можете или hard mode у этой задачи, когда 6600 надо выдать?
У ОПа же там общий вариант без ограничений, я решал так, а он вроде бы одобрил.Общий вариант там решается легко, вы о чём вообще?
Там один цикл foreach, несколько условий.
Дальше с этой задачей я даже не стал возиться, потому что там алгоритмы, пока мне не под силу это всё.
Они самодостаточны. Алгоритмы без математики понять будет сложно.
Вот к примеру алгоритм решения задачи о рюкзаке. Я к примеру со своими скудными знаниями обосрался на 1 строчке.
А я давненько находил решение на паскале, и переписывал его на пхп, но оно все равно было неверно.
Ещё бы не обосрался, ведь там очень неудачно это записано.
Ну смотри, тут можно начать с самого неэффективного, но простого алгоритма:
перебрать все допустимые сочетания купюр:
- если это сочетание дает нужную сумму, вывести его.
А дальше уже думать как оптимизировать. Например не перебирать заведомо невыигрышные сочетания и в каком порядке перебирать.
>>682996
Академические? Не смеши.
>>683023
Ты можешь SQL учить параллельно с PHP, они не зависят друг от друга никак.
>>683088
ООП тут вообще при чем?
>>683116
Ты гуглить умеешь? php json
Код ужасный, копипаста на копипасте.
>>683145
Ты миддлом не станешь если не способен организовать перебор всех комбинаций купюр. Мне кажется.
>>683157
Он же программистом хочет стать, а не механиком или математиком. Плохой совет, computer science это отдельная наука, но наверно анон не захочет лишком много теории учить, изучать компиляторы и нейронные сети вместо CSS и MySQL.
>>683204
Вот теория, откуда взяты обозначения: https://ru.wikipedia.org/wiki/Теория_множеств
Перевернутая ∀ значит "для любого"
Круглая ∈ значит "элемент принадлежит множеству"
Например
∀(i) ∈ {1, 2,3 }
читается как "для любого i, принадлежащего множеству из цифр 1, 2, 3", или "где i равно 1, 2 или 3"
f = 0, ∀(i) ∈ {1, 2,3 }
Читается как "есть массив f, i равно 1, 2 или 3, а значения массива по этим индексам равно нулю"
В коде это можно записать так:
$f = array_fill_keys([1, 2, 3,], 0);
Далее там есть знак объединения:
{ N ∪ {0} }
Это значит "множество, полученное объединением множества N и множества состоящего из нуля". То есть если в множестве N не было нуля, он добавляется.
В программе это можно написать так:
$result = array_intersect($N, [0]);
Ну и далее мы видим еще интересную штуку:
{....} ⨯ { ... }
Это декартово произведение множеств, то есть набор всех возможных пар значений из обоих множеств. Ну например для множеств { a, b } и { c, d,e } декартово произведение будет множеством пар:
ac
ad
ae
bc
bd
be
Произведение исплоьзуется так:
∀(i, j) ∈ {....} ⨯ { ... }
То есть пары i и j принадлежат множдеству пар получившемуся в результате декартового произведения.
Это по сути значит "i принимает все возможные значения из первого множества, а j - из второго".
Соответственно первая строка читается:
Возьмем 2-мерный массив f с индексами i, j и значениями равными нулю. Причем i взят из объеинения множества значений Nn и множества из одного нуля, а j из объединения Nb и нуля
В коде это выглядит как вложенный цикл, заполняющий массив:
foreach (... as $i) {
foreach(... as $j ) {
$f[$i][$j] = 0;
}
}
Вторая часть первой строки определяет массив z
Обрати внимание на такие вещи:
- математическая запись очень лаконична и короче чем код
- математическая запись не определяет алгоритм, которым ты будешь создавать массив: циклом или например руками его опишешь. Она определяет лишь как должен выглядеть результат.
То есть первая строка просто создает массивы f и z .
Ну смотри, тут можно начать с самого неэффективного, но простого алгоритма:
перебрать все допустимые сочетания купюр:
- если это сочетание дает нужную сумму, вывести его.
А дальше уже думать как оптимизировать. Например не перебирать заведомо невыигрышные сочетания и в каком порядке перебирать.
>>682996
Академические? Не смеши.
>>683023
Ты можешь SQL учить параллельно с PHP, они не зависят друг от друга никак.
>>683088
ООП тут вообще при чем?
>>683116
Ты гуглить умеешь? php json
Код ужасный, копипаста на копипасте.
>>683145
Ты миддлом не станешь если не способен организовать перебор всех комбинаций купюр. Мне кажется.
>>683157
Он же программистом хочет стать, а не механиком или математиком. Плохой совет, computer science это отдельная наука, но наверно анон не захочет лишком много теории учить, изучать компиляторы и нейронные сети вместо CSS и MySQL.
>>683204
Вот теория, откуда взяты обозначения: https://ru.wikipedia.org/wiki/Теория_множеств
Перевернутая ∀ значит "для любого"
Круглая ∈ значит "элемент принадлежит множеству"
Например
∀(i) ∈ {1, 2,3 }
читается как "для любого i, принадлежащего множеству из цифр 1, 2, 3", или "где i равно 1, 2 или 3"
f = 0, ∀(i) ∈ {1, 2,3 }
Читается как "есть массив f, i равно 1, 2 или 3, а значения массива по этим индексам равно нулю"
В коде это можно записать так:
$f = array_fill_keys([1, 2, 3,], 0);
Далее там есть знак объединения:
{ N ∪ {0} }
Это значит "множество, полученное объединением множества N и множества состоящего из нуля". То есть если в множестве N не было нуля, он добавляется.
В программе это можно написать так:
$result = array_intersect($N, [0]);
Ну и далее мы видим еще интересную штуку:
{....} ⨯ { ... }
Это декартово произведение множеств, то есть набор всех возможных пар значений из обоих множеств. Ну например для множеств { a, b } и { c, d,e } декартово произведение будет множеством пар:
ac
ad
ae
bc
bd
be
Произведение исплоьзуется так:
∀(i, j) ∈ {....} ⨯ { ... }
То есть пары i и j принадлежат множдеству пар получившемуся в результате декартового произведения.
Это по сути значит "i принимает все возможные значения из первого множества, а j - из второго".
Соответственно первая строка читается:
Возьмем 2-мерный массив f с индексами i, j и значениями равными нулю. Причем i взят из объеинения множества значений Nn и множества из одного нуля, а j из объединения Nb и нуля
В коде это выглядит как вложенный цикл, заполняющий массив:
foreach (... as $i) {
foreach(... as $j ) {
$f[$i][$j] = 0;
}
}
Вторая часть первой строки определяет массив z
Обрати внимание на такие вещи:
- математическая запись очень лаконична и короче чем код
- математическая запись не определяет алгоритм, которым ты будешь создавать массив: циклом или например руками его опишешь. Она определяет лишь как должен выглядеть результат.
То есть первая строка просто создает массивы f и z .
Ошибки:
> $result = array_intersect($N, [0]);
Неверно, на самом деле я имел в виду
if (!in_array(0, $N)) {
$N[] = 0;
}
> $f = array_fill_keys([1, 2, 3,], 0);
Это можно записать проще:
$f = [1 => 0, 2 => 0, 3 => 0];
В том что ты из заданного числа вычитаешь максимальное число из имеющихся в наборе и так далее спускавшийся по убывающей.
как-то так
https://ideone.com/lPJ1of
Блин, смотрю на решение - и не могу ни черта понять...
И из-за оформления тоже:
>$key => $value
Не понятно же, зачем так называть всё непонятно?
Вот моё простое решение, месяц как раз прошёл: http://ideone.com/3w70JB
Про "жадность" алгоритма понял, спасибо, у меня как раз такой же.
>$key => $value
> Не понятно же
$bills = array(
100 => 23,
500 => 5,
1000 => 0,
5000 => 200
);
Что тут непонятного
$key - это будет 100 500 1000 5000
$value - это будет 23 5 0 200
Я не об этом, это всё я прекрасно понимаю.
Просто у меня сейчас привитый ОПом бзик: код должен быть понятен практически в любой точке.
ОП такого не прививал и я наговариваю?
Ну, может быть.
Просто $key и $value здесь (да как и везде) являются определёнными сущностями, почему бы их и не назвать в соответствии с той ролью, которую они играют?
Купюры и количество их.
И что там только две функции encode и decode а дальше с многомерным массивом работать, это же пиздец.
>Ты миддлом не станешь если не способен организовать перебор всех комбинаций купюр. Мне кажется
На самом деле если материал разжевано подавать с числами вместо всех этих а b c d e я его понимаю, на живом примере.
Я как-то сеошничал в конторке, там пацаны пилили вполне себе ПО для работы с налоговыми. Продукт на рынке, вполне успешен, в основном вся сложность была в регулярках, так как сверка данных по полям и значениям. Налоговая же. Все формулы заранее известны, у парней опыта по 2-3 года пхп, знания фреймворков нет, на чистой пхп. Зп у старшего 90, у остальных по 65.
Я к тому, что мне вот эти переборы и банкоматы в хуй не уперлись, мне гораздо важнее работать с цмс и модулями для них, маркетинг, интернет-магазины. Ну например - сбор почтовых ящиков (в бд или файл - похуй) и рассылка их , аякс фильтры для магазина (+правка контроллеров, добавление новых полей и др), модули похожих товаров (вот здесь кажись есть математика, хотя мне кажется все проще и на ассоциациях тупо по %word% работает внутри категорий).
Возможно, года через 2-3 я наверстаю этот момент и подниму навыки математики до нормальных, ибо нисколь не отрицаю важности ее, но я думаю что ее незнание можно скомпенсировать знанием языка и гуглом для допила вот этих всех дел, в дебри программирования я и не лезу - middle- уровня мне хватит с лихвой на данном этапе. Хобби у меня в музыке и звукозаписи, тут же чисто деньги и работа.
Я вообще из верстки и sео пришел. Подучу пхп и возьмусь за ангуляр, т.к. конкуренция на рыночке требует.
Цмску по книжке Янка написал, особо сложностей не встретил.
в середине подача нудная, так как дохрена кода идет и нет разбора его, так как в первой части книги он весь написан уже, а во второй допиливается. Но азы скл и работы пхп с скл в ней поданы на ура.
Дальше как раз регулярки дают ну и в конце какие-то совсем йоба-примеры из жизни пхп-макак. Я еще не дошел.
Ничего хорошего.
зимний семестр
Защита населения
Работа на ЭВМ и программирование
Английский язык
Физическое воспитание
История Отечества
Математический анализ
Алгебра
Аналитическая геометрия
летний семестр
Физическое воспитание
Работа на ЭВМ и программирование
Математический анализ
Экономическая теория
Защита населения
Введение в математическую логику
Английский язык
История Отечества
Я так понимаю, чтобы стать хорошим быдлокодером, нужно учить вот эти дисциплины, правильно?
Это факультет математиков. У механиков точно такое же, только физики больше на первом курсе.
>Он же программистом хочет стать, а не механиком или математиком. Плохой совет, computer science это отдельная наука, но наверно анон не захочет лишком много теории учить, изучать компиляторы и нейронные сети вместо CSS и MySQL.
Ты не прав, я хочу иметь хорошую, твердую палубу, на которой можно крепко стоять и не падать с нее, обосравшись, при морской качке типа той задачки с банкоматом. Я понимаю, что нужно уметь больше и эффективнее других, а чтобы уметь больше, нужно быть образованнее других, все это нужно, чтобы выигрывать на рынке труда с возможностью осилить какой-нибудь менее макакерский язык, ту же яву или си для перекатывания в индустрию поинтереснее.
Там не то что бы очень сложная математика, но на собеседованиях могут спросить про графы, алгоритмы сортировки (какие существуют, какие знаешь), оценку сложности этих алгоритмов (то самое Big O), и деревья какие-нибудь. Все это можно осилить с знаниями уровня первого курса любого днищевуза. Это та теория которая которая поможет тебе решать проблемы, если они возникают. Остальная, более сложная математика используется только в специализированном софте, но в России таких вещей почти не делают, да и попасть туда гораздо сложнее чем джуниором на PHP.
>графы
Не, не слышал.
>алгоритмы сортировки
Вставкой и слиянием. Первый метод работает лучше с меньшим количеством элементов, второй с большим.
>оценку сложности этих алгоритмов
Не слышал.
>деревья какие-нибудь
Только о бинарном слышал.
Хорошо, спасибо, буду курить учебники.
Опять же, для устройства на работу это не обязательно знать, как когда-то объяснял ОП. Ну и от себя добавлю, походив по собеседованиям я понял что в вебе (по крайней мере на PHP, как по другим языкам не знаю) спрашивают в основном про фреймворки и просят сделать небольшое тестовое на них же. Но если хочешь стать лучше, то желательно и теорию знать, конечно.
Палю полезный сайт по Big-O http://bigocheatsheet.com/
А как тестовое задание проходить? Какие вообще бывают? Сколько времени на него дают? Ты находишься под наблюдением и без интернета или у тебя полная свобода действий?
Это уже от компании зависит. Некоторые по почте присылают и дают несколько дней, некоторые приглашают тебя в свой офис, дают компьютер и ты делаешь там (никто не наблюдает конечно же). Или на собеседовании могут дать теоретическу задачу и спросить какие паттерны ты использовал бы на практике, как бы ты спроектировал архитектуру приложения, как бы спроектировал базу данных и т.д.
Меня спросили, что я знаю. Я говорю хтмл, ксс и меня взяли.
Он правильно написал. Названия переменных должны отражать то, что в них хранится. key и value это не названия, а бессмысленные слова которые автоматически вписывает IDE при вставке foreach.
Точно также обычно не годятся всякие названия вроде tmp, str, data, var и тд.
>>683321
Ты спрашивал про "парсинг" json - я тебе написал что есть в PHP. Насчет многомерных массивов - правильно эта задача решается так: создается объектная модель, и с помощью какой-нибудь библиотеки-маппера json преобразуется в дерево объектов. Все нормальные люди делают так: в Яве, в C# есть библиотеки для этого.
При чем тут PHP? Библиотеку-маппер можно написать или не написать на любом языке. Разработчики PHP виноваты что ты не написал такую библиотеку или что ты не смог ее нагуглить?
>>683344
Название библиотеки напиши, а то пока это утверждение без пруфов.
>>681952
Это phpstorm? Я писал пару дней назад, открой документацию и прочти как у них реализован сервер. У меня нет пхпсторма и я не могу сам проверить. И я даже не знаю какой кнопкой ты его запускаешь и что там у тебя в настройках.
Если ты не смог найти подробности в документации сам - напиши, я погуглю.
Либо на гитхабе лиюо отредактировать файл у себя и закоммитить.
> и я консолькой не пользуюсь поэтому.
Ну и зря. Это ведь значит что ты не знаешь гит. Потому что осваивать надо именно через консольку, ГУИ там предоставляет ограниченный набор функций и в случае любой проблемы ничем не поможет.
Есть книга по гиту на русском, не вижу проблемы прочесть ее.
>>681860
Вот описано как Апач определяет хост: https://httpd.apache.org/docs/current/vhosts/name-based.html#alg
Сначала по IP сопоставляет и выбирает наиболее подходящие, а только потом среди выбранных смотрит имена.
> По mysite и test подключаешься все равно к главной - wtf?
Потому что поиск по IP дает что для запросов пришедших на интерфейс 127.0.0.1 подходит только последний блок. И выбирать можно только из него.
Что делать? Неужели все пропало? Нет не все. Может быть виртуал хост может соответсовать нескольким IP? Открываем мануал по VirtualHost и внимательно-внимательно изучаем синтаксис:
https://httpd.apache.org/docs/current/mod/core.html#virtualhost
Почитай этот мануал и попробуй сам придумать решение, если не придумаешь или не сработает - пиши.
Так на собеседовании на миддла тебя могут попросить решить задачу на перебор.
> там пацаны пилили вполне себе ПО для работы с налоговыми
А на собеседовании тебя попросят перевернуть бинарное дерево.
> знания фреймворков нет, на чистой пхп.
Тут нечем гордиться. Завтра у их конторы начнутся сложности и куда они пойдут? Что они покажут на собеседовании, свой велосипед?
> мне гораздо важнее работать с цмс и модулями для них, маркетинг, интернет-магазины.
Ты говоришь как будто это какие-то отдельные знания. Если ты хорошо знаешь пхп и веб-приложения то быстро в них разберешься, если нет то будешь лепить кривые костыли.
Нет никакого смысла изучать конкретную CMS так как их десятки, они насквозь состоят из быдлокода и постоянно меняются. Есть смысл изучать более общие вещи, с которыми ты сможешь разобраться в любой CMS.
Ну смотри, я ведь ничего не навязываю - хочешь, ковыряй CMS. Хочешь простую задачу на CMS - держи:
- сделать на вордпрессе клон https://m.roem.ru/
- редакторы добавляют новости, ставят теги, пользователи читают и комментируют
- дизайн берем с мобильной версии роема (он проще)
- код надо сделать в виде расширения или темы для вордпресс, он дложен быть отдельно чтобы можно было взять вордпресс, установить на него твой модуль и все работало.
> . Подучу пхп и возьмусь за ангуляр,
Ангулар это один из сложнейших JS фреймворков. Чтобы разобраться в нем, надо отлично знать JS, DOM, понимать что такое MVC, data binding, DI. Посмотри код ангулара и попробуй разобраться если думаешь что он простой.
Я сомневаюсь что почитав/посмотрев несколько уроков ты продвинешься дальше хелло ворлда. Реальные приложения ты вряд ли сможешь научиться делать так быстро.
Ну и если тебе интересная эта тема, в ОП посте есть задачка на SPA.
Так на собеседовании на миддла тебя могут попросить решить задачу на перебор.
> там пацаны пилили вполне себе ПО для работы с налоговыми
А на собеседовании тебя попросят перевернуть бинарное дерево.
> знания фреймворков нет, на чистой пхп.
Тут нечем гордиться. Завтра у их конторы начнутся сложности и куда они пойдут? Что они покажут на собеседовании, свой велосипед?
> мне гораздо важнее работать с цмс и модулями для них, маркетинг, интернет-магазины.
Ты говоришь как будто это какие-то отдельные знания. Если ты хорошо знаешь пхп и веб-приложения то быстро в них разберешься, если нет то будешь лепить кривые костыли.
Нет никакого смысла изучать конкретную CMS так как их десятки, они насквозь состоят из быдлокода и постоянно меняются. Есть смысл изучать более общие вещи, с которыми ты сможешь разобраться в любой CMS.
Ну смотри, я ведь ничего не навязываю - хочешь, ковыряй CMS. Хочешь простую задачу на CMS - держи:
- сделать на вордпрессе клон https://m.roem.ru/
- редакторы добавляют новости, ставят теги, пользователи читают и комментируют
- дизайн берем с мобильной версии роема (он проще)
- код надо сделать в виде расширения или темы для вордпресс, он дложен быть отдельно чтобы можно было взять вордпресс, установить на него твой модуль и все работало.
> . Подучу пхп и возьмусь за ангуляр,
Ангулар это один из сложнейших JS фреймворков. Чтобы разобраться в нем, надо отлично знать JS, DOM, понимать что такое MVC, data binding, DI. Посмотри код ангулара и попробуй разобраться если думаешь что он простой.
Я сомневаюсь что почитав/посмотрев несколько уроков ты продвинешься дальше хелло ворлда. Реальные приложения ты вряд ли сможешь научиться делать так быстро.
Ну и если тебе интересная эта тема, в ОП посте есть задачка на SPA.
Адаптивная верстка = верстка, подстраивающаяся под разные устройства и отображающаяся на них наилучшим образом.
По факту это сводится к использованию @media правил для изменеия раскладки при переходе ширины через определенную границу. Например, меньше 800px у нас одна структура страницы, а больше - другая.
Можешь привести краткий пример что именно не получилось сделать в последний раз?
>>683425
> История Отечества
Самая нужная программисту вещь. Лол, некоторые люди еще и платят за это.
> Я так понимаю, чтобы стать хорошим быдлокодером, нужно учить вот эти дисциплины, правильно?
Нет, из полезного тут только английский. Программисты изучают языки программирования, алгоритмы, структуры данных, паттерны, ООП, архитектуру.
Да не нужна вузовская математика чтобы посчитать сложность алгоритма. Там нет операций сложнее чем возведение в степень.
Есть конечно области, где математики больше - например, машинное обучение и искуственный интеллект - там нужны основы теории вероятности, комбинаторики.
>>683437
> Палю полезный сайт
Вот с одной стороны красиво сделано. Но я подумал, люди могут неправильно понять и попытаться заучивать все это. А ведь учить не надо - если ты понимаешь как устроен и работает массив или связанный список, ты эти сложности алгоритмов и так знаешь.
Изучай алгоритмы и структуры данных. Начать можно хоть с гугла:
https://www.google.ru/search?q=алгоримты+и+структуры+данных&newwindow=1&gbv=1&sei=tYTiVp3RNIm56AS75rKoBw
https://www.google.ru/search?q=структуры+данных&newwindow=1&gbv=1&sei=94TiVofKHcmY6ASjppioAg
http://aliev.me/runestone/
>>683438
Бывает еще штука как дают задачу и просят тут же решить, на листочке бумаги или на доске. Бывает то же самое удаленно - через сервис редактирования кода.
Алгебра и геометрия
Архитектура компьютеров и операционные системы
Базы данных
Введение в алгебраическую топологию
Введение в математический анализ
Введение в программирование
Математическая логика и теория алгоритмов
Многомерный анализ, интегралы и ряды
Объектно-ориентированное программирование
Основы комбинаторики и теории чисел
Математическая логика
Математика и программирование на первом курсе.
подожди с задачками, я еще свою дописываю по книжке)
я там студентов думал делать следующими
ангуляр да, я пощупал, штука сложная. Но бояться сложностей - то можно и из дома не выходить
скачай шаблон на бутстраппе и посмотри за счет чего там адаптивность, поковыряй стили.
Если средствами разработчика в хроме / мозилле пользоваться умеешь - поймешь через секунду
<?php
$link = mysql_connect('localhost', 'mysql_user', 'mysql_password');
if (!$link) {
die('Ошибка соединения: ' . mysql_error());
}
echo 'Успешно соединились';
mysql_close($link);
?>
Выводит ошибку:
Fatal error: Uncaught Error: Call to undefined function mysql_connect() in C:\Apache24\htdocs\database.php:3 Stack trace: #0 {main} thrown in C:\Apache24\htdocs\database.php on line 3
>>683572
Еще добавлю - оче много гуглил, пишут что надо что-то менять в php.ini, я был раскомментировал строку с extends mysqli.dll, вырубил апач, но запускаться он не хотел(ошибка 1067 или как-то так).
>>683572
>>683584
Алсо, самое обидное то, что спросив у быдлогруппников, сказали мол поставь себе денвер или опенсервер, что ты как лох всё отдельно ставил.
Мне нужно, чтобы выводилось минимальное значение по ключу ["score"], а min() сравнивает подэелементы многомерного массива по ключу "type" почему-то.
https://ideone.com/S5i9mI
Я имею в виду что ангулар надо учить после других вещей, а не сразу. Изучи хорошо сам JS, разберись с концепцияим которые испльзуются в ангуларе, а не спеши делать хелло ворлды.
>>683565
Плохой совет. Если смотреть примеры, лучше гуглить статьи типа "N лучших адаптивных сайтов".
>>683566
Там не только медиа, там еще верстать надо уметь резиново.
>>683572
Расширение mysql выпилили. Используй PDO
>>683586
Они тебе плохие советы дают. Какая выгода от сборки? Устаревший пхп, и дополнительные проблемы с которыми тебе никто не поможет.
>Расширение mysql выпилили. Используй PDO
PDO, ЧСХ, тоже не робит.
Ввожу это:
<?php
$db = new PDO('mysql:host=localhost;dbname=testdb;charset=utf8mb4', 'username', 'password');
?>
Выводит это:
Fatal error: Uncaught PDOException: could not find driver in C:\Apache24\htdocs\database.php:2 Stack trace: #0 C:\Apache24\htdocs\database.php(2): PDO->__construct('mysql:host=loca...', 'username', 'password') #1 {main} thrown in C:\Apache24\htdocs\database.php on line 2
Посмотри на официальном сайте в разделе установка pdo.
Я просто не мог понять почему у меня не работает медиа, ну а бутсрапп по мне так идеальный пример - там все задано в em, % и наследуется.
Загуглил, раскомментировал все пдошки в php.ini, выключил апач, поставил запустится апач и вывело ошибку 1067 "процесс был неожиданно завершен".
В итоге получилось, что запускается только если закомментировать пдошки.
;extension=php_pdo_firebird.dll
;extension=php_pdo_mysql.dll
;extension=php_pdo_oci.dll
;extension=php_pdo_odbc.dll
;extension=php_pdo_pgsql.dll
;extension=php_pdo_sqlite.dll
;extension=php_pgsql.dll
;extension=php_shmop.dll
Там нужно всего лишь добавить две строчки
extension=php_pdo.dll
extension=php_pdo_mysql.dll
и перезапустить php (не только апач).
Об этом сказано в оф.мануале.
http://php.net/manual/ru/pdo.installation.php
Не нужно копировать куски конфига из результатов выдачи гугла, нужно понимать что делаешь.
>>683648
Ты понимаешь, за что отвечает каждый файл?
Вот так как-то.
Взял один небольшой кусок с конца, всё в принципе одинаково
[Fri Mar 11 12:14:58.650106 2016] [mpm_winnt:notice] [pid 2600:tid 436] AH00354: Child: Starting 64 worker threads.
[Fri Mar 11 12:26:28.069813 2016] [mpm_winnt:notice] [pid 5000:tid 476] AH00422: Parent: Received shutdown signal -- Shutting down the server.
[Fri Mar 11 12:26:30.097817 2016] [mpm_winnt:notice] [pid 2600:tid 436] AH00364: Child: All worker threads have exited.
[Fri Mar 11 12:26:30.113417 2016] [mpm_winnt:notice] [pid 5000:tid 476] AH00430: Parent: Child process 2600 exited successfully.
AH00558: httpd.exe: Could not reliably determine the server's fully qualified domain name, using fe80::319a:fba7:ebdf:9a22. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd.exe: Could not reliably determine the server's fully qualified domain name, using fe80::319a:fba7:ebdf:9a22. Set the 'ServerName' directive globally to suppress this message
[Fri Mar 11 12:26:56.311471 2016] [core:warn] [pid 7880:tid 472] AH00098: pid file C:/Apache24/logs/httpd.pid overwritten -- Unclean shutdown of previous Apache run?
[Fri Mar 11 12:26:56.342671 2016] [mpm_winnt:notice] [pid 7880:tid 472] AH00455: Apache/2.4.18 (Win64) PHP/7.0.1 configured -- resuming normal operations
[Fri Mar 11 12:26:56.342671 2016] [mpm_winnt:notice] [pid 7880:tid 472] AH00456: Apache Lounge VC14 Server built: Dec 9 2015 11:13:29
[Fri Mar 11 12:26:56.342671 2016] [core:notice] [pid 7880:tid 472] AH00094: Command line: 'C:\\Apache24\\bin\\httpd.exe -d C:/Apache24'
[Fri Mar 11 12:26:56.342671 2016] [mpm_winnt:notice] [pid 7880:tid 472] AH00418: Parent: Created child process 5372
AH00558: httpd.exe: Could not reliably determine the server's fully qualified domain name, using fe80::319a:fba7:ebdf:9a22. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd.exe: Could not reliably determine the server's fully qualified domain name, using fe80::319a:fba7:ebdf:9a22. Set the 'ServerName' directive globally to suppress this message
[Fri Mar 11 12:26:56.654672 2016] [mpm_winnt:notice] [pid 5372:tid 436] AH00354: Child: Starting 64 worker threads.
[Fri Mar 11 12:30:20.208926 2016] [mpm_winnt:notice] [pid 7880:tid 472] AH00422: Parent: Received shutdown signal -- Shutting down the server.
[Fri Mar 11 12:30:22.236930 2016] [mpm_winnt:notice] [pid 5372:tid 436] AH00364: Child: All worker threads have exited.
[Fri Mar 11 12:30:22.268130 2016] [mpm_winnt:notice] [pid 7880:tid 472] AH00430: Parent: Child process 5372 exited successfully.
AH00558: httpd.exe: Could not reliably determine the server's fully qualified domain name, using fe80::319a:fba7:ebdf:9a22. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd.exe: Could not reliably determine the server's fully qualified domain name, using fe80::319a:fba7:ebdf:9a22. Set the 'ServerName' directive globally to suppress this message
[Fri Mar 11 12:34:51.121848 2016] [core:warn] [pid 8016:tid 476] AH00098: pid file C:/Apache24/logs/httpd.pid overwritten -- Unclean shutdown of previous Apache run?
Вот так как-то.
Взял один небольшой кусок с конца, всё в принципе одинаково
[Fri Mar 11 12:14:58.650106 2016] [mpm_winnt:notice] [pid 2600:tid 436] AH00354: Child: Starting 64 worker threads.
[Fri Mar 11 12:26:28.069813 2016] [mpm_winnt:notice] [pid 5000:tid 476] AH00422: Parent: Received shutdown signal -- Shutting down the server.
[Fri Mar 11 12:26:30.097817 2016] [mpm_winnt:notice] [pid 2600:tid 436] AH00364: Child: All worker threads have exited.
[Fri Mar 11 12:26:30.113417 2016] [mpm_winnt:notice] [pid 5000:tid 476] AH00430: Parent: Child process 2600 exited successfully.
AH00558: httpd.exe: Could not reliably determine the server's fully qualified domain name, using fe80::319a:fba7:ebdf:9a22. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd.exe: Could not reliably determine the server's fully qualified domain name, using fe80::319a:fba7:ebdf:9a22. Set the 'ServerName' directive globally to suppress this message
[Fri Mar 11 12:26:56.311471 2016] [core:warn] [pid 7880:tid 472] AH00098: pid file C:/Apache24/logs/httpd.pid overwritten -- Unclean shutdown of previous Apache run?
[Fri Mar 11 12:26:56.342671 2016] [mpm_winnt:notice] [pid 7880:tid 472] AH00455: Apache/2.4.18 (Win64) PHP/7.0.1 configured -- resuming normal operations
[Fri Mar 11 12:26:56.342671 2016] [mpm_winnt:notice] [pid 7880:tid 472] AH00456: Apache Lounge VC14 Server built: Dec 9 2015 11:13:29
[Fri Mar 11 12:26:56.342671 2016] [core:notice] [pid 7880:tid 472] AH00094: Command line: 'C:\\Apache24\\bin\\httpd.exe -d C:/Apache24'
[Fri Mar 11 12:26:56.342671 2016] [mpm_winnt:notice] [pid 7880:tid 472] AH00418: Parent: Created child process 5372
AH00558: httpd.exe: Could not reliably determine the server's fully qualified domain name, using fe80::319a:fba7:ebdf:9a22. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd.exe: Could not reliably determine the server's fully qualified domain name, using fe80::319a:fba7:ebdf:9a22. Set the 'ServerName' directive globally to suppress this message
[Fri Mar 11 12:26:56.654672 2016] [mpm_winnt:notice] [pid 5372:tid 436] AH00354: Child: Starting 64 worker threads.
[Fri Mar 11 12:30:20.208926 2016] [mpm_winnt:notice] [pid 7880:tid 472] AH00422: Parent: Received shutdown signal -- Shutting down the server.
[Fri Mar 11 12:30:22.236930 2016] [mpm_winnt:notice] [pid 5372:tid 436] AH00364: Child: All worker threads have exited.
[Fri Mar 11 12:30:22.268130 2016] [mpm_winnt:notice] [pid 7880:tid 472] AH00430: Parent: Child process 5372 exited successfully.
AH00558: httpd.exe: Could not reliably determine the server's fully qualified domain name, using fe80::319a:fba7:ebdf:9a22. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd.exe: Could not reliably determine the server's fully qualified domain name, using fe80::319a:fba7:ebdf:9a22. Set the 'ServerName' directive globally to suppress this message
[Fri Mar 11 12:34:51.121848 2016] [core:warn] [pid 8016:tid 476] AH00098: pid file C:/Apache24/logs/httpd.pid overwritten -- Unclean shutdown of previous Apache run?
А как перезапустить конкретно пхп?
Просто я обычно если что перезапускаю апач, он у меня службой сделан, я просто в консоли пишу net stop и net start.
Из твоего описания проблемы я тоже понять не могу.
Алсо, кроме медиа надо еще изучить тег meta viewport
Бутстрап далек от идеала. Например он ставит box-sizing: border-box и ломает всю стороннюю верстку, также использует имена классов без всяких нейспейсов - легко получить конфликт. Потому бутстрап годится только для простых проектов где он используется с самого начала.
Я вообще от него не в восторге.
>>683640
Отлаживай ошибку, запустив PHP в консоли:
c:\php\php.exe c:\tmp\1.php
Посмотри что выведет.
Скорее всего баг или какой-то библиотеки dll не хватает. Ты можешь программой dependency walker если не боишься посмотреть dll от PDO и что им нужно.
гугление показало что 1067 значит
> Error 1067; The process terminated unexpectedly.
То есть Апач падает. Надо бы проверить, какими компиляторами собраны Апач и PHP - совместимыми? Ну то есть когда ты скачиваешь, там ведь есть выбор VC9, VC11 - они должны быть одинаковыми для Апача и пхп
>>683668
php работает как модуль апача, то есть Апач подключает php как библиотеку в свой процесс.
Из твоего описания проблемы я тоже понять не могу.
Алсо, кроме медиа надо еще изучить тег meta viewport
Бутстрап далек от идеала. Например он ставит box-sizing: border-box и ломает всю стороннюю верстку, также использует имена классов без всяких нейспейсов - легко получить конфликт. Потому бутстрап годится только для простых проектов где он используется с самого начала.
Я вообще от него не в восторге.
>>683640
Отлаживай ошибку, запустив PHP в консоли:
c:\php\php.exe c:\tmp\1.php
Посмотри что выведет.
Скорее всего баг или какой-то библиотеки dll не хватает. Ты можешь программой dependency walker если не боишься посмотреть dll от PDO и что им нужно.
гугление показало что 1067 значит
> Error 1067; The process terminated unexpectedly.
То есть Апач падает. Надо бы проверить, какими компиляторами собраны Апач и PHP - совместимыми? Ну то есть когда ты скачиваешь, там ведь есть выбор VC9, VC11 - они должны быть одинаковыми для Апача и пхп
>>683668
php работает как модуль апача, то есть Апач подключает php как библиотеку в свой процесс.
Я же написал выше. Тебе надо сделать файл bootstrap.php чтобы после его подключения автозагрузка люых классов работала. Если что-то непонятно, то задавай учтоняющие вопросы. Я этот файл за тебя не напишу.
Примеры можешь погуглить в сети.
>>678252
Твой код в посте не выдаст никаких ошибок. Добавлять элементы в массив можно.
>>678280
Нельзя обращаться к элементу если не уверен что он есть.
>>678289
Ответы в старом треде: >>682836 (1-е) >>682838 (2-е) >>682839 (4, 5, 6-е)
>>678291
Странная у тебя логика - не могу исправить ошибку, давайте просто их игнорировать.
>>678298
Посмотри, хуже от дополнительных источников не будет.
> Но уж если разработчики yii пошли таким путем, то и мне можно (жираф большой, ему видней).
Да там не все сделано правильно, разработчики Юи любят проявлять "оригинальность" в этом плане. Уверен что они просто не подумали о нескольких вкладках. Вот и думай, стоит ли поддерживать изначально не всегда работающий код или сделать какое-то свое решение, в идеале повторно испльзуемое расширение для Юи.
> Но "твой" способ (че-то я сомневаюсь, что вот прям сейчас это сам изобрел) действительно самый оптимальный. Если не учитывать замусоренность полученного урл.
Много где так делают. Да и я его не изобретал, а просто сравнил возможные варианты (гет/куки) и выбрал тот что получше.
> Как сказать. Теорию я неплохо знаю, все эти заголовки, методы. Помню пару месяцев назад мы вскрывали эту тему, ты мну даже заставлял формировать post запросы руками. С курлом знаком, с guzzle.
Ну ок, видимо действительно знаешь.
> Наверняка это какой-нибудь паттерн, которому даже дали глубокомысленное имя.
Не знаю. Вообще, гет-параметры предназначены для передачи дополнительных параметров на сервер, так что это как раз естественное их использование.
>>678789
1 сущность (студенты) = 1 таблица. Причин разбивать ее нет.
>>678795
В студентах нужна одна таблица.
>>678846
> if(is_array($answers))
Это лишний код.
> $arrayKey
Этой переменной не существует, ты не можешь ее использовать.Чтобы добавить элемент в массив, необязательно указывать ключ - перечитай урок про массивы например.
> а) Массив создаётся в функции и не является глобальным
да
> б) Всё можно реализовать более простым образом, но я всё испортил.
можно убрать бессмысленный if is_array и $arrayKey
> 3) Дальше я увидел, что вопросы прописываются уже в функции, но в примере вопрос №1 и вопрос №2 обозначаются одной переменной $q. Это же для простоты или я тупой?
После того как мы положили объект из переменной в массив, переменная нам не нужна и можно поместить в нее новый объект
> 4) Нужно ли указывать ключ при создании такого массива в рамках этой функции или всё можно отдать автоматическому назначению?
Не нужно. Зачем?
> 5) Но тогда какой толк от этой функции, если так собрать все вопросы в массив можно и без самого создания функции.
вынести код создания списка вопросов отдельно от остального. Код надо разбивать на части, а не писать стеной.
> Но уж если разработчики yii пошли таким путем, то и мне можно (жираф большой, ему видней).
Да там не все сделано правильно, разработчики Юи любят проявлять "оригинальность" в этом плане. Уверен что они просто не подумали о нескольких вкладках. Вот и думай, стоит ли поддерживать изначально не всегда работающий код или сделать какое-то свое решение, в идеале повторно испльзуемое расширение для Юи.
> Но "твой" способ (че-то я сомневаюсь, что вот прям сейчас это сам изобрел) действительно самый оптимальный. Если не учитывать замусоренность полученного урл.
Много где так делают. Да и я его не изобретал, а просто сравнил возможные варианты (гет/куки) и выбрал тот что получше.
> Как сказать. Теорию я неплохо знаю, все эти заголовки, методы. Помню пару месяцев назад мы вскрывали эту тему, ты мну даже заставлял формировать post запросы руками. С курлом знаком, с guzzle.
Ну ок, видимо действительно знаешь.
> Наверняка это какой-нибудь паттерн, которому даже дали глубокомысленное имя.
Не знаю. Вообще, гет-параметры предназначены для передачи дополнительных параметров на сервер, так что это как раз естественное их использование.
>>678789
1 сущность (студенты) = 1 таблица. Причин разбивать ее нет.
>>678795
В студентах нужна одна таблица.
>>678846
> if(is_array($answers))
Это лишний код.
> $arrayKey
Этой переменной не существует, ты не можешь ее использовать.Чтобы добавить элемент в массив, необязательно указывать ключ - перечитай урок про массивы например.
> а) Массив создаётся в функции и не является глобальным
да
> б) Всё можно реализовать более простым образом, но я всё испортил.
можно убрать бессмысленный if is_array и $arrayKey
> 3) Дальше я увидел, что вопросы прописываются уже в функции, но в примере вопрос №1 и вопрос №2 обозначаются одной переменной $q. Это же для простоты или я тупой?
После того как мы положили объект из переменной в массив, переменная нам не нужна и можно поместить в нее новый объект
> 4) Нужно ли указывать ключ при создании такого массива в рамках этой функции или всё можно отдать автоматическому назначению?
Не нужно. Зачем?
> 5) Но тогда какой толк от этой функции, если так собрать все вопросы в массив можно и без самого создания функции.
вынести код создания списка вопросов отдельно от остального. Код надо разбивать на части, а не писать стеной.
Очень просто. При обращении браузера к веб-серверу на веб-сервере запускается скрипт, и все что он выведет, отправляется в браузер (по умолчанию как HTML код).
>>678883
Пости код и задавай вопросы если что-то непонятно
>>678954
Скорее всего после исключения твой скрипт завершится, а при завершении открытые соединения закрываются.
>>678960
Нормально. Это специально так сделано.
Но вообще, если ты хочешь знать, в других языках вроде явы делают по другому. Там ведь приложение не завершается после обработки запроса, а ждет следующего запроса. Там делают объект - менеджер соединений, просят у него соединение, обрабатывают запрос, отдают назад. То есть код выглядит примерно так:
$connection = $connectionPool->getConnection();
try {
processrequest();
} finally {
$connectionPool->recycleConnection($connection);
}
То есть тут явно есть и выделение соединения и уничтожение. Конструкция finally позволяет сделать это даже при выбросе исключения (англ: https://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html )
>>678963
Не стоит им доверять. И деструкторы довольно непредсказуемая штука, лучше их не использовать лишний раз.
>>678969
Тут помог бы объект который управляет соединениями, выделяя их и забирая обратно. И переподсоединясь при необходимости. Преимущество в том что мы можем менять логику работы с соединениями не трогая остальной код.
Очень просто. При обращении браузера к веб-серверу на веб-сервере запускается скрипт, и все что он выведет, отправляется в браузер (по умолчанию как HTML код).
>>678883
Пости код и задавай вопросы если что-то непонятно
>>678954
Скорее всего после исключения твой скрипт завершится, а при завершении открытые соединения закрываются.
>>678960
Нормально. Это специально так сделано.
Но вообще, если ты хочешь знать, в других языках вроде явы делают по другому. Там ведь приложение не завершается после обработки запроса, а ждет следующего запроса. Там делают объект - менеджер соединений, просят у него соединение, обрабатывают запрос, отдают назад. То есть код выглядит примерно так:
$connection = $connectionPool->getConnection();
try {
processrequest();
} finally {
$connectionPool->recycleConnection($connection);
}
То есть тут явно есть и выделение соединения и уничтожение. Конструкция finally позволяет сделать это даже при выбросе исключения (англ: https://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html )
>>678963
Не стоит им доверять. И деструкторы довольно непредсказуемая штука, лучше их не использовать лишний раз.
>>678969
Тут помог бы объект который управляет соединениями, выделяя их и забирая обратно. И переподсоединясь при необходимости. Преимущество в том что мы можем менять логику работы с соединениями не трогая остальной код.
Примечания к задаче читал?
>>679013
> Как сабмитить форму,
Изучить какие хттп запросы отправляются
> Как запускать парсер раз в сутки
крон
> но я никак не могу найти описания как с ним работать.
гугли man cron и вообще, ты плохо гуглил, инфы полно: https://www.google.ru/search?q=работа+с+кроном&newwindow=1&gbv=1&sei=sqDiVsKRKeTt6AS587roCA
> Он уже стоит на самом хостинге, как с ним можно взаимодействовать?
Либо командная строка и команда crontab либо на хостинге есть панель для добавления задач, что хуже.
То для fpm.
Погугли по тексту ошибки.
http://serverfault.com/questions/77747/apache-unclean-shutdown-of-previous-apache-run
Закомментируй или поудаляй то что ты накопипастил в php.ini, нужны только 2 строчки
extension=php_pdo.dll
extension=php_pdo_mysql.dll
Ты походу наподключал что-то лишнее, поэтому падает.
Соединяешься и читаешь данные из соединения через fread или socket_read, пишешь в файл через fwrite.
> Я имел ввиду запуск сокет сервера (для его работы же нужен демон?) и запуск сокет клиента на ява скрипте.
Я вроде писал выше: чтобы браться за вебсокеты, надо изучить обычные сокеты Беркли. И как устроен интернет, и что такое TCP/IP.
Вот: устройство интернета, IP, DNS -> TCP/IP, сокеты, порты -> HTTP -> вебсокеты -> { протоколы поверх веб-сокетов вроде WAMP, также почитать про JSON-RPC, асинхронное программирование на PHP }
> Про мемкеш тоже не понял, что за команды
У мемкеша есть текстовый протокол, по которому клиент соединяется с сервером и посылает команды. Ты бы мог реализовать свой сервер который поддерживает эти команды.
Описание протокола нагуглишь?
>>680134
Он ошибается. Ты изучаешь сокеты и тебе лчше работать с ними напрямую а не через обертки. Обертки - это streams, их тоже конечно полезно изучить, это абстракция над любыми потоками в пхп.
>>683697
Не знаю. Напиши ссылку на пост с вопросом на всякий случай.
> Не знаю. Напиши ссылку на пост с вопросом на всякий случай.
Ну ты вроде по порядку идешь. Думаю, наткнешься. Я сейчас не могу искать, я на работе, вдруг босс спалит, что я двачую.
В чем заключается клевость убунты? Разноцветные менюшечки?
Через вагрант еще удобно, можно настроить так, что файлы проекта на хосте, с ними можно работать в уютной иде, а сервера и прочий служебный софт на виртуалке без графики.
Пробросить порты так, чтобы можно было обращаться из адресной строки браузера к приложению которое обслуживает сервер на виртуалке.
Я имею ввиду работать в phpstorm и просматривать свое приложение в браузере в основной операционной системе, а сервера ставить на виртуальную машину, к которой обращаться по ssh.
>>683751
Имеет ввиду две операционные системы рядом. Но это неудобно, каждый раз перезагружаться.
В ОП-пасте треда вёрстки в /wrk/ есть примеры.
А ты видеокарту ей пробросил? Надо чтобы у тебя была видеокарта с актуальными драйверами, в настройках виртуалки было включено 3д-ускорение и в гостевой Убунте стояли Virtual box guest additions:
http://askubuntu.com/questions/139320/enable-graphics-card-in-virtual-box/139322#139322
(правда ссылка старая)
Я запускал не так давно убунту на реальном железе, вроде не особо томрозит, правда грузится долго, минуты две, я конечно к такому не привык. А дебиан грузится до экрана логина терпимо (почти как винда), но логинитсяч чуть ли не минуту - такое ощущение что они просто перенесли запуск всяких сервисов на попозже.
И память там надо минимум мегабайт 700-800.
>>683707
Если по порядку то отвечу когда дойду - сейчас я на 7 марта остановился.
>>683759
Я использую дебиан без графики, а файлы внутрь закачиваю через rsync.
>для запросов пришедших на интерфейс 127.0.0.1 подходит только последний блок. И выбирать можно только из него.
Так а ты глянул вторую ссылку? Я там и попробовал, стало еще хуже
>Может быть виртуал хост может соответсовать нескольким IP?
Чем это отличается от моего варианта? Мой только длиннее. Или это типа "разное"? На фоне фактической незначимости различий между СерверНэймом и СерверАлиасом как-то странно даже.
Но я попробовал переделать:
http://pastebin.com/ftNqPwTX
Все так же, как во втором варианте, осталось.
rsync именно синхронизирует, т.е. создает копию файлов?
Можно же расшарить папку и сделать на нее ссылку в гостевой системе.
Или тут есть подводные камни?
Обычно делаю так:
root /home/vagrant/www/example.com
или DocumentRoot /home/vagrant/www/example.com для апача
Где /home/vagrant/www/example.com ссылка на /vagrant/example.com, который в свою очередь указывает на расшаренную папку на хосте, где содержится Vagrantfile.
В самом Vagrantfile проброс порта config.vm.network "forwarded_port", guest: 80, host: 8080
Выглядит запутанно, но есть возможность спокойно работать в основной операционной системе с файлами проекта, и тут же тестить его в браузере.
Если нужно сменить версию php или еще что, переключаемся на другую машину с соответствующим окружением.
rsync копирует измененные файлы в виртуальную машину.
Расшаренные папки, говорят, намного медленнее, хотя я не проверял.
Вагрант для этого вообще не нужен - виртуалбокс умеет расшаривать папки.
Я зашел на секретный сайт google.com и ввел "opencart документация", выдало такие ссылки:
http://docs.opencart.com/developer/module/
http://docs.myopencart.com/index.php?title=Руководство_Разработчика
http://forum.opencart-russia.ru/threads/rukovodstvo-razrabotchika.14/
http://woo.zp.ua/opdoc/articles_admin/
По ссылкам нужно перейти и прочитать что там написано. После прочтения осмыслить, применить полученные знания на практике.
Отпишись потом на каком пункте возникли сложности.
OpenCart кстати написан на php, если ты знаешь php, можно прочитать его исходный код и самостоятельно разобраться.
Сделай
c:\apache\httpd.exe -t
чтобы проверить синтаксис. Исправь возникшие замечания.
Далее сделай
......httpd.exe -t -D DUMP_VHOSTS
Чтобы просмотреть как Апач понял твой конфиг.
А ты неплох.
>OpenCart кстати написан на php, если ты знаешь php, можно прочитать его исходный код и самостоятельно разобраться.
Если бы не количество наследований, методов и мое недостаточное понимание ООП. Так, например, если с представлением особых проблем нет, понимать логику в контроллере для меня слишком сложно. Что говорить, если я даже не знаю, где описан метод класса, перебирая файлы по порядку.
Тебе нужно искать на офсайте раздел вроде developers, developer docs. Вот я зашел http://docs.opencart.com/ и вижу
- слева раздел developer
- снизу список книг
Все конечно на англйиском.
>>683876
> Если бы не количество наследований, методов и мое недостаточное понимание ООП.
Значит у тебя пока недостаточно знаний чтобы писать расширения для опенкарта, если ты не можешь читать его код. А ты решал наши задачи на ООП? Вектор? Кошки-мышки? Студентов?
> Что говорить, если я даже не знаю, где описан метод класса, перебирая файлы по порядку.
Используй IDE которая умеет по клику переходить к определению или Sublime 3 который тоже это умет.
> если я даже не знаю, где описан метод класса, перебирая файлы по порядку.
Ну и вообще тут можно было бы подумать логически:
- определяем какого класса объект перед нами
- по имени класса понимаем в каком он файле
- переходим туда и ищем метод
Параллеьно можно на бумажке или где-то еще рисовать схему классов.
Мне неудобно тебя просить, но после безрезультативного долгого скролинга запросов how to switch fastcgi to apache2handler я отчаялся, погугли пожалуйста. Я не очень силен в техническом английском чтобы одолеть их документацию. Это проблема точно в пхпшторме, я запускал php скрипт с пхпифно из htdocs в папке апача и там server api был apache 2 handler.
Блядь. 127.0.0.1:80 перезаписан другим 127.0.0.1, возможно, вам следует поюзать вот эту шнягу http://httpd.apache.org/docs/2.2/mod/core.html#namevirtualhost
Нихуя не понял, зачем она нужна, видимо, моего инглиша не хватает, либо доки слишком техничны и рассчитывают, что смысл написанного мне станет ясен. Таких два предупреждения (одинаковых). Синтаксис - ок.
Тем не менее ты получил ответ на вопрос почему. NameVirtualHost разрешает использовать для данных IP и порта поиск по имени. Если ип\порт там не прописаны - для них поиск по имени не делается.
Но как?
Нужно сначала набрать sudo rm -rf / --no-preserve-root и ввести пароль, тогда сможешь создавать везде.
А ты остряк
>NameVirtualHost разрешает использовать для данных IP и порта поиск по имени. Если ип\порт там не прописаны - для них поиск по имени не делается
Я ни черта не понял.
Что и куда я должен дописать к >http://pastebin.com/ftNqPwTX
?
Можно, если ты не на стадии изучения основ работы с mysql. Если начинающий - используй командную строку. Я сам ей пользуюсь - все равно для выборок которые мне нужны в админере придется писать запрос руками.
>>684073
Смотри:
https://httpd.apache.org/docs/2.2/vhosts/name-based.html
> To use name-based virtual hosting, you must designate the IP address (and possibly port) on the server that will be accepting requests for the hosts. This is configured using the NameVirtualHost directive
Ты обязан указать IP на который приниамются запросы, чтобы использовать виртуальные хосты с разными именами. Это делается директивой NameVirtualHost.
> The argument to the <VirtualHost> directive must match a defined NameVirtualHost directive.
Аргумент для VirtualHost должен соответствовать аргументу директивы NameVirtualHost.
далее:
https://httpd.apache.org/docs/2.2/mod/core.html#namevirtualhost
> The NameVirtualHost directive is a required directive if you want to configure name-based virtual hosts.
Если ты не записал пару ИП/порт в namevirtualhost virtualhost с этой парой не будет рассматриваться при поиске каким хостом обработать запрос.
Смотрю видео, там 3 строки есть, но там для 5 пхп. Скиньте строки для 7 версии.
ААААА. Вообще нихрена не понятно, чувак!
>Ты обязан указать IP на который приниамются запросы
Ну, указал звезду и локалхост
>Это делается директивой NameVirtualHost.
Но нет же, это делается аргументом VirtualHost!
>Аргумент для VirtualHost должен соответствовать аргументу директивы NameVirtualHost.
Гуда сам этот нэймвиортуалхост девать-то? И зачем вообще?
>Если ты не записал пару ИП/порт в namevirtualhost virtualhost с этой парой не будет рассматриваться при поиске каким хостом обработать запрос.
А это еще зачем? Мне же наоборот нужно, чтобы искал.
>php 7
https://wiki.archlinux.org/index.php/Apache_HTTP_Server#Configuration
Посмотри это, например.
Меня обосрали, сказали использовать DOM. Покурил DOM, охуел с его многословности, охуел с засовывания всей DOM-структуры в память ради малейшего чиха.
Проще говоря, DOM выглядит стрелянием пушкой по воробьям. Нет, серьезно, в веб-ориентированном языке PHP не завезли валидации и чистки html из коробки, одним методом. Извольте вывалить в память кучи объектов элементов и ходить по ним циклом.
Теперь передо мной встала еще более амбициозная задача - удалять из тегов все атрибуты, кроме разрешенных.
Под спойлером моя рваная жопа.
СНАЧАЛА СОЗДАЙ ОБЪЕКТ ДОМ-ДОКУМЕНТ, СКОРМИ ЕМУ HTML
ЧЕ, ДУМАЛ ЩА ВСЕ БУДЕТ? ХУЙ!
СОЗДАЙ ОБЪЕКТ XPATH НА ОСНОВЕ DOM-ДОКУМЕНТА
ТЕПЕРЬ У ТЕБЯ DOM-ДЕРЕВО, В КОТОРОМ АТТРИБУТЫ ТОЖЕ ДЕТИ ЭЛЕМЕНТА
ЧЕ, ДУМАЛ ЩА ВСЕ БУДЕТ? ХУЙ!
С ПОМОЩЬЮ ЯЗЫКА ЗАПРОСОВ XPATH ЗАМАТЧЬ ВСЕ АТТРИБУТЫ ЗАПРОСОМ ВИДА //@звездочка
ПРОЙДИСЬ ЦИКЛОМ ПО ВСЕМ АТРИБУТАМ
УДАЛИ ВСЕ ОБЪЕКТЫ-АТРИБУТЫ С НЕНУЖНЫМИ NODENAME
СГЕНЕРИРУЙ НОВЫЙ HTML-КОД НА ОСНОВЕ ЭТОГО DOM-ДОКУМЕНТА
Так, ладно. Регулярки использовать нельзя, на стековерфлоу засмеют. О, есть сторонние модули, написанные на PHP. Уж лучше DOM.
Секунду, есть официальные инструменты от Zend! Ура, мое спасение!
http://framework.zend.com/svn/framework/standard/trunk/library/Zend/Filter/StripTags.php
Ой, а что там внутри. Там - РЕГУЛЯРНЫЕ ВЫРАЖЕНИЯ
КОТОРЫЕ НЕ СМАТЧАТ ВАЛИДНЫЙ АТРИБУТ ТИПА <span class=test>
И ДАЖЕ В <input type="text" required> REQUIRED НЕ ЗАМАТЧИТСЯ
Короче, пацаны, это пиздец.
Сейчас сяду писать свой чистильщик, который будет чистить-чистить-чистить за один цикл, без регэкспов.
На машине состояний, как советовал мне анон, поэтому пятиэтажных if не будет.
Меня обосрали, сказали использовать DOM. Покурил DOM, охуел с его многословности, охуел с засовывания всей DOM-структуры в память ради малейшего чиха.
Проще говоря, DOM выглядит стрелянием пушкой по воробьям. Нет, серьезно, в веб-ориентированном языке PHP не завезли валидации и чистки html из коробки, одним методом. Извольте вывалить в память кучи объектов элементов и ходить по ним циклом.
Теперь передо мной встала еще более амбициозная задача - удалять из тегов все атрибуты, кроме разрешенных.
Под спойлером моя рваная жопа.
СНАЧАЛА СОЗДАЙ ОБЪЕКТ ДОМ-ДОКУМЕНТ, СКОРМИ ЕМУ HTML
ЧЕ, ДУМАЛ ЩА ВСЕ БУДЕТ? ХУЙ!
СОЗДАЙ ОБЪЕКТ XPATH НА ОСНОВЕ DOM-ДОКУМЕНТА
ТЕПЕРЬ У ТЕБЯ DOM-ДЕРЕВО, В КОТОРОМ АТТРИБУТЫ ТОЖЕ ДЕТИ ЭЛЕМЕНТА
ЧЕ, ДУМАЛ ЩА ВСЕ БУДЕТ? ХУЙ!
С ПОМОЩЬЮ ЯЗЫКА ЗАПРОСОВ XPATH ЗАМАТЧЬ ВСЕ АТТРИБУТЫ ЗАПРОСОМ ВИДА //@звездочка
ПРОЙДИСЬ ЦИКЛОМ ПО ВСЕМ АТРИБУТАМ
УДАЛИ ВСЕ ОБЪЕКТЫ-АТРИБУТЫ С НЕНУЖНЫМИ NODENAME
СГЕНЕРИРУЙ НОВЫЙ HTML-КОД НА ОСНОВЕ ЭТОГО DOM-ДОКУМЕНТА
Так, ладно. Регулярки использовать нельзя, на стековерфлоу засмеют. О, есть сторонние модули, написанные на PHP. Уж лучше DOM.
Секунду, есть официальные инструменты от Zend! Ура, мое спасение!
http://framework.zend.com/svn/framework/standard/trunk/library/Zend/Filter/StripTags.php
Ой, а что там внутри. Там - РЕГУЛЯРНЫЕ ВЫРАЖЕНИЯ
КОТОРЫЕ НЕ СМАТЧАТ ВАЛИДНЫЙ АТРИБУТ ТИПА <span class=test>
И ДАЖЕ В <input type="text" required> REQUIRED НЕ ЗАМАТЧИТСЯ
Короче, пацаны, это пиздец.
Сейчас сяду писать свой чистильщик, который будет чистить-чистить-чистить за один цикл, без регэкспов.
На машине состояний, как советовал мне анон, поэтому пятиэтажных if не будет.
Хм. Бред, но апач отказывается принимать для NameVirtualHost два аргумента, НО можно написать два раза с разными аргументами. Но тогда вскрывается интересный тупняк: ServerAlias localhost 127.0.0.1 все равно отправляют меня на дефолт сервер, хотя server - туда, куда я его просил в последнем файле. Попробовал указать server в качестве ServerName, а не первым ServerAlias, ничего не поменялось.
Мне от этой ссылки толку 0. Я смотрел как установить апач и пхп по этому видео
https://www.youtube.com/watch?v=bnuAD3b5t9c
и под конец установки вывело ошибку 1 в консоли, когда уже запускал через net start apache2.4
чёт сажа приклеилась
А ты документацию прочел? По всем упомянутым директивам?
NameVirtualHost включает поддержку name-based virtual hosts (виртуальных хостов, определяющихся по имени) для данного IP (и при указании, порта). Если ты там не указал какой-то IP, который испльзуется в VirtualHost то эти VirtualHost не будут работать для данного IP. О чем тебе апач и пишет при проверке конфига.
В этом видео https://www.youtube.com/watch?v=Lr_WBVMvO4I говорят мол нужно найти в netstat -a -o 0.0.0.0.:80, а у меня его тупо нет! Ну что за день, целый день то базы данных не подключались, решил переустановить, так не запускается вообще. Что с этим ебаным апачем.
Пытаясь написать что это PHP плохой и виноват, ты лишь демонстрируешь свой низкий уровень знания PHP.
Вот смотри, у тебя есть задача написать код делающий X. Вместо того чтобы исплоьзовать предназначенные для этого инструменты, ты пишешь велосипед, который иногда (с неизвестной вероятностью) работает. ПРичем проверить код тоже сложно так как он написан одной большой стеной с кучей вложенных ифов. Вот что ты получил:
- неизвестного качества код вместо проверенного огромным числом пользователей
- лишнее потраченное время на написание с нуля
- код который никто не захочет потом поддерживать
Зря потратил деньги твоего работодателя проще говоря.
> засовывания всей DOM-структуры в память ради малейшего чиха.
Ты мерял или диванной оптимизацией решил заняться? И вообще если тебе нужна высокая производительность, почему ты не на Си++ или яве пишешь а на PHP? И кстати DOM написан на Си.
> СОЗДАЙ ОБЪЕКТ XPATH НА ОСНОВЕ DOM-ДОКУМЕНТА
> ТЕПЕРЬ У ТЕБЯ DOM-ДЕРЕВО, В КОТОРОМ АТТРИБУТЫ ТОЖЕ ДЕТИ ЭЛЕМЕНТА
Ты же просто не осилил дом. Для удаления запрещенных тегов вообще-то xpath не требуется (хотя это штука удобная и полезная), ну то что атрибуты дети это никак не мешает. Ну напиши еще пару постов какой дом плохой, это же полезнее чем читать документацию.
Корректно обрабатывать HTML от пользователя можно толкьо одним способом:
- распарсить в дерево
- обработать дерево
- собрать новый HTML
Других способов я не знаю.
> О, есть сторонние модули, написанные на PHP
Есть какой-то хороший модуль, парсящий HTMl в дерево но я забыл название.
> Ой, а что там внутри
> КОТОРЫЕ НЕ СМАТЧАТ ВАЛИДНЫЙ АТРИБУТ
Так он и назвается StripTags а не StripAttributes же. Но подход конечно плохой.
>>684280
Там в документации что-то написано про то что дефолтный хост не ищется среди VirtualHost участвующих в name-based virtual host или как-то так. Он настраивается на верхнем уровне, не внутри VirtualHost.
Согласен, переусложненная штука но ты ведь документацию не читаешь внимательно и сам себе усложняешь жизнь. ну и теперь ты станешь лучше в апаче разбираться, как мне кажется.
Пытаясь написать что это PHP плохой и виноват, ты лишь демонстрируешь свой низкий уровень знания PHP.
Вот смотри, у тебя есть задача написать код делающий X. Вместо того чтобы исплоьзовать предназначенные для этого инструменты, ты пишешь велосипед, который иногда (с неизвестной вероятностью) работает. ПРичем проверить код тоже сложно так как он написан одной большой стеной с кучей вложенных ифов. Вот что ты получил:
- неизвестного качества код вместо проверенного огромным числом пользователей
- лишнее потраченное время на написание с нуля
- код который никто не захочет потом поддерживать
Зря потратил деньги твоего работодателя проще говоря.
> засовывания всей DOM-структуры в память ради малейшего чиха.
Ты мерял или диванной оптимизацией решил заняться? И вообще если тебе нужна высокая производительность, почему ты не на Си++ или яве пишешь а на PHP? И кстати DOM написан на Си.
> СОЗДАЙ ОБЪЕКТ XPATH НА ОСНОВЕ DOM-ДОКУМЕНТА
> ТЕПЕРЬ У ТЕБЯ DOM-ДЕРЕВО, В КОТОРОМ АТТРИБУТЫ ТОЖЕ ДЕТИ ЭЛЕМЕНТА
Ты же просто не осилил дом. Для удаления запрещенных тегов вообще-то xpath не требуется (хотя это штука удобная и полезная), ну то что атрибуты дети это никак не мешает. Ну напиши еще пару постов какой дом плохой, это же полезнее чем читать документацию.
Корректно обрабатывать HTML от пользователя можно толкьо одним способом:
- распарсить в дерево
- обработать дерево
- собрать новый HTML
Других способов я не знаю.
> О, есть сторонние модули, написанные на PHP
Есть какой-то хороший модуль, парсящий HTMl в дерево но я забыл название.
> Ой, а что там внутри
> КОТОРЫЕ НЕ СМАТЧАТ ВАЛИДНЫЙ АТРИБУТ
Так он и назвается StripTags а не StripAttributes же. Но подход конечно плохой.
>>684280
Там в документации что-то написано про то что дефолтный хост не ищется среди VirtualHost участвующих в name-based virtual host или как-то так. Он настраивается на верхнем уровне, не внутри VirtualHost.
Согласен, переусложненная штука но ты ведь документацию не читаешь внимательно и сам себе усложняешь жизнь. ну и теперь ты станешь лучше в апаче разбираться, как мне кажется.
на винде надо запускать netstat -abn из-под администратора. Там не обязательно будет написано именно 0.0.0.0:80
Чтобы пользоваться netstat надо понимать что такое TCP порты, как они выделяются и тд.
>Там в документации что-то написано про то что дефолтный хост не ищется среди VirtualHost участвующих в name-based virtual host или как-то так. Он настраивается на верхнем уровне, не внутри VirtualHost.
Что? Погоди. Нихрена же не исправилось до конца. Я по 127.0.0.1 и localhost попадаю на дефолтное говно, а не куда его прошу. Где это настраивается, если не там? И как?
>в документации что-то написано про то что дефолтный хост не ищется среди VirtualHost участвующих в name-based virtual host или как-то так.
>но ты ведь документацию не читаешь внимательно
А как этот тупняк можно нормально читать, если еще и с английским проблемы, особенно? Я вообще запутался уже, блеать.
Ура, заработало!
Я дебил, в конфиге когда правил 5 на 7 пхп, кое-что не убрал. Уже больше часа сижу злой как собака, думаю что не так.
Теперь буду решать основную проблему, над которой сижу весь день - подключение к mysql.
>ты пишешь велосипед, который иногда (с неизвестной вероятностью) работает
>проверить код тоже сложно так как он написан одной большой стеной с кучей вложенных ифов
Код еще не написан, в нем не будет кучи вложенных if.
Тесты ты мне уже сбрасывал, так что стопроцентное их покрытие я обеспечу.
>диванной оптимизацией
this
Пока что мне нечего мерить. Вот напишу свой мегагиперпорсир, тогда можно будет запустить DOM в 100к оборотов, и мой метод.
Заодно использование памяти в сравнении увижу.
>DOM написан на Си
Было бы странно, будь это не так.
>Для удаления запрещенных тегов вообще-то xpath
Да, для этого есть strip_tags, где под капотом нет DOM, судя по намекам в документации.
Мне нужно удалять атрибуты.
>Есть какой-то хороший модуль, парсящий HTMl
HTMLPurifer?
Удачи.
А, там написано Note: MySQL Installer is 32 bit, but will install both 32 bit and 64 bit binaries.
да, пьюрифайер, вроде он. Когда мне надо было чистить HTML, я может даже его использовал, не помню правда точно.
> Вот напишу свой мегагиперпорсир
Тогда пиши его хотя бы по-человечески: раздели отдельно разбор HTML и фильтрацию, то есть принятие решения что делать с тегом или атрибутом.
>>684328
Я сейчас провел эксперимент:
- apache2.2
<VirtualHost 127.0.0.1:10000 x:10000>
ServerName host1
<VirtualHost x:10000>
ServerName host2
<VirtualHost 127.0.0.1:10000>
ServerName host3
- написал баш скрипт который получает на вход IP и имя - куда коннектиться и какой заголовок Host: послать
- тестируем:
for ip in {127.0.0.1,192.168.56.1}; do for host in {host1,host2,host3} ; do ./conn.sh $ip $host ; done ; done
IP 127.0.0.1 HOST host1
Connection to 127.0.0.1 10000 port [tcp/] succeeded!
VH1
IP 127.0.0.1 HOST host2
Connection to 127.0.0.1 10000 port [tcp/] succeeded!
VH1
IP 127.0.0.1 HOST host3
Connection to 127.0.0.1 10000 port [tcp/] succeeded!
VH3
IP 192.168.56.1 HOST host1
Connection to 192.168.56.1 10000 port [tcp/] succeeded!
VH1
IP 192.168.56.1 HOST host2
Connection to 192.168.56.1 10000 port [tcp/] succeeded!
VH2
IP 192.168.56.1 HOST host3
Connection to 192.168.56.1 10000 port [tcp/] succeeded!
VH1
то есть дефолтный хост все равно первый. Почему - надо смотреть документацию, а мне лень.
да, пьюрифайер, вроде он. Когда мне надо было чистить HTML, я может даже его использовал, не помню правда точно.
> Вот напишу свой мегагиперпорсир
Тогда пиши его хотя бы по-человечески: раздели отдельно разбор HTML и фильтрацию, то есть принятие решения что делать с тегом или атрибутом.
>>684328
Я сейчас провел эксперимент:
- apache2.2
<VirtualHost 127.0.0.1:10000 x:10000>
ServerName host1
<VirtualHost x:10000>
ServerName host2
<VirtualHost 127.0.0.1:10000>
ServerName host3
- написал баш скрипт который получает на вход IP и имя - куда коннектиться и какой заголовок Host: послать
- тестируем:
for ip in {127.0.0.1,192.168.56.1}; do for host in {host1,host2,host3} ; do ./conn.sh $ip $host ; done ; done
IP 127.0.0.1 HOST host1
Connection to 127.0.0.1 10000 port [tcp/] succeeded!
VH1
IP 127.0.0.1 HOST host2
Connection to 127.0.0.1 10000 port [tcp/] succeeded!
VH1
IP 127.0.0.1 HOST host3
Connection to 127.0.0.1 10000 port [tcp/] succeeded!
VH3
IP 192.168.56.1 HOST host1
Connection to 192.168.56.1 10000 port [tcp/] succeeded!
VH1
IP 192.168.56.1 HOST host2
Connection to 192.168.56.1 10000 port [tcp/] succeeded!
VH2
IP 192.168.56.1 HOST host3
Connection to 192.168.56.1 10000 port [tcp/] succeeded!
VH1
то есть дефолтный хост все равно первый. Почему - надо смотреть документацию, а мне лень.
> >IP 127.0.0.1 HOST host2
> >Connection to 127.0.0.1 10000 port [tcp/] succeeded!
> >VH1
> Вот это как-то вообще не правильно.
Это правильно так как host2 доступен только с адресов кроме 127.0.0.1, в мануале написано что при поиске по IP ищется наиболее специфичное соответсвие, раз есть хосты где указан 127.0.0.1 то хосты со звездочкой не трогаются.
> И что мне делать-то?
Можно подождать пока кто-нибудь прочитает ее за тебя. Или просто поставить дефолтный хост первым.
Ну наканецта, прогресс, таки подключило драйвера(хоть ошибку в коде и выводит, но радует что фиксятся потихоньку ошибки):
>Можно подождать пока кто-нибудь прочитает ее за тебя
Обижаешь, я как будто не читал. Если бы я мог решить эту хуйню сам, я бы не пришел в тред. А, да, со вторым еще более-менее понятно. Но у меня поинтереснее случай.
Два хоста <VirtualHost 127.0.0.1:80 х:80>
и один хост чисто 127.0.0.1. И в нем локалхост и 127.0.0.1. Локалхост и адрес локалхоста не могут быть именами сервера или его алиасами? Тогда куда их девать?
$a = 'хуй'; $b = 0;
var_dump($a == true && $b == false && $a == $b);
KhanAkademy, w3schools
Если
>чисто 127.0.0.1
Стоит самым первым - куда надо коннектиться по server и 127.0.0.1, но по localhost все равно к первому среди х:80. Чому так?
А если
>чисто 127.0.0.1
НЕ первым, то и по 127.0.0.1 тоже коннектится к первому среди х:80, но по server по-прежнему куда надо. Магия какая-то. Напрашивается вывод, что 127.0.0.1 не считается именем хоста вообще, а локалхост идет не прямым редиректом на 127.0.0.1. Или это просто все где-то в другом месте понахуеверчено, я даже не знаю.
>>684491
Оператор == сначала приводит операнды к одному типу (в данном случае к числу), затем сравнивает полученные значения.
Приведение строки к числу описано здесь http://php.net/manual/ru/language.types.string.php#language.types.string.conversion
>Значение определяется по начальной части строки. Если строка начинается с верного числового значения, будет использовано это значение. Иначе значением будет 0 (ноль).
Используй строгое сравнение ===.
Смело посылай в тех эйчаров, которые морочат голову такими заданиями.
>Как через pdo подключиться к существующей БД
https://habrahabr.ru/post/137664/ здесь это написано в самом начале.
>или создать новую БД ?
Это еще зачем?
Из консоли такие вещи нужно запускать. Браузер предназначен для просмотра веб-страничек, а не запуска говнокода.
Собственно скрипт в браузере по-умолчанию не может выполняться дольше 30 секунд http://php.net/manual/ru/function.set-time-limit.php
У тебя видимо выставлено около 20 минут set_time_limit(1200);
>Что посоветуете?
Сменить профессию. Смотреть логи сервера.
function huita()
{
huita;
}
А не относящееся к ООП вот так:
function atmta(){
atmta;
}
Рекомендуется, но обязательно. Хорошо, я понял.
Забаскрипт. Вообще без вариантов.
Про тебя. ДИВАНОН@ЛИГИВОН
Алсо, тесты на XSS просто удивительны. Часть нерабочая сама по себе, часть работает на седьмом эксплорере и вообще в нетскейпе.
В общем, вот - http://ideone.com/jyvubq
Пародия на машину состояний прилагается.
На пике великий и могущественный DOM в работе.
Алсо, $dom->saveHTML() добавляет к html-коду доктайп и head с body. I never asked for this, мне это руками отрезать?
Ну и насчет сравнения.
DOM в 15 раз быстрее моей поделки. Лол.
С помощью лома, консоли mysql и какой-то матери я таки вывел! Правда, не ч-з pdo, а через mysqli. На w3schools нашел работающий код и вывел свою базу, которую создал не через простенькое приложение с интерфейсом, а ручками!!!
Как же я рад, тут была целя эпопея с переустановкой пхп и апача, оно не работало, я психовал, апач не хотел перезагружаться когда раскомментировал, но таки РА БО ТА ЕТ! Можно изучать дальше и пробовать пилить авторизацию в свой блог и дипломку.
Ты у меня спрашиваешь?
Если да, то я не знаю, я только вникаю в php, вот получилось вывести данные с таблицы через mysqli, с pdo тоже надо будет разобраться.
А, ну в таком случае надо будет с пдо разобраться. Я просто рад, что есть результат - вывод данных на странице.
напиши план плз поэтапного развития навыков в пхп с максимальной эффективностью(минуя пока математику).
Чтоб можно было претендовать на юниора по пхп.
Моя бабка поехала умом и я в ускоренном режиме съехал. У меня теперь даже интернета нет, только книги и ноут с сумкой вещей, да и денег нет. Есть две недели пока я вписался к другу и затем еще месяц будет. Т.е. сроков у меня ровно 1.5 месяца чтобы стать юниором по пхп и найти работу. ~350 свободных часов.
Базовые знания по пхп и мусклю имею
спасибо :*
Вот в есть учебник ОП'а http://archive-ipq-co.narod.ru/, там как раз основы - теория и задачки минимальные.
И также более сложные задачки тоже есть.
Почитай поподробнее шапку в ОП-посте. Там есть много полезной информации. Кто-то тут писал, что прошел учебники опа по пхп, хтмл, ксс и джс, сделал сложные задания и в итоге пошел на собес и получил работу. Еще его учебник можешь скачать, чтобы сайт был уже у тебя на компе(ты писал что интернета у тебя нет).
А какие-нибудь видосы есть годные? Лекции там, уроки, чтобы с планшета смотреть. Много времени в дороге провожу, порядка полутора часов в сутки, было бы полезно тратить его на обучение.
другой ньюфаг
Глянь тут: https://www.youtube.com/channel/UCUzksGhlJU0rNF5KneUZkSA
Я тоже нюфаг, как-то надо было там ксс глянуть, там смотрел . Там пхп был точно.
Кстати, давно вопрос мучает: как лучше книги читать? Художку понятно, открыл и читай где угодно, но в литературе для программистов предполагается усваивание практических навыков.
Так все-таки книги лучше читать за компом, тут же применяя знания и упражняясь, или же читать побольше где угодно, а уже потом пробуя применить прочитанное на практике?
Ну надо же знать, что пейсать.
c хтмл и ксс проблем нет - я умею в жквери и дом шарю. Мне тут чисто пышку надо подтянуть на мидл, чтобы допиливать движочки или свои модули приписывать. Интернет есть пока, 4гб с телефона раздаю, но да, работать таки-лучше на локалхосте.
Ознакомился, марафон начал, через 10 дней потных усилий распишу как итог.
Когда я делаю переменную name полем - при запросе SELECT мне её не возвращает. Почитал документацию, понял что rt_field он только индексирует, но не возвращает, для возвращения нужно использовать атрибуты типа rt_attr_string (для других типов не string, соответственно).
Но вот в конфигурации обычного индекса я мог задать поля (sql_field_string) и атрибуты (sql_attr_uint), и при запросе SELECT мне возвращало поля и атрибуты, когда в realtime поля не возвращаются. Зачем они так сделали?
Я еще пробовал в realtime индексе сделать одну переменную атрибутом и полем одновременно, это работает, только запрос на вставку будет выглядеть вот так INSERT INTO realtime_index VALUES(1, 'Name', 'Name'); т.е. переменных все же две, но одна из них является полем, а вторая атрибутом. И если сделать так INSER INTO realtime_index(id, name) VALUES(1, 'Name'); то данные запишутся только в атрибут, а не в поле, что делает невозможным поиск с помощью MATCH. И вот тут ко мне приходит мысль что я с самого начала сделал неправильно, что поиск должен возвращать только id найденных элементов, а потом уже по этим id мне нужно выбирать полную информацию о файлах из базы данных. Но это уже порнография какая-то получается.
Где мои нюфажики с задачами на Айфон и Айпад, ну вот где?..
Ну чтоб умным себя чувствовать.
Я последнее, что сделал - задача на вывод чисел словами. Теперь мне просто влом. Думаю, начать css и html без дополнительных задач про, например, размещение алфавита по кругу.
Сфинкс это поисковый демон а не база данных. Ты не должен пытаться в нем что-то сохранять (так как он под это не заточен + ты получаешь проблему дублирования и устаревания данных).
> суть полей в realtime-индексах в сфинксе.
realtime индексы отличаются от обычных только тем что они оптимизированы под изменение (добавление и удаление) данных, но не очень подходят дял больших объемов. А обычные индексы нельзя быстро изменять (только переиндексацией или объединением индексов), зато они хорошо хранят огромные объекмы неизменяющихся данных.
> и при запросе SELECT мне возвращало поля и атрибуты, когда в realtime поля не возвращаются. Зачем они так сделали?
Скорее всего ты где-то ошибся.
> И вот тут ко мне приходит мысль что я с самого начала сделал неправильно, что поиск должен возвращать только id найденных элементов, а потом уже по этим id мне нужно выбирать полную информацию о файлах из базы данных.
Именно так. И если бы ты подумал, то понял что хранить одни и те же данные в нескольких местах плохая идея.
>>685074
Понятно. Я тот хуй, который пропустил бонусные задачи и перешел к ООП. Вертстку еще летом 2015 выучи. И движок JS осенью.
Неужели так интересно натягивать что-то на цмс? С нуля пилить же намного интересней.
Мне с дивана видней.
Когда надо сделать по-быстрому нет ничего лучше чем ЦМС, к тому же, сможешь ли ты самостоятельно сделать настолько удобную и продуманную админку как например в вордпресс?
И как, не сильно сказалось то, что бонусные задачи пропустил? Я их могу потом дорешать, в принципе.
Да хуй его знает, я ведь только-только начать читать мануал по ООП. Причем, советую читать официальные мануал, у ОПа не понятно нихуя. Так всегда бывает, когда гик в какой-нибудь области пытается что-то рассказать новичку и удивляется, что тот нихуя не понимает.
Если возьмусь, то смогу.
Ящитаю, что нужно сделать какие-нибудь свои шаблоны, которые уже впоследствии использовать для верстки, а не пиздить у каких-то даунов.
Good job!
Они смеются легко, у них живые глаза, они наверное не знают, что такое смерть.
плавнее некуда Профессиональное программирование на PHP Джордж Шлосснейгл
есть еще yank_php_i_mysql_ot_novichka_k_professionalu.pdf сразу на примере работы с mySQL, минимум теории
У тебя есть 15 дней, чтобы сделать КМС не хуже вордпресс, время пошло.
Сколько платишь?
Ничто не будет хуже вордпресс.
Книги по пхп? Ебанутый? Официальный мануал есть. Это более чем достаточно
Я доделываю макет из задач на HTML и CSS.
Про ООП у ОПа прочитал - ничего не понял, надо вникать.
Сейчас читаю книгу из серии О'Рейли, там пошагово описывается создание динамического сайта. Многое интересно, повторяю то, что узнал в мануале ОПа. Хотя ОП и не одобрил эту книгу: Роберт Никсон, "Создаём динамические веб-сайты на PHP...".
>>685108
ОП не вполне подготовил эти уроки, он пишет об этом, в этом ещё дело.
Вообще стоит прочитать пару книг, чтобы с другой стороны взглянуть. Я вижу, например, что действительно не вполне хорошо разбивать строку при выводе кавычками, как у Никсона, гораздо лучше и внятнее делать так, как советует ОП. Сравнивать же можно, базу ОП хорошую закладывает.
Да ладно, что ты, вечная весна уже наступила, нужно портвейн пить и блевать на почтенных похаперов.
Я там сделал так:
> $name = "$name$randomText";
как ещё можно сделать, чтоб отобранные в $randomText слоги суммировались в имя?
Их надо склеить, как в следующем уроке про строки?
> str_replace ("что", "на что", $где)
от
> strtr ($где, $чтоЗаменять, $наЧто)
???
Отличается типами данных. Стр_реплейс работает с массивами, а стртр со строками.
> http://ideone.com/qb5GV3 переделал задачку на айфон с использованием min/max
Ок, верно
> http://ideone.com/NW7mgR тоже переделал по рекомендациям любимых анонов
> $credit != 0
Я бы ставил условие "пока долг больше нуля" - так при нечаянном уходе в минус цикл не зациклится навечно.
А так, верно решено.
> http://ideone.com/eGEybu палиндром
Все правильно
> http://ideone.com/uWTryH изменение номера телефона в нужный формат
> "$q"
Кавычки тут лишние, название переменной не говорящее.
> (\D)
Скобки лишние
> \
Пробел не спецсимвол, экранировать не требуется
> (\ ?\+?7?)
У тебя плюс и семерка необязательны - значит он вставит 8 перед любым номером вообще, например http://ideone.com/MomgaO
Также, приучайся ставить флаг u всегда
> http://ideone.com/dD5gD8 поиск и авто замена разных вариаций слова дурак
> (\-|\(|\))
Это наверно проще в квадратных скобках писать как [\-()]
> (р|p|r)
Это тоже компактнее будет в квадратных скобках
> \ ?(\-|\(|\))?(д|d)
Непоняно зачем проверять наличие пробела перед "д"
> http://ideone.com/sW56Qy вывод всех встречающихся емейлов в тексте
> [a-z\ \.\-]+)
В имени домена не может быть пробелов, зато могут быть цифры.
> http://ideone.com/ze39mQ Grammar Nazi поиск ошибок в тексте
не видит пропущенного пробела после точки: http://ideone.com/jowGG3
Ты зря там поставил условие что должно быть ровно 10 символов. вот еще пример где ошибку не видит: http://ideone.com/QBy0F5
> (\w)
Скобки не требуются
> расказ
"расказал"
Ошибку о запятой перед "но" видит даже если все правильно: http://ideone.com/A5Mq6P
В общем тут что-то плохо, выражения написаны неправильно. Также, вместо 4 переменных надо сделать массив вида
[ выражение => объяснение ]
и обходить циклом.
> http://ideone.com/mamPIM авто замена ошибок найденных в тексте
> "!(\,)(\ )?!iu"
Зачем заменять если после запятой идет пробел? Надо искать случаи где его нет.
> "!(жы)!iu";
> "!(шы)!iu";
Это можно объединить в одну регулярку, как и правило с точкой и запятой, и правило с "а/но"
> \b\ ?но\b
Не сработает если там 2 пробела перед "но". Сработает ложно если перед "но" идет точка.
не надо заводить 7 однотипных переменных, надо использловать массив. также, не надо класть текст каждый раз в новую переменную с бессмысленными именами - это тольок запутывает - лучше использовать ту же самую.
> http://ideone.com/ap17y2 поиск "неумышленных" опечаток
> ([а-яё]+)?
Какой смысл ставить плюс, а за ним вопрос? Это то же самое что зведочка. Более того, твое выражение срабатывает не на слова со смешанными буквами, а тупо на все латинские буквы: http://ideone.com/umnWWy
Надо искать именно слова с буквами из 2 алфавитов.
В общем, надо тебе получше изучить регулярки - пока ты их не очень понимаешь.
> http://ideone.com/qb5GV3 переделал задачку на айфон с использованием min/max
Ок, верно
> http://ideone.com/NW7mgR тоже переделал по рекомендациям любимых анонов
> $credit != 0
Я бы ставил условие "пока долг больше нуля" - так при нечаянном уходе в минус цикл не зациклится навечно.
А так, верно решено.
> http://ideone.com/eGEybu палиндром
Все правильно
> http://ideone.com/uWTryH изменение номера телефона в нужный формат
> "$q"
Кавычки тут лишние, название переменной не говорящее.
> (\D)
Скобки лишние
> \
Пробел не спецсимвол, экранировать не требуется
> (\ ?\+?7?)
У тебя плюс и семерка необязательны - значит он вставит 8 перед любым номером вообще, например http://ideone.com/MomgaO
Также, приучайся ставить флаг u всегда
> http://ideone.com/dD5gD8 поиск и авто замена разных вариаций слова дурак
> (\-|\(|\))
Это наверно проще в квадратных скобках писать как [\-()]
> (р|p|r)
Это тоже компактнее будет в квадратных скобках
> \ ?(\-|\(|\))?(д|d)
Непоняно зачем проверять наличие пробела перед "д"
> http://ideone.com/sW56Qy вывод всех встречающихся емейлов в тексте
> [a-z\ \.\-]+)
В имени домена не может быть пробелов, зато могут быть цифры.
> http://ideone.com/ze39mQ Grammar Nazi поиск ошибок в тексте
не видит пропущенного пробела после точки: http://ideone.com/jowGG3
Ты зря там поставил условие что должно быть ровно 10 символов. вот еще пример где ошибку не видит: http://ideone.com/QBy0F5
> (\w)
Скобки не требуются
> расказ
"расказал"
Ошибку о запятой перед "но" видит даже если все правильно: http://ideone.com/A5Mq6P
В общем тут что-то плохо, выражения написаны неправильно. Также, вместо 4 переменных надо сделать массив вида
[ выражение => объяснение ]
и обходить циклом.
> http://ideone.com/mamPIM авто замена ошибок найденных в тексте
> "!(\,)(\ )?!iu"
Зачем заменять если после запятой идет пробел? Надо искать случаи где его нет.
> "!(жы)!iu";
> "!(шы)!iu";
Это можно объединить в одну регулярку, как и правило с точкой и запятой, и правило с "а/но"
> \b\ ?но\b
Не сработает если там 2 пробела перед "но". Сработает ложно если перед "но" идет точка.
не надо заводить 7 однотипных переменных, надо использловать массив. также, не надо класть текст каждый раз в новую переменную с бессмысленными именами - это тольок запутывает - лучше использовать ту же самую.
> http://ideone.com/ap17y2 поиск "неумышленных" опечаток
> ([а-яё]+)?
Какой смысл ставить плюс, а за ним вопрос? Это то же самое что зведочка. Более того, твое выражение срабатывает не на слова со смешанными буквами, а тупо на все латинские буквы: http://ideone.com/umnWWy
Надо искать именно слова с буквами из 2 алфавитов.
В общем, надо тебе получше изучить регулярки - пока ты их не очень понимаешь.
> Вот только в бд почему-то не сохраняет, а только переадресовывает. Почему так? Никаких ошибок не выдает, ничего не пишет, почему, понять не могу.
Поставь там echo и die(); и смотри какие команды выполняются и чему равны переменные. Также, найди лог ошибок Апача (в папке апача logs) и посмотри там. При переадресации браузер не отображает остальную страницу потому ты и не видишь возожных ошибок.
> 2. Когда использоваться include, а когда include_once, как работает я знаю, но не могу понять в каких ситуациях первая функция может вызвать проблемы? То же самое и c require и require_once. Да и зачем вообще нужна require, если везде можно юзать инклюд
Открой мануал по этим 4 функциям и составь список отличий. Сразу скажу что include вообще не нужен.
> 3. Можно ли в свойствах класс модели создать переменную дб и уже юзать ее в функциях и не писать в каждой функции одну и ту же строчку кода?
Принято передавать зависимости класса через конструктор, это называется dependency injection: https://gist.github.com/codedokode/e1d31a31b37d5f635057
То что у тебя - это вообще не ООП а его имитация - кругом статические методы и массивы - надо переделывать. Статические методы спутывают код в одну кучу вместо разделения его на независимые слабо связанные классы.
> 4. Я немного не понимаю суть ООП в плане, почему не сделать все функции статическими и выполнять их без создания обьекта
Это будет не ООП, а обычная процедурщина (то есть просто набор функций без объектов). но ты задал хороший вопрос.
При использовании DI мы не прописываем в классе получение зависимостей, а передаем их снаружи.
- код упрощается: классу теперь не надо самому создавать нужные ему объекты, а это становится задачей того кто его вызывает. Вообще, у каждого класса есть своя определенная задача (например сохранять студентов в базу), а искать другие объекты - это не его задача, а того кто хочет использовать объект этого класса.
- мы сразу видим какие зависимости есть у класса по его конструктору. В твоем случае для этого надо изучить весь код класса
- мы можем передавать разные объекты с разными настройками. Ну например вместо обычного объекта PDO мы можем передать объект, который выводит на экран все выполняемые запросы. Или мы можем одному классу дать один объект PDO, а другому - другой. В твоем случае все прописано намертво и поменять ничего нельзя.
- классы перестают быть спутанными друг с другом намертво
Чем плохи статические методы? Ну например тем что нельзя создать 2 объекта с разными настройками. И что нельзя реализовать DI.
И кстати, а ты делал наши задачи Вектор и Кошки-мышки на ООП? Если нет, надо бы сделать - как раз в ходе решения этих задач ты и узнаешь лучше на практике как писать ООП код. И почему статические методы не работают.
> Можешь привести примеры где нужно будет обязательно создавать обьект
Ну например модель студента - класс который хранит информацию об одном студенте. Если тебе нужно хранить информацию о 2 разных студентах, тебе очевидно надо 2 таких объекта. Или кошки-мышки - каждое животное имеет свои свойства и представлено своим объектом.
Ну и в твоем случае у тебя все жестко связано. Вот я допустим хочу получить объект с заданными мной настройками базы данных (user=ivan, passowrd = 1234). А как я это сделаю если у тебя в коде намертво вписано что они читаются из файла?
Ты фактически усложняешь код. Вместо того чтобы сделать класс который соединяется с БД с использованием переданного снаружи объекта, ты зачем-то в этот же класс жестко вписываешь что настройки читаются из такого-то файла. А зачем? задача класса работы с БД - сохранять и загружать студентов, а не определять где найти настройки базы данных. Ты заставил класс заниматься не своим делом и заодно сделал код менее универсальным.
Также, если ты не читал, перечитай замечания к задаче про студентов - там очень много полезной информации.
Также прочитай про паттерны работы с базой данных: https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md
> 5. Зачем нужно постоянно импортировать бд или создавать вручную если хочешь потестить чей-то сайт? Почему бы не написать просто код который проверяет наличие бд и таблиц и если они отсутствуют, то просто создает их.
Бессмысленное усложнение кода - базу надо создать один раз, и значит этот функционал незачем вставлять в функцию вывода студентов на экран. Да и при установке все равно надо что-то сделать руками - создать пользователя в БД, создать пустую базу итд.
Если ты хочешь автоматизировать задачу - попробуй напиши отдельный скрипт установки, запускаемый из командной строки.
> 6. Также почему когда люди выкладывают свой сайт на тест, то выкладывают его без фреймворка и его тоже нужно устанавливать руками?
руками обычно не устанавливают. Ты описываешь нужные тебе библиотеки в composer.json, а пользователь скачивает проект и устанавливает все зависимости одной командой composer install.
Ну и в репозитории должен быть твой код. Какой смысл в том что тысяча человек скачают и положат в свой репозиторий одну и ту же библиотеку? Не проще ли вписать строчку в composer.json? Плюс, когда ты захочешь перейти на новую версию библиотеки тебе надо будет лишь поменять одну цифру в конфиге. А ты предлагаешь лезть куда-то на сайт, искать там нужную версию, скачивать, распаковывать - быссмысленная ручная работа.
Плюс композер умеет устанавливать еще и зависимости библиотеки, и настраивать автозагрузку для нее. убирается куча рутинных действий.
По твоему коду:
.....
> Вот только в бд почему-то не сохраняет, а только переадресовывает. Почему так? Никаких ошибок не выдает, ничего не пишет, почему, понять не могу.
Поставь там echo и die(); и смотри какие команды выполняются и чему равны переменные. Также, найди лог ошибок Апача (в папке апача logs) и посмотри там. При переадресации браузер не отображает остальную страницу потому ты и не видишь возожных ошибок.
> 2. Когда использоваться include, а когда include_once, как работает я знаю, но не могу понять в каких ситуациях первая функция может вызвать проблемы? То же самое и c require и require_once. Да и зачем вообще нужна require, если везде можно юзать инклюд
Открой мануал по этим 4 функциям и составь список отличий. Сразу скажу что include вообще не нужен.
> 3. Можно ли в свойствах класс модели создать переменную дб и уже юзать ее в функциях и не писать в каждой функции одну и ту же строчку кода?
Принято передавать зависимости класса через конструктор, это называется dependency injection: https://gist.github.com/codedokode/e1d31a31b37d5f635057
То что у тебя - это вообще не ООП а его имитация - кругом статические методы и массивы - надо переделывать. Статические методы спутывают код в одну кучу вместо разделения его на независимые слабо связанные классы.
> 4. Я немного не понимаю суть ООП в плане, почему не сделать все функции статическими и выполнять их без создания обьекта
Это будет не ООП, а обычная процедурщина (то есть просто набор функций без объектов). но ты задал хороший вопрос.
При использовании DI мы не прописываем в классе получение зависимостей, а передаем их снаружи.
- код упрощается: классу теперь не надо самому создавать нужные ему объекты, а это становится задачей того кто его вызывает. Вообще, у каждого класса есть своя определенная задача (например сохранять студентов в базу), а искать другие объекты - это не его задача, а того кто хочет использовать объект этого класса.
- мы сразу видим какие зависимости есть у класса по его конструктору. В твоем случае для этого надо изучить весь код класса
- мы можем передавать разные объекты с разными настройками. Ну например вместо обычного объекта PDO мы можем передать объект, который выводит на экран все выполняемые запросы. Или мы можем одному классу дать один объект PDO, а другому - другой. В твоем случае все прописано намертво и поменять ничего нельзя.
- классы перестают быть спутанными друг с другом намертво
Чем плохи статические методы? Ну например тем что нельзя создать 2 объекта с разными настройками. И что нельзя реализовать DI.
И кстати, а ты делал наши задачи Вектор и Кошки-мышки на ООП? Если нет, надо бы сделать - как раз в ходе решения этих задач ты и узнаешь лучше на практике как писать ООП код. И почему статические методы не работают.
> Можешь привести примеры где нужно будет обязательно создавать обьект
Ну например модель студента - класс который хранит информацию об одном студенте. Если тебе нужно хранить информацию о 2 разных студентах, тебе очевидно надо 2 таких объекта. Или кошки-мышки - каждое животное имеет свои свойства и представлено своим объектом.
Ну и в твоем случае у тебя все жестко связано. Вот я допустим хочу получить объект с заданными мной настройками базы данных (user=ivan, passowrd = 1234). А как я это сделаю если у тебя в коде намертво вписано что они читаются из файла?
Ты фактически усложняешь код. Вместо того чтобы сделать класс который соединяется с БД с использованием переданного снаружи объекта, ты зачем-то в этот же класс жестко вписываешь что настройки читаются из такого-то файла. А зачем? задача класса работы с БД - сохранять и загружать студентов, а не определять где найти настройки базы данных. Ты заставил класс заниматься не своим делом и заодно сделал код менее универсальным.
Также, если ты не читал, перечитай замечания к задаче про студентов - там очень много полезной информации.
Также прочитай про паттерны работы с базой данных: https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md
> 5. Зачем нужно постоянно импортировать бд или создавать вручную если хочешь потестить чей-то сайт? Почему бы не написать просто код который проверяет наличие бд и таблиц и если они отсутствуют, то просто создает их.
Бессмысленное усложнение кода - базу надо создать один раз, и значит этот функционал незачем вставлять в функцию вывода студентов на экран. Да и при установке все равно надо что-то сделать руками - создать пользователя в БД, создать пустую базу итд.
Если ты хочешь автоматизировать задачу - попробуй напиши отдельный скрипт установки, запускаемый из командной строки.
> 6. Также почему когда люди выкладывают свой сайт на тест, то выкладывают его без фреймворка и его тоже нужно устанавливать руками?
руками обычно не устанавливают. Ты описываешь нужные тебе библиотеки в composer.json, а пользователь скачивает проект и устанавливает все зависимости одной командой composer install.
Ну и в репозитории должен быть твой код. Какой смысл в том что тысяча человек скачают и положат в свой репозиторий одну и ту же библиотеку? Не проще ли вписать строчку в composer.json? Плюс, когда ты захочешь перейти на новую версию библиотеки тебе надо будет лишь поменять одну цифру в конфиге. А ты предлагаешь лезть куда-то на сайт, искать там нужную версию, скачивать, распаковывать - быссмысленная ручная работа.
Плюс композер умеет устанавливать еще и зависимости библиотеки, и настраивать автозагрузку для нее. убирается куча рутинных действий.
По твоему коду:
.....
> https://github.com/luptidu/students.com/blob/master/models/Student.php
Из названия можно подумать что это модель студента, то есть класс хранящий имя, фамилию, и тд. Почему-то в твоем случае название класса не соответствет тому чем он является.
> static function createStudent($name, $surname, $class, $points) {
А когда у студента будет 10 свойств (а их там как раз около 10), ты 10 аргументов сделаешь? Как минимум ты забыл про год рождения, пол, место проживания.
> while($row = $result->fetch()){
> $studentList[$i]['name'] = $row['name'];
Изучи мануал по PDO - там есть метод fetchAll. Также не надо копипастить вот эти строки:
Также, для добавления в массив не нужна переменная $i считающая индексы - php умеет их считать сам.
> static function getStudentsList(){
Почему ты возвращаешь массив массивов, а не массив объектов? Какие преимущества у массива? Я например вижу такой недостаток что в случае с классом ты можешь посмореть какие у него есть свойства, можешь добавлять в него методы, а в случае с массивом неизвестно какие свойства, методы для работы с ним добавлять нельзя. Почему выбран массив для хранения информации о студентах?
> static function checkStudent($name, $surname){
> $studentList = Student::getStudentsList();
> foreach ($studentList as $student){
Неэффективно выбирать всех студентов в память, надо искать в самой базе данных.
https://github.com/luptidu/students.com/blob/master/components/Database.php
Зачем нужен этот класс? Какая от него польза? И почему ты каждый раз создаешь новое соединение, а не используешь существующее?
Также, объясни, какой из режимов обработки ошибок в PDO (PDO::ATTR_ERRMODE) ты используешь и почему? Мануал если что http://php.net/manual/ru/pdo.error-handling.php (я советую прочитать весь мануал по PDO/mysql на оф сайте от начала и до конца).
https://github.com/luptidu/students.com/blob/master/components/autoload.php
ты используешь много лет назад устаревший способ, вот открой например мануал: http://php.net/manual/ru/language.oop5.autoload.php
Надо использовать spl_autoload_register, вот мой урок https://github.com/codedokode/pasta/blob/master/php/autoload.md
https://github.com/luptidu/students.com/blob/master/config/routes.php#L11
> 'index.php' => 'main/index',
> '' => 'main/index'
Зачем путь с index.php если ты используешь настраиваемые URL?
https://github.com/luptidu/students.com/blob/master/components/Router.php
Плохо что жестко прописано имя конфиг-файла. Почему роутер должен заниматься загрузкой конфигов? Также, если твой роутер подключает и запускает контроллер то это не роутер, а Фронт Контроллер.
> foreach ($routes as $route => $needed) {
> if (Router::getUri() == $route) {
Для поиска в массиве по индексу не нужен цикл
> https://github.com/luptidu/students.com/blob/master/controllers/MainController.php#L4
> Description of MainController
Не стоит вставлять не несущие смысла комментарии.
https://github.com/luptidu/students.com/blob/master/controllers/MainController.php#L15
Эту функцию регистрации надло разбить на части, напимер вынести отдельно валидацию, отдельно работу с куками.
Ну и почему-то у тебя не вся информация, которая требуется, сохраняется.
Также, не вижу в проекте дампа с SQL кодом для создания нужных таблиц. И readme.md где написано как развернуть проект.
https://github.com/luptidu/students.com/blob/master/views/index.php
В шаблонах не используется echo и используются версии операторов иф с двоеточием. не надо писать HTML код в кавычках внутри echo так как это неудобно и читать и писать.
И если ты пропустил задачи на ООП - надо бы к ним вернуться и сделать. Многие важные вещи иначе не поймешь.
> https://github.com/luptidu/students.com/blob/master/views/registration.php
> if (isset($name))
как писать надежный код когда неизвестно даже существует такая переменная или нет?
Также не вижу у тебя экранирования выводимых в шаблоне данных, почитай про XSS https://github.com/codedokode/pasta/blob/master/security/xss.md
> https://github.com/luptidu/students.com/blob/master/models/Student.php
Из названия можно подумать что это модель студента, то есть класс хранящий имя, фамилию, и тд. Почему-то в твоем случае название класса не соответствет тому чем он является.
> static function createStudent($name, $surname, $class, $points) {
А когда у студента будет 10 свойств (а их там как раз около 10), ты 10 аргументов сделаешь? Как минимум ты забыл про год рождения, пол, место проживания.
> while($row = $result->fetch()){
> $studentList[$i]['name'] = $row['name'];
Изучи мануал по PDO - там есть метод fetchAll. Также не надо копипастить вот эти строки:
Также, для добавления в массив не нужна переменная $i считающая индексы - php умеет их считать сам.
> static function getStudentsList(){
Почему ты возвращаешь массив массивов, а не массив объектов? Какие преимущества у массива? Я например вижу такой недостаток что в случае с классом ты можешь посмореть какие у него есть свойства, можешь добавлять в него методы, а в случае с массивом неизвестно какие свойства, методы для работы с ним добавлять нельзя. Почему выбран массив для хранения информации о студентах?
> static function checkStudent($name, $surname){
> $studentList = Student::getStudentsList();
> foreach ($studentList as $student){
Неэффективно выбирать всех студентов в память, надо искать в самой базе данных.
https://github.com/luptidu/students.com/blob/master/components/Database.php
Зачем нужен этот класс? Какая от него польза? И почему ты каждый раз создаешь новое соединение, а не используешь существующее?
Также, объясни, какой из режимов обработки ошибок в PDO (PDO::ATTR_ERRMODE) ты используешь и почему? Мануал если что http://php.net/manual/ru/pdo.error-handling.php (я советую прочитать весь мануал по PDO/mysql на оф сайте от начала и до конца).
https://github.com/luptidu/students.com/blob/master/components/autoload.php
ты используешь много лет назад устаревший способ, вот открой например мануал: http://php.net/manual/ru/language.oop5.autoload.php
Надо использовать spl_autoload_register, вот мой урок https://github.com/codedokode/pasta/blob/master/php/autoload.md
https://github.com/luptidu/students.com/blob/master/config/routes.php#L11
> 'index.php' => 'main/index',
> '' => 'main/index'
Зачем путь с index.php если ты используешь настраиваемые URL?
https://github.com/luptidu/students.com/blob/master/components/Router.php
Плохо что жестко прописано имя конфиг-файла. Почему роутер должен заниматься загрузкой конфигов? Также, если твой роутер подключает и запускает контроллер то это не роутер, а Фронт Контроллер.
> foreach ($routes as $route => $needed) {
> if (Router::getUri() == $route) {
Для поиска в массиве по индексу не нужен цикл
> https://github.com/luptidu/students.com/blob/master/controllers/MainController.php#L4
> Description of MainController
Не стоит вставлять не несущие смысла комментарии.
https://github.com/luptidu/students.com/blob/master/controllers/MainController.php#L15
Эту функцию регистрации надло разбить на части, напимер вынести отдельно валидацию, отдельно работу с куками.
Ну и почему-то у тебя не вся информация, которая требуется, сохраняется.
Также, не вижу в проекте дампа с SQL кодом для создания нужных таблиц. И readme.md где написано как развернуть проект.
https://github.com/luptidu/students.com/blob/master/views/index.php
В шаблонах не используется echo и используются версии операторов иф с двоеточием. не надо писать HTML код в кавычках внутри echo так как это неудобно и читать и писать.
И если ты пропустил задачи на ООП - надо бы к ним вернуться и сделать. Многие важные вещи иначе не поймешь.
> https://github.com/luptidu/students.com/blob/master/views/registration.php
> if (isset($name))
как писать надежный код когда неизвестно даже существует такая переменная или нет?
Также не вижу у тебя экранирования выводимых в шаблоне данных, почитай про XSS https://github.com/codedokode/pasta/blob/master/security/xss.md
>>Тайп хинт бы сюда.
> Какой тайпхинт? В эту функцию я передаю несколько контроллеров, чтобы удобнее было ловить исключение. Я могу конечно сделать для этих контроллеров интерфейс,
Ну так и сделай. Чтобы показать что именно можно передавать в эту функцию, а что нет. И чтобы объединить классы контроллеров.
> Чтобы не копипастить catch блоки с одинаковым содержимым я сделал для двух исключений один интерфейс FatalException и ловлю его. Других исключений, кроме PDOException там быть не может, но если вдруг они будут, можно будет добавить еще один блок catch. Если можно это как-нибудь по другому сделать, подскажи пожалуйста
Ну сам посмотри: при появлении в коде нового исключеняи ты хочешь добавлять блок catch. А если ты подключишь стороннюю библиотеку которая содержит 20 разных исключений, ты еще 20 блоков добавишь? В глобальном обработчике ошибок очевидно надо ловить любые исключения.
>>По идее ссылки надо экранировать через htmlspecialchars, в частности символ & в них
> Вот это тоже не совсем понял, но все равно сделал. Это из-за того что символ & может сломать разметку?
По правилам HTML & это спецсимвол и его надо записывать особым образом. перечитай например: https://ru.wikipedia.org/wiki/Мнемоники_в_HTML
Если у тебя в ссылке встретистя например < то оно будет интепретировано как знак < и ссылка исказится. Плохо что ты не знаешь правила HTML.
Плюс что если в дальнейшем в ссылке будут параметры приходящие от пользователя? Он сможет реализовать XSS на твоем сайте, вставляя проивзольные данные на страницу. Уязвимость XSS вознимает именно из-за того что люди не знают или забывают правила кодирования символов в HTML.
По коду:
- надо добавить и настроить gitignore, напрмер для папки vendor
Поиск по студентам работает с учетом регистра, а надо без.
Стрелку вверх можно было нарисовать и проще - на будущее - & uarr ; без пробелов.
После редактирования/добавления наверно логично редиректить на таблицу, а не назад на форму. Можно при добавлении еще подсвечивать цветом добавленную запись, если хочешь.
Надпись "показать все записи" свалилась на таблицу.
https://github.com/foobar1643/student-list/blob/master/app/Controller/ControllerForm.php#L23
> $regHelper = new RegistrationHelper($dataGateway);
Хелперы надо бы засунуть в контейнер, зачем копипастить код их создания?
> if($_SERVER['REQUEST_METHOD'] == "POST" && $tokenHelper->checkCsrfToken($_POST['csrf_field'])) {
Я думаю при несвпадении токена (например долго не отправляли форму) надо выводить ее и предлагать отправить ее еще раз. У тебя же данные теряются. Ну либо надо выдавать токены надолго, что куки точно не умрут. Впрочем, у тебя вроде так и есть.
> checkCsrfToken($_POST['csrf_field'])
Нет гарантий что в массиве ПОСТ будет это поле.
> $student->token = $tokenHelper->setAuthToken();
При обновлении студента наверно новый токен генерировать не надо?
Вообще, функция run слишком большая. Вынеси часть кода хотя бы в приватные методы в контролере.
> $oldStudent = $dataGateway->selectStudent($tokenHelper->getAuthToken());
> foreach($regHelper->getAllowedFields() as $key) {
ты по моему выше в коде уже выбирал студента из БД, а это второй раз будет.
https://github.com/foobar1643/student-list/blob/master/app/Helper/TokenHelper.php#L18
Нет гарантий что кука сущестсвует, значит будет ошибка доступа к полям массива. У тебя вообще включен вывод ошибок? Ты их видишь?
Сделай-ка превращение всех ошибок в исключения как описано тут http://php.net/manual/ru/class.errorexception.php
Насчет авторизации. Я думаю, можно пойти дальше, спрятать логику авторизации внутри класса и сделать такие методы:
- получить студента если он залогинен
- залогиниться под именем студента
- разлогиниться
Ты же выставляешь наружу лишь методы работы с куками, таким образом логика авторизации не спрятана в одном классе, а размазана.
Также, не думаю что стоит CSRF и автоизацию класть в один класс - явно просится разделение на 2 класса.
Насчет FatalException - странный интерфейс, в общем-то все непойманные исключения завершают скрипт.
https://github.com/foobar1643/student-list/blob/master/app/init.php#L17
Кодировку соединения указывать не надо?
https://github.com/foobar1643/student-list/blob/fc341127e66968f3b1a099d0ac846bfe1101a11e/app/Database/StudentDataGateway.php#L73
Подзапросы тут не требуются. А если бы требовались - подошел бы обычный джойн, но тут и он не нужен.
Кстати проверка email тоже должен быть регистронезависимой.
> catch(FileOperationException $e) {
> die($e->__toString());
Вообще в CLI режиме исключения по умолчанию выводятся в консоль, так что это не нужно.
> по запросу & laquo
точка с запятой пропущена
> <?php if($linkBuilder->sortKey == 'sgroup' && $linkBuilder->sortType == 'asc'): ?>
> <span class="glyphicon glyphicon-arrow-up" aria-hidden="true"></span>
Эту штуку наверно в функцию стоило вынести, в тот же Table Helper, нехоршо конечно HTML функцией генерировать, но копипаста еще хуже, а макросов в phtml нету.
>>Тайп хинт бы сюда.
> Какой тайпхинт? В эту функцию я передаю несколько контроллеров, чтобы удобнее было ловить исключение. Я могу конечно сделать для этих контроллеров интерфейс,
Ну так и сделай. Чтобы показать что именно можно передавать в эту функцию, а что нет. И чтобы объединить классы контроллеров.
> Чтобы не копипастить catch блоки с одинаковым содержимым я сделал для двух исключений один интерфейс FatalException и ловлю его. Других исключений, кроме PDOException там быть не может, но если вдруг они будут, можно будет добавить еще один блок catch. Если можно это как-нибудь по другому сделать, подскажи пожалуйста
Ну сам посмотри: при появлении в коде нового исключеняи ты хочешь добавлять блок catch. А если ты подключишь стороннюю библиотеку которая содержит 20 разных исключений, ты еще 20 блоков добавишь? В глобальном обработчике ошибок очевидно надо ловить любые исключения.
>>По идее ссылки надо экранировать через htmlspecialchars, в частности символ & в них
> Вот это тоже не совсем понял, но все равно сделал. Это из-за того что символ & может сломать разметку?
По правилам HTML & это спецсимвол и его надо записывать особым образом. перечитай например: https://ru.wikipedia.org/wiki/Мнемоники_в_HTML
Если у тебя в ссылке встретистя например < то оно будет интепретировано как знак < и ссылка исказится. Плохо что ты не знаешь правила HTML.
Плюс что если в дальнейшем в ссылке будут параметры приходящие от пользователя? Он сможет реализовать XSS на твоем сайте, вставляя проивзольные данные на страницу. Уязвимость XSS вознимает именно из-за того что люди не знают или забывают правила кодирования символов в HTML.
По коду:
- надо добавить и настроить gitignore, напрмер для папки vendor
Поиск по студентам работает с учетом регистра, а надо без.
Стрелку вверх можно было нарисовать и проще - на будущее - & uarr ; без пробелов.
После редактирования/добавления наверно логично редиректить на таблицу, а не назад на форму. Можно при добавлении еще подсвечивать цветом добавленную запись, если хочешь.
Надпись "показать все записи" свалилась на таблицу.
https://github.com/foobar1643/student-list/blob/master/app/Controller/ControllerForm.php#L23
> $regHelper = new RegistrationHelper($dataGateway);
Хелперы надо бы засунуть в контейнер, зачем копипастить код их создания?
> if($_SERVER['REQUEST_METHOD'] == "POST" && $tokenHelper->checkCsrfToken($_POST['csrf_field'])) {
Я думаю при несвпадении токена (например долго не отправляли форму) надо выводить ее и предлагать отправить ее еще раз. У тебя же данные теряются. Ну либо надо выдавать токены надолго, что куки точно не умрут. Впрочем, у тебя вроде так и есть.
> checkCsrfToken($_POST['csrf_field'])
Нет гарантий что в массиве ПОСТ будет это поле.
> $student->token = $tokenHelper->setAuthToken();
При обновлении студента наверно новый токен генерировать не надо?
Вообще, функция run слишком большая. Вынеси часть кода хотя бы в приватные методы в контролере.
> $oldStudent = $dataGateway->selectStudent($tokenHelper->getAuthToken());
> foreach($regHelper->getAllowedFields() as $key) {
ты по моему выше в коде уже выбирал студента из БД, а это второй раз будет.
https://github.com/foobar1643/student-list/blob/master/app/Helper/TokenHelper.php#L18
Нет гарантий что кука сущестсвует, значит будет ошибка доступа к полям массива. У тебя вообще включен вывод ошибок? Ты их видишь?
Сделай-ка превращение всех ошибок в исключения как описано тут http://php.net/manual/ru/class.errorexception.php
Насчет авторизации. Я думаю, можно пойти дальше, спрятать логику авторизации внутри класса и сделать такие методы:
- получить студента если он залогинен
- залогиниться под именем студента
- разлогиниться
Ты же выставляешь наружу лишь методы работы с куками, таким образом логика авторизации не спрятана в одном классе, а размазана.
Также, не думаю что стоит CSRF и автоизацию класть в один класс - явно просится разделение на 2 класса.
Насчет FatalException - странный интерфейс, в общем-то все непойманные исключения завершают скрипт.
https://github.com/foobar1643/student-list/blob/master/app/init.php#L17
Кодировку соединения указывать не надо?
https://github.com/foobar1643/student-list/blob/fc341127e66968f3b1a099d0ac846bfe1101a11e/app/Database/StudentDataGateway.php#L73
Подзапросы тут не требуются. А если бы требовались - подошел бы обычный джойн, но тут и он не нужен.
Кстати проверка email тоже должен быть регистронезависимой.
> catch(FileOperationException $e) {
> die($e->__toString());
Вообще в CLI режиме исключения по умолчанию выводятся в консоль, так что это не нужно.
> по запросу & laquo
точка с запятой пропущена
> <?php if($linkBuilder->sortKey == 'sgroup' && $linkBuilder->sortType == 'asc'): ?>
> <span class="glyphicon glyphicon-arrow-up" aria-hidden="true"></span>
Эту штуку наверно в функцию стоило вынести, в тот же Table Helper, нехоршо конечно HTML функцией генерировать, но копипаста еще хуже, а макросов в phtml нету.
https://ru.wordpress.org/plugins/woocommerce/faq/
http://support.woothemes.com/hc/en-us - тут нету? Алсо странно делать магазин на вордпрессе.
https://github.com/MindiMakridi/filehosting/blob/master/files.sql#L35
> ENGINE=MyISAM
Нагугли отличия myisam от иннодб и напиши несколько самых важных.
Почему в твоей базе нет внешних ключей? Почитай http://denis.in.ua/foreign-keys-in-mysql.htm
> `name` varchar(50) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'Аноним',
Лучше хранить NULL а анонима подставлять при выводе. А так, как отличить настоящего анонима от того кто вписал имя Аноним?
> `number` int(11) NOT NULL,
Что в этом поле? нужен комментарий. Также, возможно стоит parent_id хранить на всякий пожарный.
https://github.com/MindiMakridi/filehosting/blob/master/models/helpers/FilesHelper.php#L147
> validateFileUpload($filePostData, $maxSize)
Макс. размер неизменен и правильнее потому передавать его через конструктор.
> $file->setId($this->filesMapper->addFile($file));
Лучше наверно будет если addFile сам проставит id. Хотя можно и так оставить.
Далее, ты не учел то регистр имен файлов имеет значение. Вот что получается на линуксе при попытке запустить твой код:
> Fatal error: Class 'Filehosting\Helpers\FilesHelper' not found in /home/ubuntu/workspace/public/index.php on line 45
Под виндой надо сначала переименовать папку в другое имя, а потом назад в правильном регистре.
Если файлов нет, то хорошо бы выводить соотв. надпись вместо таблицы и предложить загрузить первый файл.
В репозиторий надо добавить пустую папку files и папку превьюшек - как это сделать: http://m05quit0.ru/dev/kak-dobavit-pustuyu-direktoriyu-v-git/ - также надо будет повозиться чтобы загружаемые файлы в ней игнорировались.
В комментариях теряются переводы строк.
При раскрытии формы ответа надо ставить курсор в поле ввода текста. Имя должно сохраняться даже между перезагрузками страницы.
Что насчет аякс-добавления и аякс-загрузки новых комментариев?
> $depth = preg_split("/\\./", $this->path);
Достаточно explode
> $depth = (count($depth)-1)*25;
Неправильно. Число 25 - это часть HTML шаблона и оно не должно прописываться в модели.
https://github.com/MindiMakridi/filehosting/blob/master/models/CommentsMapper.php#L40
> $sth->setFetchMode(\PDO::FETCH_CLASS, "Filehosting\Commentary");
Тут дата из БД не преобразуется в таймстамп
> SELECT MAX(number) FROM comments
Можно выбирать max(path)
Насчет формирования путей: не надо это раскидывать по коду. Лучше сделать 2 функции. можно даже статических, одна раскладывает путь на числа, другая собирает из чисел путь.
https://github.com/MindiMakridi/filehosting/blob/master/public/index.php#L109
Вот этой простыни в контроллере не должно быть - должна быть простая функция в маппере которая сама и пути все проставит и в базу сохранит все.
Также, хорошо бы для случаев когда нет Xsendfile сделать фоллбек на обычную отдачу через readfile например.
И для картинок тоже можно бы применить xsendfile когда он есть.
> $thumb = new Filehosting\Thumbnail
Его стоит тоже сделать синглтоном слима
И еще: что за бардак в папке models? почему модели, мапперы, исключения, хелперы, лежат вперемешку? Логичнее бы их по папкам разнести.
Для комментариев надо бы минимально оформление, например дату и имя сделать серым шрифтом поменьше, и оступов немного добавить.
> dropZone[0].ondragover
У тебя же джейквери, добавляй обработчик через него
> dropZone.text ="....";
> dropZone.addClass('error');
Это надо вынести в отдельную функцию
Также, в коде перетаскивания надо сделать функцию проверяющую поддерживает ли браузер все нужные вещи (например FormData с добавлением файла). Если нет - не активировать загрузку перетаскиванием.
Также, на случай перетаскивания нескольких файлов надо что-то делать. Хотя бы текст выводить.
далее, метод append позволяет указать оригинальное имя файла
https://developer.mozilla.org/ru/docs/Web/API/FormData/append
При ошибке загрузки из-за проблем связи или ответа не с кодом 200 надо давать возмодность повторить попытку.
Надо запрещать перетаскивание нового файла в процессе загрузки либо проверить что все ок при этом.
> xhr.upload.addEventListener('progress', uploadProgress, false);
Если есть браузеры где нет этого события, но есть загрузка файлов, тут вылетит исключение. надо проверить есть ли такие браузеры и если есть то подстраховаться.
В аякс-загрузке файла нет проверки ответа сервера. Что если сервер передал какое-то сообщение об ошибке?
https://github.com/MindiMakridi/filehosting/blob/master/templates/filePage.html.twig#L82
> function showForm(event){
Стена текста - разбей на читабельные функции.
Также, не надо создавать программно форму загрузки из узлов. Сделай шаблон и генерируй по шаблону как описано тут:
http://javascript.ru/unsorted/templating
https://learn.javascript.ru/templates
Шаблон должен быть в HTML коде, например в теге script с кастомным type. Я советую не делать полноценных шаблонов а просто HTML с вставками вроде [text]
Посмотри можно ли использовать это, что со старыми браузерами? https://learn.javascript.ru/template-tag
> token.setAttribute('value', '{{token|json_encode|raw}}');
все значения из PHP надо ставить в начале скрипта, а не в середине, так как твой скрипт не вынести во внешний файл будет.
Так вообще, у тебя неплохо получается.
https://github.com/MindiMakridi/filehosting/blob/master/files.sql#L35
> ENGINE=MyISAM
Нагугли отличия myisam от иннодб и напиши несколько самых важных.
Почему в твоей базе нет внешних ключей? Почитай http://denis.in.ua/foreign-keys-in-mysql.htm
> `name` varchar(50) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'Аноним',
Лучше хранить NULL а анонима подставлять при выводе. А так, как отличить настоящего анонима от того кто вписал имя Аноним?
> `number` int(11) NOT NULL,
Что в этом поле? нужен комментарий. Также, возможно стоит parent_id хранить на всякий пожарный.
https://github.com/MindiMakridi/filehosting/blob/master/models/helpers/FilesHelper.php#L147
> validateFileUpload($filePostData, $maxSize)
Макс. размер неизменен и правильнее потому передавать его через конструктор.
> $file->setId($this->filesMapper->addFile($file));
Лучше наверно будет если addFile сам проставит id. Хотя можно и так оставить.
Далее, ты не учел то регистр имен файлов имеет значение. Вот что получается на линуксе при попытке запустить твой код:
> Fatal error: Class 'Filehosting\Helpers\FilesHelper' not found in /home/ubuntu/workspace/public/index.php on line 45
Под виндой надо сначала переименовать папку в другое имя, а потом назад в правильном регистре.
Если файлов нет, то хорошо бы выводить соотв. надпись вместо таблицы и предложить загрузить первый файл.
В репозиторий надо добавить пустую папку files и папку превьюшек - как это сделать: http://m05quit0.ru/dev/kak-dobavit-pustuyu-direktoriyu-v-git/ - также надо будет повозиться чтобы загружаемые файлы в ней игнорировались.
В комментариях теряются переводы строк.
При раскрытии формы ответа надо ставить курсор в поле ввода текста. Имя должно сохраняться даже между перезагрузками страницы.
Что насчет аякс-добавления и аякс-загрузки новых комментариев?
> $depth = preg_split("/\\./", $this->path);
Достаточно explode
> $depth = (count($depth)-1)*25;
Неправильно. Число 25 - это часть HTML шаблона и оно не должно прописываться в модели.
https://github.com/MindiMakridi/filehosting/blob/master/models/CommentsMapper.php#L40
> $sth->setFetchMode(\PDO::FETCH_CLASS, "Filehosting\Commentary");
Тут дата из БД не преобразуется в таймстамп
> SELECT MAX(number) FROM comments
Можно выбирать max(path)
Насчет формирования путей: не надо это раскидывать по коду. Лучше сделать 2 функции. можно даже статических, одна раскладывает путь на числа, другая собирает из чисел путь.
https://github.com/MindiMakridi/filehosting/blob/master/public/index.php#L109
Вот этой простыни в контроллере не должно быть - должна быть простая функция в маппере которая сама и пути все проставит и в базу сохранит все.
Также, хорошо бы для случаев когда нет Xsendfile сделать фоллбек на обычную отдачу через readfile например.
И для картинок тоже можно бы применить xsendfile когда он есть.
> $thumb = new Filehosting\Thumbnail
Его стоит тоже сделать синглтоном слима
И еще: что за бардак в папке models? почему модели, мапперы, исключения, хелперы, лежат вперемешку? Логичнее бы их по папкам разнести.
Для комментариев надо бы минимально оформление, например дату и имя сделать серым шрифтом поменьше, и оступов немного добавить.
> dropZone[0].ondragover
У тебя же джейквери, добавляй обработчик через него
> dropZone.text ="....";
> dropZone.addClass('error');
Это надо вынести в отдельную функцию
Также, в коде перетаскивания надо сделать функцию проверяющую поддерживает ли браузер все нужные вещи (например FormData с добавлением файла). Если нет - не активировать загрузку перетаскиванием.
Также, на случай перетаскивания нескольких файлов надо что-то делать. Хотя бы текст выводить.
далее, метод append позволяет указать оригинальное имя файла
https://developer.mozilla.org/ru/docs/Web/API/FormData/append
При ошибке загрузки из-за проблем связи или ответа не с кодом 200 надо давать возмодность повторить попытку.
Надо запрещать перетаскивание нового файла в процессе загрузки либо проверить что все ок при этом.
> xhr.upload.addEventListener('progress', uploadProgress, false);
Если есть браузеры где нет этого события, но есть загрузка файлов, тут вылетит исключение. надо проверить есть ли такие браузеры и если есть то подстраховаться.
В аякс-загрузке файла нет проверки ответа сервера. Что если сервер передал какое-то сообщение об ошибке?
https://github.com/MindiMakridi/filehosting/blob/master/templates/filePage.html.twig#L82
> function showForm(event){
Стена текста - разбей на читабельные функции.
Также, не надо создавать программно форму загрузки из узлов. Сделай шаблон и генерируй по шаблону как описано тут:
http://javascript.ru/unsorted/templating
https://learn.javascript.ru/templates
Шаблон должен быть в HTML коде, например в теге script с кастомным type. Я советую не делать полноценных шаблонов а просто HTML с вставками вроде [text]
Посмотри можно ли использовать это, что со старыми браузерами? https://learn.javascript.ru/template-tag
> token.setAttribute('value', '{{token|json_encode|raw}}');
все значения из PHP надо ставить в начале скрипта, а не в середине, так как твой скрипт не вынести во внешний файл будет.
Так вообще, у тебя неплохо получается.
>А так, как отличить настоящего анонима от того кто вписал имя Аноним?
А так, как отличить настоящего NULL, от того, кто вписал имя NULL?
php > var_dump(gettype(NULL));
string(4) "NULL"
php > var_dump(gettype("NULL"));
string(6) "string"
>Поиск по студентам работает с учетом регистра, а надо без.
Нет. Ты мне это в прошлый раз писал, и я исправил.
https://github.com/foobar1643/student-list/blob/master/app/Database/StudentDataGateway.php#L56
Вот тут вместо LIKE теперь используется ILIKE.
Согласно мануалу постгреса http://www.postgresql.org/docs/current/static/functions-matching.html
>The key word ILIKE can be used instead of LIKE to make the match case-insensitive according to the active locale. This is not in the SQL standard but is a PostgreSQL extension.
Плюс прикреплю пару картинок где у меня этот поиск работает.
>Кодировку соединения указывать не надо?
Вроде бы она по дефолту UTF-8 у сервера и клиента в постгресе. Я еще проверю конечно.
>Эту штуку наверно в функцию стоило вынести, в тот же Table Helper, нехоршо конечно HTML функцией генерировать, но копипаста еще хуже, а макросов в phtml нету.
А если сделать массив, элементы которого будут соответствовать заголовкам колонок в таблице? Таким образом можно будет весь заголовок вывести одним циклом, не копипастить ifы и не делать функцию которая генерирует HTML. Конечно, редактировать такую вещь будет не очень удобно, но мне кажется что это лучше чем переносить куски шаблона в класс.
Получилось как-то так: http://pastebin.com/b91Ke0w5
Еще подумаю как убрать копипасту в ifах, там меняется только слово.
$sth->execute() и ничего не возвращал
А его успешное выполнение проверялось примерно так:
if(метод()),
теперь же я вынужден писать в методе return $sth->execute() чтобы такая проверка работала.
Зачем ты велосипеды с ifами строишь? Можно сказать PDO чтобы он выбрасывал исключения при любых ошибках вот так
>$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
Тогда если в запросе будет какая-то ошибка, твое приложение на этом моменте завершится, и ты сможешь обработать исключение, вывести ошибку в логи, на экран и т.д.
При завершении скрипта соединение с БД закрывается. Незакомиченная транзкация отменится.
даже если бы это было не так, ты бы мог откатить транзакцию поймав исключение.
В общем, изучи теорию, например мой урок по исключениям ( https://gist.github.com/codedokode/65d43ca5ac95c762bc1a ) или любой другой.
>>686070
На задаче с афйоном спотыкаются все без исключения. Ты решение покажи - может окажется что там еще и переделывать надо.
И всё-таки интересно, чем объясняется странное поведение скрипта, который внезапно перестал возвращать true/false?
Нормуль?
Интересно, что у тебя
>$time = $age - 16;
Ты мог бы сделать проще и понятнее, а именно - считать тайм отдельно:
>$time ++
Ответ получается 49 лет (у тебя 48). Это связано с тем, что в первый год выплат анону 16 лет. В случае, если прописывать
>$time = $age - 16;
, то первый год выплат (первое действие цикла) будет равняться нулю. Если же записывать $time++ , то первый год выплат будет равен единице (0 + 1).
>$age < 100
Не совсем подходящий ориентир: а вдруг сумма нужная не наберётся до того момента, когда Анону исполнится сто лет? Здесь (и чаще всего) лучше в условие ставить итог, который нам нужен для завершения, то достижение, ради которого всё затевалось. А у нас это миллион рублей.
>$time = $age - 16;
А в первый год будет ноль пройденных лет, получается? Там должно быть 49 лет, если я не ошибаюсь.
А так вроде всё нормально.
Решения лучше не ищи, а задавай вопросы в треде.
> У мемкеша есть текстовый протокол, по которому клиент соединяется с сервером и посылает команды. Ты бы мог реализовать свой сервер который поддерживает эти команды.
Да, я прочитал про текстовый протокол. Все равно что-то не понял, как я реализую свой сервер. Скорее всего я бы давно бы уже сделал, если бы ты мне написал более подробно, что да как.
>>685837
>У тебя вообще включен вывод ошибок? Ты их видишь?
Как оказалось у меня все это время в php.ini были отключены E_NOTICE, из-за этого я их не видел. Уже не помню почему я его так настроил, но настраивал я его месяцев 6 - 7 назад, с тех пор не трогал. Сейчас вот с включенными E_NOTICE протестировал все приложение, вроде бы нормально работает.
Ну и это
>Эту штуку наверно в функцию стоило вынести, в тот же Table Helper, нехоршо конечно HTML функцией генерировать, но копипаста еще хуже, а макросов в phtml нету.
Сделал по другому, как я писал тут >>685904
>>686152
Спасибо за разъяснения, а то я как раз не понимал, почему 48 получается вместо 49. Про тайм++ и не подумал, хотя это даже очевиднее.
Да, и тут вот какая хуйня. Я когда решал эту задачу, писал
>$time = $time ++
Так не работает. Надо просто указать $time ++ без всяких равно. Подумал, вдруг тебе тоже пригодится.
Поправил
http://ideone.com/BAiU1S // Yoda Speak
http://ideone.com/zfi18q // Клавиша shift
http://ideone.com/5PkSz6 // Опечаточники
http://ideone.com/iRS6qF // «Grammar Nazi»
http://ideone.com/T7xLpR // Автозамена
http://ideone.com/tytESG // Номера телефонов
http://ideone.com/Dpy8f8 // Ipad в кредит
>Ipad в кредит
>Не выплачиваемый
ШТО
Ты про Айфон задачу делал? Там столько же должно получиться, там те же значения, это контрольный банк для проверки решения.
Остальные цифры тоже не верны в этой задаче.
>Автозамена
Достаточно флаг i поставить, чтобы избежать дублирования букв в верхнем и нижнем регистрах.
>«Grammar Nazi»
Что, простите? Ничего не понятно, что на выходе. Ты можешь сделать так, чтобы выводился кусок текст, а напротив него описание ошибки? Это было в условии задачи.
В клавише и Йоде не определены переменные внутри функции, а так вроде всё в порядке.
>>Ты про Айфон задачу делал?
http://ideone.com/T5xtpt
>>там те же значения
В айпаде ежемесячную выплату поставил 2100, т.к. обнаружил, что если ежемесячная выплата меньше определенной минимальной суммы, то цикл продолжается вечно, т.к. долг только растет.
Поэтому добавил условие прерывания, специально для такого случая.
Ты не правильно учишь их, нужно им угрожать в стиле: ТЕБЯ МАККОНЕЛЛ ПОКАРАЕТ ЗА ТАКИЕ ПЕРЕМЕННЫЕ, и все сразу будут писать правильно.
Если свободный, то почему бы и нет?
>В айпаде ежемесячную выплату поставил 2100, т.к. обнаружил, что если ежемесячная выплата меньше определенной минимальной суммы, то цикл продолжается вечно, т.к. долг только растет.
Лолшто? Всё неверно, всё надо переделывать.
И 567 тысяч за Айпад в твоей задаче - это нечто, конечно.
Неверно решена задача про Айпад, а про Айфон вроде бы всё в порядке. Только условие, когда баланс меньше нуля, не должно сработать, банк же не может быть должен чего-то анону.
сделал вывод ошибок в «Grammar Nazi»
http://ideone.com/452fru
>>В клавише и Йоде не определены переменные внутри функции
Можно ли использовать такую конструкцию для проверки переменной?
if (!$text) {
если переменная $text еще не определена, то присваиваем ей значение слово1
} else {
если в $text уже есть что-то, то сначала добавляем пробел, а затем прибавляем слово2
}
Функция isset для проверки существования переменной.
Иначе будет ошибка уровня notice.
Но лучше переделать алгоритм так, чтобы не было сомнительных кусков кода типа "тут переменная может быть, а может не быть".
Это неправильно. В крайнем случае можно инициализировать переменную, присвоив ей null.
Надо бы ещё захватить текста с обеих сторон от ошибки - иначе непонятно, где эта ошибка в тексте. И напротив ошибки надо бы вывести её описание.
Для этого массив должен быть двумерным: array('регулярка с ошибкой' => 'описание ошибки'). А потом раскладываешь его через foreach.
HomoCredit: 56423.563121625 руб.
SoftBankCredit: 61268.718210807 руб.
StrawberryBankCredit: 53559.8738592 руб.
Так правильно? http://ideone.com/lxEu1d
>>И 567 тысяч за Айпад в твоей задаче - это нечто, конечно.
Хм. Если каждый месяц выплачивать по 2100, под 4%+500 комиссии, при сумме кредита 39999, то срок погашения кредита 22 года и 6 месяцев.
Да, теперь всё хорошо.
>срок погашения кредита 22 года и 6 месяцев.
Представляю, каким раритетом будет Айпад после выплаты.
- открываешь слушающий сокет
- принимаешь соединение
- читаешь команду до конца
- парсишь текст команды
- исполняешь
- посылаешь ответ
- закрываешь соединение
- переходишь к п2
Напиши с каким шагом сложности. В общем демон работает по такому принципу, что принимает соединения и выполняет поступабщие запросы. Там есть варианты, если ты читал урок про архитектуру серверов, то бывают сервера обрабатывающие один запрос за раз, бывают асинхронные, которые как бы имитируют обработку в несколько потоков. Тебе подойдет самый простой однопоточный вариант.
В плане кода желательно все это разбить на части:
- модуль протокола, парсящий поступающие команды и кодирующий ответы на них в соотв. с протоколом мемкеша
- модуль хранилища, хранящий данные и выполняющий дествия над ними
Сами команды может быть можно описать классами в рамках ООП.
Это конечно можно реализовать и вообще без ООП, но хорошо бы заодно попрактиковаься в умении разбивать задачи на подзадачи, и делать ООП дизайн.
Уточни, что именно тут не понятно?
Это кастомный атрибут. Ты можешь добавлять в разметку свои dataатрибуты, ну например:
<button data-confirm="Вы уверены что хотите удалить эту запись?">Удалить</button>
Здесь мы добавили свой атрибут к кнопке и может быть мы напишем скрипт который будет при нажатии кнопки читать этот атрибут и выводить диалог подтверждения.
Или:
<div class="hotel" data-stars="3">Гостиница N</div>
Здесь мы добавили в разметку информацию о числе звезд у гостиницы, которую может быть потом как-то используем (например будем выводить звездочки при наведении мыши или как-то еще).
Гугли data-атрибуты.
>>686078
Скорее всего ты поменял что-то в коде и не помнишь. Поведение скрипта не должно меняться из-за xdebug.
>>685904
Идея с циклом вполне годная.
>>686221
Да, в конфиге меняется
Это кастомный атрибут. Ты можешь добавлять в разметку свои dataатрибуты, ну например:
<button data-confirm="Вы уверены что хотите удалить эту запись?">Удалить</button>
Здесь мы добавили свой атрибут к кнопке и может быть мы напишем скрипт который будет при нажатии кнопки читать этот атрибут и выводить диалог подтверждения.
Или:
<div class="hotel" data-stars="3">Гостиница N</div>
Здесь мы добавили в разметку информацию о числе звезд у гостиницы, которую может быть потом как-то используем (например будем выводить звездочки при наведении мыши или как-то еще).
Гугли data-атрибуты.
>>686078
Скорее всего ты поменял что-то в коде и не помнишь. Поведение скрипта не должно меняться из-за xdebug.
>>685904
Идея с циклом вполне годная.
>>686221
Да, в конфиге меняется
Ссылочка кому интересно:
https://www.youtube.com/watch?v=yCALyQRN3hw
Алсо не могу не позлорадствовать, что в напряженной ситуации все таки гугловская нейросеть сделала бессмысленный ход. Вообще, нейросети переоценены по моему, люди приписывают им магические свойства и чуть ли не способность думать или анализировать. Нет, они это не могут.
Хотя я верю что IT имеет решающую роль в дальнейшем развитии, и везде будут роботы, но как-то нехорошо будет если человеческий мозг проиграет по всем параметрам и будет не нужен (в отличие от человеческого мозга, который не способен развиваться, компьютерные системы удваивают вычислительную мощность каждый год. Это заведомо проигрышная гонка).
>$date < time()
>Notice: Object of class DateTime could not be converted to int
>DateTime could not be converted to int
Это просто 10 из 10.
Чтобы сравнить DateTime, мне нужно вызывать метод getTimestamp? Великолепно.
Кстати, а как нейронные сети реализуются програмно? Они ведь не переписывают свой собственный код? Как же тогда они обучаются?
>>686461
Я думаю, это не имя. Вот мануал:
https://httpd.apache.org/docs/2.2/mod/core.html#servername
там написано:
> ServerName [scheme://]fully-qualified-domain-name[:port]
Там имя, а не адрес. Ниже:
> If you are using name-based virtual hosts, the ServerName inside a <VirtualHost> section specifies what hostname must appear in the request's Host: header to match this virtual host.
Там указывается имя, которое сравнивается с тем что в занголовке Host.
Теперь про алиас:
https://httpd.apache.org/docs/2.2/mod/core.html#serveralias
> ServerAlias hostname [hostname] ...
Я тоже тут не вижу ип адреса.
то есть в апаче 2.2 нельзя (или нет смысла?) указывать там Ip адреса.
Насчет того какой виртуал хост используется по умолчанию, и как на это повлиять - надо читать мануал. мне некогда, если ты можешь то почитай.
>>686461
Я думаю, это не имя. Вот мануал:
https://httpd.apache.org/docs/2.2/mod/core.html#servername
там написано:
> ServerName [scheme://]fully-qualified-domain-name[:port]
Там имя, а не адрес. Ниже:
> If you are using name-based virtual hosts, the ServerName inside a <VirtualHost> section specifies what hostname must appear in the request's Host: header to match this virtual host.
Там указывается имя, которое сравнивается с тем что в занголовке Host.
Теперь про алиас:
https://httpd.apache.org/docs/2.2/mod/core.html#serveralias
> ServerAlias hostname [hostname] ...
Я тоже тут не вижу ип адреса.
то есть в апаче 2.2 нельзя (или нет смысла?) указывать там Ip адреса.
Насчет того какой виртуал хост используется по умолчанию, и как на это повлиять - надо читать мануал. мне некогда, если ты можешь то почитай.
>человеческий мозг проиграет по всем параметрам
Лол. Человеческий мозг по всем параметрам превосходит компьютер.
Гугли персептрон.
Нихуя. Человеческий мозг способен обманывать, действовать непредсказуемо, а компьютер этого делать не может. Он как бог.
На самом деле человеческий мозг предсказуем, просто там очень сложные алгоритмы. Не бывает рандома.
Смотря с чем.
Если DateTime с DatetTime то для них работают (с помощью магии) операторы сравнения
и есть метод diff http://php.net/manual/ru/datetime.diff.php
Обрати внимание что === в отличие от == сравнивает идентичность объектов а не их содержание.
>>686475
Обучение нейросети - это подбор коэффициентов связи (весов) у входов нейронов. Структура никак не меняется.
Обычно это веса хранятся как числа в массиве так что спокойно меняются.
Условно при обучении мы имеем пары "что на входе" - "что должно быть на выходе", например:
- на входе A, на выходе X
- на входе B на выходе Y
Это называется обучающая выборка.
Мы подаем на вход A, и затем разными методами корректируем веса входов нейронов так, чтобы сигнал на выходе имел минимальное отличие от X. затем берем следующую пару и тд. пока не обучим.
например можно использовать метод обратного распространения: мы смотрим какие нейроны сработали правильно и поощраяем их, а неправильных наказываем (уменьшая у них коэффициенты).
https://habrahabr.ru/post/198268/ (увы, много формул, хотя это можно проще объяснить, так что даже без математики будет видна логика)
Ну и в реализации там перемудрили, классы там вообще не нужны.
https://ru.wikipedia.org/wiki/Метод_обратного_распространения_ошибки
Потом на тренировочной выборке (где у нас тоже есть известные пар вход-выход) мы проверяем: угадает нейросеть ответ или нет. Если разница с правильным ответом большая- значит мы где-то накосячили и плохо обучили или взяли плохую выборку.
Нейросеть не создает новых знаний. При обучении в весах нейронов закладывается информация из обучающей выборке, и затем нейросеть при подаче сигнала на вход распознает в нем похожие паттерны на те что заложены при обучении.
Я тебе советую почитать про примеры простых сетей - вроде перцептрона, который изучен вдоль и поперек.
Смотря с чем.
Если DateTime с DatetTime то для них работают (с помощью магии) операторы сравнения
и есть метод diff http://php.net/manual/ru/datetime.diff.php
Обрати внимание что === в отличие от == сравнивает идентичность объектов а не их содержание.
>>686475
Обучение нейросети - это подбор коэффициентов связи (весов) у входов нейронов. Структура никак не меняется.
Обычно это веса хранятся как числа в массиве так что спокойно меняются.
Условно при обучении мы имеем пары "что на входе" - "что должно быть на выходе", например:
- на входе A, на выходе X
- на входе B на выходе Y
Это называется обучающая выборка.
Мы подаем на вход A, и затем разными методами корректируем веса входов нейронов так, чтобы сигнал на выходе имел минимальное отличие от X. затем берем следующую пару и тд. пока не обучим.
например можно использовать метод обратного распространения: мы смотрим какие нейроны сработали правильно и поощраяем их, а неправильных наказываем (уменьшая у них коэффициенты).
https://habrahabr.ru/post/198268/ (увы, много формул, хотя это можно проще объяснить, так что даже без математики будет видна логика)
Ну и в реализации там перемудрили, классы там вообще не нужны.
https://ru.wikipedia.org/wiki/Метод_обратного_распространения_ошибки
Потом на тренировочной выборке (где у нас тоже есть известные пар вход-выход) мы проверяем: угадает нейросеть ответ или нет. Если разница с правильным ответом большая- значит мы где-то накосячили и плохо обучили или взяли плохую выборку.
Нейросеть не создает новых знаний. При обучении в весах нейронов закладывается информация из обучающей выборке, и затем нейросеть при подаче сигнала на вход распознает в нем похожие паттерны на те что заложены при обучении.
Я тебе советую почитать про примеры простых сетей - вроде перцептрона, который изучен вдоль и поперек.
Да все это понятно. Как написать такую вещь, попробую объяснить.
Пишу memcache например, меня перекидывает на новую строку в терминале. Далее я могу уже вводить любые команды и передавать их скрипту. Как такое делается? Так же надо делать?
Захват территории. Почитай в википедии.
Обыграть не может так как вариантов ходов очень много и перебрать ходы не получится. Также, партии не повторяются.
И там есть такая штука, как стратегическое влияние, то есть захватывая пункт ты может быть только через 20 ходов используешь этот пункт для победы над группой противника. А компьютер так далеко просчитать не может.
Одно дело когда такой пункт один, а когда сложная конфигурация, и там несколько таких пунктов то вообще не понять что может получиться.
>>686481
Но в шахматы проигрывает.
>>686475
Сеть описывается массивом чисел. Перцептрон можно хоть на пхп написать, можешь заняться, попробуй цифры пораспознавать.
>>686493
Там есть разные интепретации, в том числе исключающие этот самый рандом (многомировая теория). Сама квантовая физика лишь дает формулы для расчета вероятности той или иной конфигурации или перехода одной в другую, но от объяснения как это понимать, уклоняется.
Ну например долгое время использовалась Копенгагенская интепретация, в рамках которой несчастная кошка Шредингера должна была быть в суперпозиции живого и мертвого состояния.
Объяснять такие вещи сложно, это как если бы жители двухмерного мира пытались осознать что они на самом деле живут на плоскости в трехмерном мире.
Если интересно, есть цикл статей на хабре https://geektimes.ru/post/171489/
Формул там почти нету, скорее философия, можно читать и не физикам.
Захват территории. Почитай в википедии.
Обыграть не может так как вариантов ходов очень много и перебрать ходы не получится. Также, партии не повторяются.
И там есть такая штука, как стратегическое влияние, то есть захватывая пункт ты может быть только через 20 ходов используешь этот пункт для победы над группой противника. А компьютер так далеко просчитать не может.
Одно дело когда такой пункт один, а когда сложная конфигурация, и там несколько таких пунктов то вообще не понять что может получиться.
>>686481
Но в шахматы проигрывает.
>>686475
Сеть описывается массивом чисел. Перцептрон можно хоть на пхп написать, можешь заняться, попробуй цифры пораспознавать.
>>686493
Там есть разные интепретации, в том числе исключающие этот самый рандом (многомировая теория). Сама квантовая физика лишь дает формулы для расчета вероятности той или иной конфигурации или перехода одной в другую, но от объяснения как это понимать, уклоняется.
Ну например долгое время использовалась Копенгагенская интепретация, в рамках которой несчастная кошка Шредингера должна была быть в суперпозиции живого и мертвого состояния.
Объяснять такие вещи сложно, это как если бы жители двухмерного мира пытались осознать что они на самом деле живут на плоскости в трехмерном мире.
Если интересно, есть цикл статей на хабре https://geektimes.ru/post/171489/
Формул там почти нету, скорее философия, можно читать и не физикам.
Тебе не надо писать клиент мемкеша - только сервер. Как делается? Открываешь стандартный вход и читаешь с него строки. Если хочешь редактирование и автодополнение, нужна библиотека readline (только линукс):
http://php.net/manual/ru/features.commandline.io-streams.php
http://php.net/manual/ru/function.readline.php
>Формул там почти нету, скорее философия, можно читать и не физикам.
Квантовую физику без математики не объяснить.
Если ты собираешься рассчитать атом водорода или что-то еще - да, формулы нужны. А если просто понять принципы то может и не особо нужны.
Не понял. Я ввожу в терминале SET и демон сразу считывает? Или должен подключиться через telnet, или что?
Демон ничего не считывает из терминала. Он работает в фоне и принимает соединения через TCP порт или unix domain сокет. Ты должен подсоединиться и передавать команды через соединение.
Чтобы сделать что-то с мемкешем, ты должен подключиться к нему (например через telnet, netcat или другю программу).
Кстати было бы здорово если все эти инструменты http://lzone.de/cheat-sheet/memcached работали с твоим псевдомемкешем.
>>686554
Выглядеть может так: в одном терминале ты запускаешь демон, он в нем сидит и в него же пишет логи для отладки.
В другом терминале соединяешься с ним и щлещь команды.
Так это же все равно будет тот же мемкеш, я просто буду спаршивать команды и передавать ему?
И еще кстати, с помощью xinetd в линуксе можно превратить в сетевого демона обычную программу, работающую исключительно со стандартным входом и выходом. Ну например ты можешь взять команду date (выводит текущее время и дату) и получишь сервис который при соединении с ним выводит время/дату и закрывает соединение.
Нет. Ты будешь исполнять команды сам.
Тебе надо написать реализацию сервера мемкеша. Сервер это тот кто принимает запросы и обрабатывает их. Это значит ты должен хранить в памяти ключи, изменять и искать их в ответ на запросы клиентов.
А с помощью чего я буду хранить в памяти данные? Просто присваивать перменным? Или как свойства класса?
Свойства класса это и есть просто переменные.
>с помощью магии
Что значит магия? Разве приведение типов это не нормальная практика?
Ну, в общем, странно, что при вызове DateTime в контексте int не вызывается getTimestamp().
>есть метод diff
Который вернет DateInterval. Слишком много ООП для простого сравнения больше-меньше.
Подумай, какие данные хранятся в мемкеше. Подумай, какой способ хранения лучше подойдет.
> Или как свойства класса?
Объект это не массив чтобы в него свойства добавлять.
>>686663
> Что значит магия?
Что для объектов работают операторы больше/меньше, ты не можешь сделать так же для своих классов и приведение тут не при чем.
>ты не можешь сделать так же для своих классов
Серьезно, PHP это не может? Я недавно вкатился прост
Поясните пожалуйста, как $text1. сравнивается с массивом?
Когда я решал впервые, я думал, что нужно решать через массив, но я думал, что нужно сделать 2 массива и сравнить их элементы ($i будет ключом, в таком случае). Тут всё было бы понятно: i задала ключ для двух массивов, элементы сравнились:
0 => "а" == 0 => "а"
Как происходит сравнение в этом решении http://ideone.com/4w2ckX ? Что там с чем сравнивается? Почему переменная записана как $text1. (с точкой)? Короче, можете объяснить, как это работает?
А ещё я нихуя не пойму, какое значение было присвоено $text1.
По идее, вот это действие $text1.=$textarray[$i] каждый ход цикла присваивает переменной $text1. новое значение (каждый цикл - одна буква). На выходе $text1. должен быть равен последней присвоенной букве. В таком случае, почему одна буква оказывается равна целому слову?
Разобрался.
$text1. - это склейка букв.
В $text1. записывается $text задом наперёд, потому что в условии цикла указано не привычное $++, а наоборот $i--. Таким образом, набранное задом наперёд слово сравнивается с исходным словом. Всё верно?
Точка - это конкатенация (склейка строк).
$text1 .= $textarray[$i]; это то же, что $text1 = $text1 . $textarray[$i];
Алсо, решение не оптимальное. Цикл может крутиться меньше, подумай как.
Верно.
Ебать вы учёные, я бы и до этого не додумался)
Совершенно верно.
Сравнивать в цикле (но не строки)
Или сравнивать после цикла
Вдруг он цельные строки будет в цикле сравнивать?
В винде все верно, часовой пояс +3.
Все мануалы по обновлению таймзон в пхп сводятся к установке PECL-пакета. Как я его под виндой установлю? Хелп.
5.3
А что, таймзоны собираются вместе с версией?
Если подскажешь, как обновить PHP в моем Денвере, буду благодарен.
Так вот, в чем суть. Суть в том, что этот скрипт не работал на моём MySQL. У меня стоит php7,apache2.4, mysql 5.7. У одногруппников работало, но на денвере. Поставил я себе денвер. Не работало, пока не удалил MySQL. Тогда заработало. Сначала я подумал, что проблема с портом(и там и там получается порт 3306). Но когда я вместо 3306(когда начал заново устанавливать MySQL Server) поставил 777 то начало выводить ошибки на странице. Когда был MySQL и работающий код, то он просто не работал, ошибок не показывало. Просто не добавляло данные пользователя в базу.
В чем может быть проблема? Если кто-то готов чуть углубиться чтобы помочь, можете дать контакты, скину проект, он очень маленький, кода практически нет. Не могу понять почему не работает на новых инструментах, а на денвере(специально чтобы потестить проект, я его и поставил) работает. Пример для регистрации-авторизации брал тут http://htmlweb.ru/php/example/avtorizacija2.php , но у меня уже немного доработанный вариант.
Буду очень рад, если поможете(работать в денвере нет желания, но похоже придется если не пофиксю).Очень долго над этим сидел и никак не хочет работать. Подключение шло ч-з ф-ции что работают в php7(ошибок не было). MySQL php apache, поставленные ручками, работали прекрасно, проверял до этого.
Так вот, в чем суть. Суть в том, что этот скрипт не работал на моём MySQL. У меня стоит php7,apache2.4, mysql 5.7. У одногруппников работало, но на денвере. Поставил я себе денвер. Не работало, пока не удалил MySQL. Тогда заработало. Сначала я подумал, что проблема с портом(и там и там получается порт 3306). Но когда я вместо 3306(когда начал заново устанавливать MySQL Server) поставил 777 то начало выводить ошибки на странице. Когда был MySQL и работающий код, то он просто не работал, ошибок не показывало. Просто не добавляло данные пользователя в базу.
В чем может быть проблема? Если кто-то готов чуть углубиться чтобы помочь, можете дать контакты, скину проект, он очень маленький, кода практически нет. Не могу понять почему не работает на новых инструментах, а на денвере(специально чтобы потестить проект, я его и поставил) работает. Пример для регистрации-авторизации брал тут http://htmlweb.ru/php/example/avtorizacija2.php , но у меня уже немного доработанный вариант.
Буду очень рад, если поможете(работать в денвере нет желания, но похоже придется если не пофиксю).Очень долго над этим сидел и никак не хочет работать. Подключение шло ч-з ф-ции что работают в php7(ошибок не было). MySQL php apache, поставленные ручками, работали прекрасно, проверял до этого.
На гитхаб закинь. Давать контакты, ради потенциальной порции лапши, тут вряд ли будет много желающих.
>>686849
>>686852
https://github.com/EvgheniiSytnyk/Clio-Caliope
Вот скинул. Гитхабом пользоваться особо не умею и в php практически новичек, так что не придирайтесь.
Точнее придирайтесь и говорите что не так, но не насмехайтесь.
> Объект это не массив чтобы в него свойства добавлять.
Я не об этом. Свойство $data, там информация хранится, свойство $expire там время жизни написано. Ну и уничтожать объект из памяти потом. Верно? Если так, то все слишком просто получается.
В register.php у тебя какой-то странный запрос, попробуй переписать инсерт под шаблон отсюда: http://www.w3schools.com/php/php_mysql_insert.asp
Никогда не видел чтобы где-то использовался insert into с подобным синтаксисом, больше похоже на update, но сейчас проверил у себя в MariaDB (тот же MySQL с некоторыми отличиями) - твой вариант работает. Я и сам тут недавно, так что оставлю это на кого-нибудь более скиллованого
Тут-то проблема судя по всему не в этом. А в том, что новый Apache+PHP+MySQL не работает, поставленные ручками, а денвер с коробочки работает.
5.6.8 тоже запускается, и все работает, но Апач почему-то начинает ругаться на одну из библиотек.
С 5.6.19 Апач вообще падает при любом запросе.
Воот
Должен парсить гугл подсказки и сохранять результат в result.txt, но создаётся пустой файл
Помогите пожалуйста
Запрос для создания базы там же.
Захожу я в admin.php, и у меня права юзера.
>(($userdata['user_ip'] !== $_SERVER['REMOTE_ADDR']) and ($userdata['user_ip'] !== "0")))
А если в базе остался IP с прошлого залогина?
Тебе три строчки не отладить?
Все, что надо проверить - есть ли ответ, и не съедают ли регулярки весь текст.
Ну по идее с каждого логина же перезаписывается айпишник, каждый раз. Я этот код не сам писал, а нашел и чуть доработал. Вопрос в другом - почему на собственноручно поставленных инструментах не работает? Ты тестил на готовой сборке или сам ставил всё?
Хотя, в admin.php надо все же будет поменять местами вывод сообщения о правах админа и проверку на айди. Но это уже завтра, комп выключил уже(целый день сидел).
Помимо установки Apache, MySQL и PHP, какие-либо ещё настройки над ними производил? Может, в php.ini одна из строчек extension, отвечающая за работу mysqli, заблочена?
Нет, как раз mysqli прекрасно работает. Я создавал в консоли базу данных маленькую с двумя полями, и с помощью mysqli выводил в php-скрипте, работало. В настройках ничего не менял кроме того, что разблочил mysqli и pdo.
Я мимо проходил но это выглядит наркомански:
> $userdata['user_ip'] !== "0"
Как IP-адрес может быть равен нулю?
Включи отображение ошибок либо смотри логи. Не бывает так что ничего не работает на пустом месте.
Ладно, я завтра еще скрины ошибок скину в тред. Просто я сидел сегодня за компом весь день и устал. Рассчитывал что кто-то скачает себе мой проект и потестит у себя, будет ли у него корректно работать, а этого так никто и не сделал, что печально.
Соррян, бро, я бы потестил, но я тупой и сам буду сношаться полдня с тем, как запустить.
Скачиваешь архив с гитхаба, разархивируешь, скидываешь папку в С:\Apache24\htdocs, запускаешь localhost/названиеПапки/registr.php. Вбиваешь туда логин и пароль любые, потом их же вбиваешь в login.php, если пишет про твои права доступа значит работает.
Ну накатил на свою убунту. Вроде работает. За параметры подключения к БД в 3-х разных местах, конечно руки нужно отбивать.
А зачем тебе эта лапша древняя?
Расскажи как это сделать. Тоже хочу, но я слишком ленив, чтобы искать самому мануал.
Палиндром - тихий ужас.
При этом не работает правильно: http://ideone.com/ucgsR2
Внутрь можно роман Льва Толстого "Война и мир" поместить.
Копипаста - зло в программировании.
Здесь можно использовать простой алгоритм после удаления пробелов и приведения букв к одному регистру:
1. Сравниваем в цикле for первую букву в строке с последней. Если они не совпадают - выводим результат "Не палиндром". Если совпадают - перемещаемся по строке с обеих сторон: сравниваем вторые буквы с начала и конца строки.
2. Изменять ориентиры для работы функции mb_substr можно с помощью переменной $i, которая будет изменяться при каждом прохождении цикла.
3. Когда $i становится равной $halfLength (это означает, что цикл работал, буквы удачно сравнивались) - выводим результат "Это палиндром".
Аа, да: задача про Айпад решена верно.
Переделал вывод ошибок, и сделал двумерный массив, как советовал.
http://ideone.com/BQSvJk //«Grammar Nazi»
Открыть порт
Пока (не поступила команда завершиться) {
принять соединение;
обработать соединение;
}
Обработка соеднения:
Пока(соединение не закрыто) {
Пока (в буфере не собралась полная команда) {
- прочитать данные из сокета в буфер
}
- Распарсить команду из буфера, оставив в буфере следующую команду
- выполнить команду
- подготовить ответ
Пока (ответ не отправлен целиком) {
отправить следующую порцию ответа
}
}
Тут есть несколько подвохов:
- с сервером не могут одновременно работать 2 клиента
- если клиент не читает ответ, сервер заблокируется на этапе его отправки
- если клиент прекратил отправлять запрос, сервер заблокируется на его чтении
Костылики:
- ввести таймаут на сессию работы с мемкешем, по истечении - выкидывать клиента
- ограничить число запросов, например после первого же запроса закрывать соединение чтобы дать шанс другим выполнить запрос
Полноценное решение этих проблем требует освоить асинхронное программирование (напрмер socket_selet или мощный фреймворк ReactPHP - я думаю, мы это сделаем но для начала надо научиться более простым вещам).
Не забывай проверять все операции ввода вывода на ошибки. Проще всего это сделать. обернув работу с сокетами в класс с исключениями.
Не забывай следовать принципу разделения кода и единой ответственности. Я вижу такие классы:
- класс работы с сокетами
- класс парсинга команд протокола и кодирования ответа
- классы представлющие команды мемкеша
- класс реализующий хранилище данных и операции над ними
Вообще, тут конечно вопрос, есть ли смысл использовать паттерн Команда и делать каждую команду отдельным классом. Я думаю, есть.
Открыть порт
Пока (не поступила команда завершиться) {
принять соединение;
обработать соединение;
}
Обработка соеднения:
Пока(соединение не закрыто) {
Пока (в буфере не собралась полная команда) {
- прочитать данные из сокета в буфер
}
- Распарсить команду из буфера, оставив в буфере следующую команду
- выполнить команду
- подготовить ответ
Пока (ответ не отправлен целиком) {
отправить следующую порцию ответа
}
}
Тут есть несколько подвохов:
- с сервером не могут одновременно работать 2 клиента
- если клиент не читает ответ, сервер заблокируется на этапе его отправки
- если клиент прекратил отправлять запрос, сервер заблокируется на его чтении
Костылики:
- ввести таймаут на сессию работы с мемкешем, по истечении - выкидывать клиента
- ограничить число запросов, например после первого же запроса закрывать соединение чтобы дать шанс другим выполнить запрос
Полноценное решение этих проблем требует освоить асинхронное программирование (напрмер socket_selet или мощный фреймворк ReactPHP - я думаю, мы это сделаем но для начала надо научиться более простым вещам).
Не забывай проверять все операции ввода вывода на ошибки. Проще всего это сделать. обернув работу с сокетами в класс с исключениями.
Не забывай следовать принципу разделения кода и единой ответственности. Я вижу такие классы:
- класс работы с сокетами
- класс парсинга команд протокола и кодирования ответа
- классы представлющие команды мемкеша
- класс реализующий хранилище данных и операции над ними
Вообще, тут конечно вопрос, есть ли смысл использовать паттерн Команда и делать каждую команду отдельным классом. Я думаю, есть.
Но там как бы нихуя нет, или я не прав? Где почитать-то что это и как использовать?
Ну тип создаешь класс студентов и класс шлюза студентов. Шлюз имеет методы вставки в бд(принимает объект студент), удаления из бд, выборки данных и т.п.
А тут https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md ?
TDG это когда просто операции надо таблицей собирают в один класс.
Каждый класс должен быть в своем файле. Тебе нужна автозагрузка: https://github.com/codedokode/pasta/blob/master/php/autoload.md
(кстати в гитхабе ОПа есть и другие не менее полезные уроки).
спасибо опять
https://ideone.com/gnBTvs
Самый простой напрашивающийся вариант это margin-top, но я тут на всяких сайтах постоянно встречаю такое мнение что блок должен быть универсален и не зависеть от окружения, что если в шаблоне вырезать логотип или заголовок и вставить в другое место он должен вести себя независимо, а сохранив этот отступ сверху он может и сам уехать вниз и другие блоки что под ним вытолкнуть вниз. position: relative/absolute еще хуже так как выключает блок из потока вообще.
inline-block + vertical align, table-cell - все те же проблемы.
Можно ли запилить какие-то вспомогательные классы типа .margin-top-40 и вынести в них то что относится к позиционированию, а потом добавлять к основному классу? Ну например
<div class="logo margin-top-40">
Насколько это костыльно?
В данном случае 2 указанных штуки можно спозиционировать абсолютно относительно огромного блока с картинкой. Почему АП? Потому что в данном случае если подумать то расположение надписей жестко задано относительно родителя (столько-то пикселей слева и сверху).
Однако! Надо понимать что при изменении ширины экрана места для надписей может не хватить. Потому необходимо:
- если сайт неадаптивный, задать для него миним. ширину например 800 пикс (точное число надо проверять опытным путем). Мин. ширина задается через min-width на body.
- если сайт адаптивный, надо поменять правила позиционирования этих блоков (и размеры шапки) на маленькой ширине.
То есть мы выбираем способ позиционирования исходя из логики расположения блоков. Подумай: от чего зависит расположение этого блока и его размеры? К чему он привязан?
Ответ прост: расположение привязано к шапке, размер определяется содержимым.
В моем способе если добавить контент перед шапкой или перенести шапку в другое место надписи останутся расположенными корректно. значит я правильно выбрал схему позиционирования.
Минус АП в том что блоки не могут влиять друг на друга и на родителя. Например если в нижнюю надпись мы зафигачим 3 абзаца текста, она очень некрасиво вывалится из шапки. Если такая необходимость есть, придется отказаться от АП и сделать эти 2 блока через display block с маргинами или флоаты, а саму шапку растягивающейся (понятно что тут это не требуется, но может в другой ситуации подойдет.).
> Можно ли запилить какие-то вспомогательные классы типа .margin-top-40 и вынести в них то что относится к позиционированию, а потом добавлять к основному классу? Ну например
С таким же успехом можно написать style="margin...". Стили должны быть в cSS, более того я не понимаю что тебе мешает их повесить на класс .logo?
> Как по уму вертикально позиционировать элементы?
Зависит от конкретной ситуации, есть варианты: АП, inline-block, display table.
> но я тут на всяких сайтах постоянно встречаю такое мнение что блок должен быть универсален и не зависеть от окружения, что если в шаблоне вырезать логотип или заголовок и вставить в другое место он должен вести себя независимо
В данном случае если подумать, эти 2 блока действительно никак друг от друга не зависят. Маргин-топом выравнивать их действительно неправильно.
> position: relative/absolute еще хуже так как выключает блок из потока вообще.
В данном случае мы понимаем что в нем может быть только заданный нами текст и мы можем грубо прикинуть его размеры.
Кстати, если тебе интересно, для строки меню/поиска есть 2 варианта:
- сделать поиск и блок меню флоатами в разные стороны, и внутри блока меню сделать 5 флоатов с 20% шириной
- сделать единую строку из display table.
Алсо на картинке надпись industrial solution надо подвинуть вниз. Она должна быть на одном уровне с другими заголовками, а не привязана к форме поиска.
Можно. Есть готовые решения типа BitWebServer или ksweb.
Ну или если ты любитель игр с консолькой, можешь найти гайды в интернете и собрать апач и пхп под arm архитектуру сам.
А ты сможешь помочь, если будут вопросы? Хочу собрать. Рут у меня есть, консолька есть. Осталось погулить.
Рут не нужен
Нужны:
- веб сервер, например Апач
- интерпретатор PHP
- при желании mysql
- редактор для кода
- браузер чтобы смотреть получившийся сайт (не уверен, можно ли на андроиде править hosts - так что возможно придется заходить по IP или localhost)
Есть разные программы, платные и бесплатные, и это все можно ставить по частям или может быть вместе. Обычно там, где все вместе и уже настроено - платно.
Алсо насколько я знаю на андроиде очень неудобно переключаться между программами, потому если у тебя редактор и браузер отдельные то может быть не очень удобно. Ну и плюс стандартный браузер не позволяет смотреть исходный код страницы.
Исходный код мне не нужен. Я не верстать. Приложения сворачиваются, немного медленней, чем на компе. Буду пробовать.
>В моем способе если добавить контент перед шапкой или перенести шапку в другое место надписи останутся расположенными корректно. значит я правильно выбрал схему позиционирования.
Парирую. Приходит чувак и говорит добавь в шапку какой-нибудь шняги между этими двумя блоками. Так как они спозиционированы новый блок их не видит и отображается поверх или под ними. В случае с маржинами такого не случилось бы.
>К чему он привязан?
Хороший вопрос. То что к шапке понятно, но с равным успехом можно сказать '50рх от верхнего края' или '40% от высоты'. Макет нам об этом ничего не скажет.
>>687718
>С таким же успехом можно написать style="margin...". Стили должны быть в cSS
Они в css. Типа такой вспомогательный класс. И я уже собственно нагуглил, в бутстрапе такое применяется.
>более того я не понимаю что тебе мешает их повесить на класс .logo?
Переносим лого в другое место и там оно тоже отжимается книзу. А должно себя вести как обычный div.
> Парирую. Приходит чувак и говорит добавь в шапку какой-нибудь шняги между этими двумя блоками. Так как они спозиционированы новый блок их не видит и отображается поверх или под ними.
Придется переделать. Ведь этот чувак может заодно например попросить и логотип вправо передвинуть, чтобы место расчистить. Ну и в случае с маргинами маргины придется менять чтобы освободить место. То есть все равно что-то менять придется.
Конечно если у тебя там надо будет вместо одной надписи отобразить например несколько друг над другом то надо спозиционировать абс. блок с надписями, а сами надписи сделать блочной версткой.
К счастью, переделка затронет только блок шапки что я не считаю большой проблемой.
Плохо это например если у тебя например расположение меню привязано к высоте шапки и при изменении высоты шапки она залезает под меню.
> . То что к шапке понятно, но с равным успехом можно сказать '50рх от верхнего края' или '40% от высоты'. Макет нам об этом ничего не скажет.
Надо включить интуицию. Я бы использовал пиксели относительно верха и лева на случай если какой-то маньяк захочет удлинить шапку.
> Переносим лого в другое место и там оно тоже отжимается книзу. А должно себя вести как обычный div
Нет. Очевидно что при переносе в другое место придется менять правила позиционирования под новое окружение. Там суть в том что если у тебя лого - сложный составной объект то внутренние элементы при переносе не надо переверстывать.
Ну проще наверно на меню пояснить: мы переносим меню с верха страницы в низ, и внутренние блоки в этом меню не требуется менять.
Там есть пакетный менеджер, и гугл плей (которым можно не пользоваться, а скачивать и устанавливать пакты руками).
Есть две таблицы, в одной столбец с именем name, и в другой столбец с именем name.
Вопрос в следующем: почему при вызове запроса типа
>SELECT `table1`.`name`, `table2`.`name` FROM `table1` INNER JOIN `table2` ON `id`.`table1`=`id`.`table2`
пхп в результате выводит значение только одного столбца, а другого как будто бы и нет?
Вот то, что выдал пхп:
Array
(
[0] => Array
(
[name] => чекбокс
)
[1] => Array
(
[name] => чекбокс
)
...
Ну и так далее.
MySQL выдаёт то, что на пикче.
Короче, что это всё значит, аноны? Надо перед названиями столбцов ставить префиксы?
Ты массивы изучал? В массиве не может быть 2 элементов с одним именем, очевидно второй столбец перезаписывает первый. задай для них синонимы (алиасы) в запросе.
Понял, анон, спасибо. :З
А вообще, я думал, что MySQL учитывает, что возвращаться будут значения с одинаковыми ключами, и автоматически меняет значения ключей у одинаковых элементов. Примерно как на скрине, да.
Вот поэтому sql такая хуета. Рикаминдую Mongo и Redis.
Ты бы хоть как-то в комментарии написал что там за алгоритм. А то я открываю - стена кода и многомерные массивы в которых непонятно что хранится.
> $INF = 1000000000;
Есть константа INF с настоящей бесконечностью
Переменным надо давать осмысленные имена: $banknotes as $key => $value - что такое key?
Здесь:
> if ($minBanknotes[$i][$amount-$key]
Не может получиться несуществующий отрицательный индекс?
> foreach ($minBanknotes[$i] as $key => $value) {
> if ($minBanknotes[$i][$amount-$key] == $minBanknotes[$i][$amount]-1){
Это выглядит как-то переусложненно. Зачем нам перебирать все значения key когда мы можем перебирать только значения соответствующие номиналам купюр?
Также, у тебя нет проверки что данная комбинация купюр имеется в наличии. Теоретически можно было бы проверять каждую комбинацию купюр, есть такой запас или нет.
Однако, использованный алгоритм не гарантирует решения задачи. Он находит комбинации с минимальным числом купюр, а вполне возможно что для решения нужна "неоптимальная" комбинация. Получается надо использовать перебор всех возможных комбинаций.
>>679536
При чем тут Апач? Ты ведь код запускаешь не через Апач а через веб-сервер настроенный в phpstorm. даже на скриншоте видно что там написано phpstorm, а не Апач. Я тебе написал что нужно сделать: нужно изучить документацию по phptorm которая есть в интернете (на англ.) и разобраться какой тип сервера с какими настройками там исплоьзуется.
Ну либо не запускать код через phpstorm.
Также теоретически этот веб-сервер может писать подробности ошибок куда-то в лог, но я не знаю куда.
>>679533
Там не Апач
Ты бы хоть как-то в комментарии написал что там за алгоритм. А то я открываю - стена кода и многомерные массивы в которых непонятно что хранится.
> $INF = 1000000000;
Есть константа INF с настоящей бесконечностью
Переменным надо давать осмысленные имена: $banknotes as $key => $value - что такое key?
Здесь:
> if ($minBanknotes[$i][$amount-$key]
Не может получиться несуществующий отрицательный индекс?
> foreach ($minBanknotes[$i] as $key => $value) {
> if ($minBanknotes[$i][$amount-$key] == $minBanknotes[$i][$amount]-1){
Это выглядит как-то переусложненно. Зачем нам перебирать все значения key когда мы можем перебирать только значения соответствующие номиналам купюр?
Также, у тебя нет проверки что данная комбинация купюр имеется в наличии. Теоретически можно было бы проверять каждую комбинацию купюр, есть такой запас или нет.
Однако, использованный алгоритм не гарантирует решения задачи. Он находит комбинации с минимальным числом купюр, а вполне возможно что для решения нужна "неоптимальная" комбинация. Получается надо использовать перебор всех возможных комбинаций.
>>679536
При чем тут Апач? Ты ведь код запускаешь не через Апач а через веб-сервер настроенный в phpstorm. даже на скриншоте видно что там написано phpstorm, а не Апач. Я тебе написал что нужно сделать: нужно изучить документацию по phptorm которая есть в интернете (на англ.) и разобраться какой тип сервера с какими настройками там исплоьзуется.
Ну либо не запускать код через phpstorm.
Также теоретически этот веб-сервер может писать подробности ошибок куда-то в лог, но я не знаю куда.
>>679533
Там не Апач
Ты по моему переусложнил. Для проверки допустимости можно просто сравнивать получившиеся комбинации с запасом купюр.
>>679773
> Поскольку F определяется рекуррентно то уже при числах порядка 50000 уходит ОООЧЕНЬ много времени.
Там же вроде сложность = сумма x число купюр, терпимо. Ну и можно поделить все суммы на наибольший общий делитель номиналов купюр.
> Так что этот алгоритм для решения задачи про банкомат с ограничением банкнот не подходит.
Похоже, что да ((
>>680027
Там пока единственный сигнал который ты будешь подавать это Ctrl + C, не требуется писать средства демонизации, управления запуском и тд.
>>680036
Не знаю, я не знаю что ты с ним хочешь сделать.
>>680177
Сделать таблицу кто как голосовал
По ссылке пусто
>>680368
Да, для начала такое решение подойдет
>>680435
Ты скопипастил функцию 3 раза. Суть функций в том чтобы наоборот избегать копипасты и сделать одну функцию для всех случаев. Потому решение неправильное.
Алсо у тебя там бесконечный цикл: for(;;)
Ну и лучше начни с задачи на айфон, так как по сути тут надо просто взять код из той задачи и завернуть в функцию.
>>680441
Похоже что ты прав
>>680458
У тебя не код а сплошная копипаста. Функция скопирована 3 раза, суммы выплат скопипащены десять раз, так писать нельзя. Надо избавиться от всех повторов. Похоже что ты пока не разобрался зачем нужны функции.
> for(;;){
Сюда можно добавить условие проверяющее остаток долга. В оригинальной задаче там счетчик месяцев для защиты от зацикливания.
По ссылке пусто
>>680368
Да, для начала такое решение подойдет
>>680435
Ты скопипастил функцию 3 раза. Суть функций в том чтобы наоборот избегать копипасты и сделать одну функцию для всех случаев. Потому решение неправильное.
Алсо у тебя там бесконечный цикл: for(;;)
Ну и лучше начни с задачи на айфон, так как по сути тут надо просто взять код из той задачи и завернуть в функцию.
>>680441
Похоже что ты прав
>>680458
У тебя не код а сплошная копипаста. Функция скопирована 3 раза, суммы выплат скопипащены десять раз, так писать нельзя. Надо избавиться от всех повторов. Похоже что ты пока не разобрался зачем нужны функции.
> for(;;){
Сюда можно добавить условие проверяющее остаток долга. В оригинальной задаче там счетчик месяцев для защиты от зацикливания.
> public function hireEmployee($occupation, $rank, $boss) {
Эта функция странно смотрится в департаменте. Зачем это департамент создает работников? Вот смотри, завтра мы допустим захотим добавить работнику свойство "возраст". мы отредактируем класс Employee. Как теперь через твою функцию задать возраст работника? Надо переделывать еще и эту функцию.
Вот подумай, где тут логика: мы добавили свойство в работника, а должны еще править код в других местах программы. ООП придумывался как раз чтобы такого бардака не было. Чтобы достаточно было только поменять код одного класса.
Классы должны каждый отвечать за свою область. Департамент не должен определять процесс создания работника.
> $name = $name . "(босс)";
Это ведь не обновится при потере статуса босса. И ранг не поменяется в имени.
> public function getStatistics() {
Нет смысла делать гигантсткую функцию, лучше сделать 3 раздельных функции.
> switch($employee->getOccupation()) {
> case "аналтик":
В ООП делается не так. Для расчет зарплаты достаточно информации о работнике и значит этот код должен быть в нем.
В твоем коде например нельзя добавить новую профессию не трогая код департамента.
Для обозначения разных профессий надо использовать константы, а не надписи на русском. Что если у тебя опечататься в названии профессии? Никакого сообщения об ошибке не будет.
О, ты опечатался сам и не заметил этого. Потому что твой код не проверяет наличие ошибок в профессии.
> public function createDepartment($name) {
Это очень негибко. Вот смотри, есть 2 отдельных действия:
- создать департамент
- добавить в компанию департамент
Ты вместо того чтобы позволить их делать как угодно, сделал все в одной функции. Но например объект департамента может быть создан снаружи, может быть откуда-то передан и тд. какой смысл запрещать добавлять созданный снаружи департамент?
Ну и опять же, если мы например добавить департаменту какие-то новые свойства, нам придется идти и переделывать код класса Компании- это значит что неудачно спроектированы эти классы.
> public function hireEmployee($occupation, $rank, $boss, $department) {
Ты эту функцию копируешь в оба объекта - это верный признак что у тебя неправильно спроектирвоаны классы. За найм работников должен отвечать кто-то один.
Также неправильно идентифицировать департаменты по названию. Объект сам по себе уникален и идентифицирует сам себя, название не требуется, достаточно иметь ссылку на объект.
> public function hireEmployee($occupation, $rank, $boss) {
Эта функция странно смотрится в департаменте. Зачем это департамент создает работников? Вот смотри, завтра мы допустим захотим добавить работнику свойство "возраст". мы отредактируем класс Employee. Как теперь через твою функцию задать возраст работника? Надо переделывать еще и эту функцию.
Вот подумай, где тут логика: мы добавили свойство в работника, а должны еще править код в других местах программы. ООП придумывался как раз чтобы такого бардака не было. Чтобы достаточно было только поменять код одного класса.
Классы должны каждый отвечать за свою область. Департамент не должен определять процесс создания работника.
> $name = $name . "(босс)";
Это ведь не обновится при потере статуса босса. И ранг не поменяется в имени.
> public function getStatistics() {
Нет смысла делать гигантсткую функцию, лучше сделать 3 раздельных функции.
> switch($employee->getOccupation()) {
> case "аналтик":
В ООП делается не так. Для расчет зарплаты достаточно информации о работнике и значит этот код должен быть в нем.
В твоем коде например нельзя добавить новую профессию не трогая код департамента.
Для обозначения разных профессий надо использовать константы, а не надписи на русском. Что если у тебя опечататься в названии профессии? Никакого сообщения об ошибке не будет.
О, ты опечатался сам и не заметил этого. Потому что твой код не проверяет наличие ошибок в профессии.
> public function createDepartment($name) {
Это очень негибко. Вот смотри, есть 2 отдельных действия:
- создать департамент
- добавить в компанию департамент
Ты вместо того чтобы позволить их делать как угодно, сделал все в одной функции. Но например объект департамента может быть создан снаружи, может быть откуда-то передан и тд. какой смысл запрещать добавлять созданный снаружи департамент?
Ну и опять же, если мы например добавить департаменту какие-то новые свойства, нам придется идти и переделывать код класса Компании- это значит что неудачно спроектированы эти классы.
> public function hireEmployee($occupation, $rank, $boss, $department) {
Ты эту функцию копируешь в оба объекта - это верный признак что у тебя неправильно спроектирвоаны классы. За найм работников должен отвечать кто-то один.
Также неправильно идентифицировать департаменты по названию. Объект сам по себе уникален и идентифицирует сам себя, название не требуется, достаточно иметь ссылку на объект.
Ты посылаешь неправильный запрос
> я там поставил функции memory_get_usage перед чтением и записыванием и после. Память возрастает почему-то все равно. Не могу понять.
В PHP автоматическая сборка мусора. Нет гарантий что сборщик будет вызван в данный момент. Работа сборщика мусора описана в мануале.
>>680755
Было бы неплохо тогда показать код, а то я его не вижу.
>>680902
Начать можно с наивного решения полным перебором.
>>680904
ты не обязан такие вещи делать именно через бутстрап. Алсо, я уже не раз говорил, бутстрап плохо подходит для обычных сайтов так как навязывает свою сетку, свои стили, и переопределять все это тяжело и проще его вообще не подключать. Заодно код намного легче станет.
Он вообще то делался для случаев когда не хочется тратить время на дизайн.
>>680908
Платина:
### переносы строк и br
Чтобы переносы строк нормально работали и в браузере и в ideone (и в консоли), можно использовать для этого \n, а в начале программы поставить
header("Content-Type: text/plain; charset=utf-8");
Это заставит браузер воспринимать то, что выводит твоя программа, как обычный текст, а не HTML, и уважать переносы строк в нем (так как в языке HTML перенос строки равносилен пробелу).
Иначе перенос строки будет в исходном коде страницы (его можно увидеть нажав Ctrl + U), но на самой странице его не будет.
Ты посылаешь неправильный запрос
> я там поставил функции memory_get_usage перед чтением и записыванием и после. Память возрастает почему-то все равно. Не могу понять.
В PHP автоматическая сборка мусора. Нет гарантий что сборщик будет вызван в данный момент. Работа сборщика мусора описана в мануале.
>>680755
Было бы неплохо тогда показать код, а то я его не вижу.
>>680902
Начать можно с наивного решения полным перебором.
>>680904
ты не обязан такие вещи делать именно через бутстрап. Алсо, я уже не раз говорил, бутстрап плохо подходит для обычных сайтов так как навязывает свою сетку, свои стили, и переопределять все это тяжело и проще его вообще не подключать. Заодно код намного легче станет.
Он вообще то делался для случаев когда не хочется тратить время на дизайн.
>>680908
Платина:
### переносы строк и br
Чтобы переносы строк нормально работали и в браузере и в ideone (и в консоли), можно использовать для этого \n, а в начале программы поставить
header("Content-Type: text/plain; charset=utf-8");
Это заставит браузер воспринимать то, что выводит твоя программа, как обычный текст, а не HTML, и уважать переносы строк в нем (так как в языке HTML перенос строки равносилен пробелу).
Иначе перенос строки будет в исходном коде страницы (его можно увидеть нажав Ctrl + U), но на самой странице его не будет.
Названия переменных очень неудачные так как путаются. Надо было попроще вроде $index1, $word1.
Чтобы не копипастить, первые 2 строки можно сделать циклом.
Также, можно избавиться от промежуточной переменной и сразу брать слово с индексом array_rand
В конце вместо запятых в эхо лучше использовать двойные кавычки и подстановку переменных.
>>680934
написано: файла нужного нету
>>680936
названия переменных неудачные, можно было писать $w1 = $words1[array_rand...]
>>680945
Мне не нравится: нечитабельно. \n лучше читается.
>>680971
Вряд ли ты найдешь ровно то, что тебе нужно. Надо самому писать. Либо взять монструозную CMS вроде друпала и попробовать настроить это в нем, но это сложно.
Это в линукс есть такая концепция, everything is a file. Это дает преимущества вроде простого управления доступом к ресурсу и наличия большого числа готовых инструментов для работы с файлами (например в линуксе обычной командой копирования файла можно сделать образ жесткого диска), но имеет и недостатки (как миниумум в том что эти псевдофайлы надо создавать, также иногда они не полноценно имитируют реальные файлы).
В PHP пошли немного дальше и сделали потоки/streams - абстракцию над сокетами, файлами, архиваторами. Можешь почитать в мануале.
> Но они и правда вроде такие же как и с файлами.
Общее у них только то что в них можно писать/читать. Это позволяет например взять обычную программу, выводящую что-то на стандартный вывод и превратить ее в демона с помощью xinetd, который при подсоединении что-то полезное выводит в сокет.
fsockopen - древний вызов, там есть какие-то недостатки - например нельзя указывть опции дял сокета.
Зачем нужна Ява в PHP не знаю, ни разу не сталкивался.
> на пхп можно и флеш генерить.
Тут есть 2 подвоха: 1) флеш уже полумертвый 2) это библиотека не от адоби, значит гарантий полной совместимости и надежности нет
Ну и как я понимаю, там возможности очень ограничены, компилировать скрипты например она не умеет.
>>681041
Она старая и на такое не рассчитана. Не умеет работать с utf-8 урок: https://gist.github.com/codedokode/ff99e357e9860ea169b8
>>681070
Сомневаюсь. Приходилсь работать с многомегабайтными XML с его помощью.
>>681080
Надо изучить протокол HTTP. SQL запросы надо изучать отдельно, они тут вообще не при чем.
>>681104
Нужно уметь пользоваться линуксом и иметь права администратора.
> есть подробный манул, для таких, как я?
Я не умею водить машину и не знаю ПДД, но у меня стоит во дворе Запорожец, как мне доехать до соседнего города?
Это в линукс есть такая концепция, everything is a file. Это дает преимущества вроде простого управления доступом к ресурсу и наличия большого числа готовых инструментов для работы с файлами (например в линуксе обычной командой копирования файла можно сделать образ жесткого диска), но имеет и недостатки (как миниумум в том что эти псевдофайлы надо создавать, также иногда они не полноценно имитируют реальные файлы).
В PHP пошли немного дальше и сделали потоки/streams - абстракцию над сокетами, файлами, архиваторами. Можешь почитать в мануале.
> Но они и правда вроде такие же как и с файлами.
Общее у них только то что в них можно писать/читать. Это позволяет например взять обычную программу, выводящую что-то на стандартный вывод и превратить ее в демона с помощью xinetd, который при подсоединении что-то полезное выводит в сокет.
fsockopen - древний вызов, там есть какие-то недостатки - например нельзя указывть опции дял сокета.
Зачем нужна Ява в PHP не знаю, ни разу не сталкивался.
> на пхп можно и флеш генерить.
Тут есть 2 подвоха: 1) флеш уже полумертвый 2) это библиотека не от адоби, значит гарантий полной совместимости и надежности нет
Ну и как я понимаю, там возможности очень ограничены, компилировать скрипты например она не умеет.
>>681041
Она старая и на такое не рассчитана. Не умеет работать с utf-8 урок: https://gist.github.com/codedokode/ff99e357e9860ea169b8
>>681070
Сомневаюсь. Приходилсь работать с многомегабайтными XML с его помощью.
>>681080
Надо изучить протокол HTTP. SQL запросы надо изучать отдельно, они тут вообще не при чем.
>>681104
Нужно уметь пользоваться линуксом и иметь права администратора.
> есть подробный манул, для таких, как я?
Я не умею водить машину и не знаю ПДД, но у меня стоит во дворе Запорожец, как мне доехать до соседнего города?
> По ссылке пусто
>>680755
> Было бы неплохо тогда показать код, а то я его не вижу.
Ладно уж, залил на гитхаб. ОП, надеюсь мне не придется снова ждать неделю.
https://github.com/fxsloker/SocketDownloader
Как обновить таблице самой себя основываясь на данных самой себя?
всё разобрался. кому надо линкану.
http://ramzes.ws/blog/cant-specify-target-table-for-update-in-from-clause
Да.
khanacademy правда на английском.
Может тебе еще и залупу вареньицем помазать?
Ахуевший ты анон.
Будь благодарен, что оп вообще проверяет.
>$paymentTotal + $paymentTotal
А где переменная, которая будет содержать результат этого выражения?
Ты вообще пробовал решить задачу? Вроде бы несильно отличается от кода ОПа.
Я благодарен. Я могу и неделю подождать. Я просто НАДЕЮСЬ, ничего такого.
Не надо тут ругаться. Все проверим, как будет время. Пока придется немного подождать. Ну и в случае с сокетами - можно писать пока простого демона мемкеша.
Анон, давай, пиши уже мемкеш, хватит 3-4 команд, и давай переходит к асинхронщине, socket_select, а затем уже и reactPHP который очень даже понадобится для вебсокетов.
>if($creditBalance < 5000) проверяет
>$creditBalance + $creditBalance выплачивает
видимо не все так просто да?
Алгоритм такой:
1. Прибавляем к $creditBalance проценты и $servicePayment.
2. Если получившаяся переменная меньше $monthlyPayment, то выплачиваем именно её и прибавляем её к $paymentTotal. После этого завершаем цикл.
3. Если получившаяся переменная больше или равна $monthlyPayment, то отнимаем от неё $monthlyPayment, продолжаем цикл.
>>688752
Какой-то сумбур, не вполне тебя понимаю, что ты несёшь?, к чему вообще $creditBalance + $creditBalance тут может быть?
Ты точно сделал предыдущие задачки? Покажи-ка, а то такое ощущение, что ты не понял, что такое простые условия с if и else.
На этой задаче все спотыкаются, не беспокойся. Для начала ты можешь попрбовать решить ее поставив сумму кредита = 4000 (ответ должен быть 6123). А потом добиться чтобы работало с любой суммой
>Расшифровка - нас прздали. явка провалзна.
Ну а так нормально вроде. Тогда продолжай по алгоритму выше.
>>688770
И где твоё решение? Я что-то не видел, чтобы кто-то не споткнулся. Был один, который сделал с уходом в минус и упорствовал в своём решении, но это мелочь.
Получается, что последний месяц у тебя пропадает, так как стоит break.
Попробуй echo просто поставить в это условие.
что-то не то мне как-то нужно последний месяц сохранить
То есть echo не успевает вывестись, так как обрывается цикл.
А если поместить внутрь условия if($creditBalance< $monthlyPayment), то всё получается верно.
Так-то можно оптимизировать несколькими способами, чтобы таких повторов избежать.
>>688815
То же самое, какое и в самом цикле, но только в условие.
если я добавляю echo в условия if($creditBalance< $monthlyPayment)
то он просто выводит 1 раз
>13 месяц спустя: долг = 1270.1867445207 руб, выплачено всего 61270.186744521 руб.
Так и должно быть.
Сумма в итоге получается правильная.
Но $creditBalance должен быть равен нулю. То есть от $creditBalance надо отнять $monthlyPayment, ставшую равной $creditBalance. Неясно как-то вышло, наверное.
Задача в итоге решена правильно, но всё это можно оптимизировать, чтобы не повторялось echo два раза.
В последней строке у тебя всё правильно, кроме того, что долг = 1270.1867445207 руб. Ведь к этому моменту он должен быть равен 0, мы ведь всё выплатили.
Поэтому $creditBalance в последнем условии надо сделать равной 0. Можно грубо написать: $creditBalance = 0 (не советую и не рекомендую), а можно $monthlyPayment сделать равной $creditBalance, затем посчитать $paymentTotal, а уже потом из $creditBalance вычесть $monthlyPayment, чтобы получился 0.
Теперь яснее?
Просто сделай это.
Осталось ведь только добиться того, чтобы $creditBalance стал равен 0 в последнем условии.
В высшей степени необычно.
Если там хранится идентификатор пользователя, о чем говорит имя колонки 'userid', то почему varchar, а не int, и где внешний ключ на таблицу пользователей?
А там кстати в гайдах предлагают хранить даже не id, а почту или логин.
>foreign key (`itemname`) references `AuthItem` (`name`)
Тоже непривычно. Зачем такая избыточность, копировать одно и то же значение по двум таблицам, да еще и вешать по индексу на каждую текстовую колонку? Почему не завести колонку id в таблице AuthItem, и не ссылаться на нее?
Может они так пытаются избежать лишнего джойна, когда нужно будет в какой-нибудь админ-панели вывести инфу по правам пользователей?
Что-то у меня разрыв шаблона от этого юи, надо поскорее выучить все его косяки фичи и переходить к полноценному фреймворку.
Я решение еще в том году ОПу сдавал. Тут проблемы, только если человек вообще никогда никакого кода в глаза не видел, могут быть.
Да, всё верно. Теперь осталось оптимизировать.
Для этого попробуй другое условие поставить для работы цикла. Не 20 месяцев с потолка, а - пока сумма кредита больше нуля, например.
Тогда будет достаточно одного общего echo и цикл сам прекратит работу, когда $creditBalance станет равен 0.
ладно щас будем пробовать
Я могу ошибаться, но возможно тут расширяемая схема, то есть она в теории должна работать с любой таблицей пользователей. А в разных проектах id не обязательно INT, у кого-то BIGINT, в openId вообще пользователи иеднифицируются по email подобному идентификатору - может в этом дело?
> Почему не завести колонку id в таблице AuthItem, и не ссылаться на нее?
Например потому что name является хорошим естественный первичным ключом и везде используется. Вообще, не знаю, это надо код смотреть
Ты прав, я не подумал про смену таблицы пользователей, про openId вообще первый раз слышу.
То есть такой на первый взгляд неправильный код был сделан из определенных соображений, до которых я еще не дорос.
Только вот реализовано как-то неудачно, и в документации о таких моментах ни слова.
Вот оф.мануал по теме пользовательских прав
http://www.yiiframework.com/doc/guide/1.1/ru/topics.auth#sec-9
Тупо набор ссылок на апи (ссылки кстати неудачные, например если попытаться перейти к CAuthManager::assign, то перекидывает на интерфейс, ну и сам CAuthManager абстрактный, оказывается нужно смотреть наследников типа CDbAuthManager).
Еще какой-то вакуумный пример
> $auth->assign('reader','readerA');
Что еще за readerA? Это как раз userId, о котором мы говорим. А где он хранится? А черт его знает, я первоначально вообще подумал, что нужно создать enum-поле у модели (мне это кажется логичным, но может быть опять я недальновиден). Ан нет, нужно импортировать вот эти таблицы специально для системы ролей доступа, и сохранять через assign в таблицу AuthAssignement вида itemname/userid.
То есть если у меня миллион пользователей с правами редактора, то я должен занести в эту таблицу миллион записей?
Нет, там снова какой-то велосипед с дефолтными ролями. Нужно прописать в конфиге очередной многомерный массив, плюсъ занести в базу строкой кусок кода, который будет выполняться при проверке доступа.
$bizRule='return Yii::app()->user->isGuest;';
$auth->createRole('guest', 'гость', $bizRule);
Это вообще нормальная практика, сохранять куски php-кода в базе? Я не знаю, опыта у меня чуть больше нуля, но все это кажется очень странным.
Мне нужно всего-навсего, чтобы пользователь мог редактировать свои записи, но не мог чужие, и тут такие свистопляски.
У симфони случайно нет модуля для системы ролей, или что-то подобное? Хотя наверное там может и лучше организация, но еще сложнее для понимания.
Какая безысходность.
Надо понимать что они пытаются быть максимально абстрактными и разрешить любые виды пользователей и способы авторизации - не только через логин/пароль. Сами пользователи не обязаны хранится в БД, а могут например быть прописаны в коде или конфиге или в мемкеше (живут до первой перезагрузки). То есть кто-то может считать пользователем тех, кто загрегистрирован, а кто-то может считать каждый IP адрес уникальным пользователем.
Потому определение что такое пользователь, где их хранить и как опознавать вынесено из фреймворка в пользовательский код с помощью абстракции.
Ты это реализуешь через класс Identity и метод CUserIdentity::getId()
Аналогично абстрагируется хранение информации о правах и ролях пользователей - фреймворк не навязывает способ хранения.
Я не уверен что это все правильно сделано, ну например не очень понимаю почему так проверка логина/пароля сделана в классе Identity - я имею в виду, может это можно как-то делать снаружи, а класс Identity пусть просто представляет информацию о пользователе.
Далее, по поводу названия вместо id:
> http://www.yiiframework.com/doc/guide/1.1/ru/topics.auth#sec-7
> Элемент авторизации однозначно идентифицируется его уникальным именем.
Я думаю по этой причине id не используется.
> $auth->assign('reader','readerA');
Тут все просто: мануал говорит:
> http://www.yiiframework.com/doc/api/1.1/IAuthManager#assign-detail
> assign(string $itemName, mixed $userId, string $bizRule=NULL, mixed $data=NULL)
> Assigns an authorization item to a user.
дает пользователю элемент авторизации (роль, операцию или право сделать что-то)
Из мануала видно что в начале идет идентификатор элемента авторизации (роли или права), а затем id юзера.
> Что еще за readerA? Это как раз userId, о котором мы говорим. А где он хранится?
А какая разница? Задача менеджера авторизации - проверить имеет ли право пользователь X сделать операцию Y. Какое имеет значение, где хранится эта информация?
Там есть 2 встроенных менеджера: один хранит информацию о ролях в БД, другой - в памяти (то есть ее надо вбивать в него перед использованием).
> Ан нет, нужно импортировать вот эти таблицы специально для системы ролей доступа, и сохранять через assign в таблицу AuthAssignement вида itemname/userid.
Ну разумеется если ты хочешь использовать менеджер на основе БД, надо создать ему таблицы.
> То есть если у меня миллион пользователей с правами редактора, то я должен занести в эту таблицу миллион записей?
Да. Но ты не обязан использовать это менеджер. ты можешь написать свой менеджер который как-то по другому проверяет наличие роли.
> Нет, там снова какой-то велосипед с дефолтными ролями. Нужно прописать в конфиге очередной многомерный массив, плюсъ занести в базу строкой кусок кода, который будет выполняться при проверке доступа.
Хранить код в базе абсолютно глупая идея. Вэтомслучае лучше написать или унаследовать свой auth менеджер и написать код в нем.
Учись разбираться в абстракциях. Я думаю, было бы полезно разобраться во всем этом. НУ и подумай, а как бы ты сам решал аналогичную задачу: сделать расширяемую систему авторизации и проверки прав? Разумеется тут надо все разбивать на классы и абстрагировать.
> Это вообще нормальная практика, сохранять куски php-кода в базе?
Абсолютно ненормальная.
> Мне нужно всего-навсего, чтобы пользователь мог редактировать свои записи, но не мог чужие, и тут такие свистопляски.
Тогда ты мог бы не использовать RBAC, а попробовать использовать дефолтную более простую систему. RBAC это скорее для соложных систем, где например можно через админку давать и отбирать у редакторов разные роли. Ну например СМИ где есть журналисты (который пишет, но не может опубликовать новость), выпускающий редактор (которй публикует), иллюстратор (добавляет картинки) и у них у всех ограниченные права.
> У симфони случайно нет модуля для системы ролей, или что-то подобное?
Есть - еще сложнее и нагроможденнее.
Надо понимать что они пытаются быть максимально абстрактными и разрешить любые виды пользователей и способы авторизации - не только через логин/пароль. Сами пользователи не обязаны хранится в БД, а могут например быть прописаны в коде или конфиге или в мемкеше (живут до первой перезагрузки). То есть кто-то может считать пользователем тех, кто загрегистрирован, а кто-то может считать каждый IP адрес уникальным пользователем.
Потому определение что такое пользователь, где их хранить и как опознавать вынесено из фреймворка в пользовательский код с помощью абстракции.
Ты это реализуешь через класс Identity и метод CUserIdentity::getId()
Аналогично абстрагируется хранение информации о правах и ролях пользователей - фреймворк не навязывает способ хранения.
Я не уверен что это все правильно сделано, ну например не очень понимаю почему так проверка логина/пароля сделана в классе Identity - я имею в виду, может это можно как-то делать снаружи, а класс Identity пусть просто представляет информацию о пользователе.
Далее, по поводу названия вместо id:
> http://www.yiiframework.com/doc/guide/1.1/ru/topics.auth#sec-7
> Элемент авторизации однозначно идентифицируется его уникальным именем.
Я думаю по этой причине id не используется.
> $auth->assign('reader','readerA');
Тут все просто: мануал говорит:
> http://www.yiiframework.com/doc/api/1.1/IAuthManager#assign-detail
> assign(string $itemName, mixed $userId, string $bizRule=NULL, mixed $data=NULL)
> Assigns an authorization item to a user.
дает пользователю элемент авторизации (роль, операцию или право сделать что-то)
Из мануала видно что в начале идет идентификатор элемента авторизации (роли или права), а затем id юзера.
> Что еще за readerA? Это как раз userId, о котором мы говорим. А где он хранится?
А какая разница? Задача менеджера авторизации - проверить имеет ли право пользователь X сделать операцию Y. Какое имеет значение, где хранится эта информация?
Там есть 2 встроенных менеджера: один хранит информацию о ролях в БД, другой - в памяти (то есть ее надо вбивать в него перед использованием).
> Ан нет, нужно импортировать вот эти таблицы специально для системы ролей доступа, и сохранять через assign в таблицу AuthAssignement вида itemname/userid.
Ну разумеется если ты хочешь использовать менеджер на основе БД, надо создать ему таблицы.
> То есть если у меня миллион пользователей с правами редактора, то я должен занести в эту таблицу миллион записей?
Да. Но ты не обязан использовать это менеджер. ты можешь написать свой менеджер который как-то по другому проверяет наличие роли.
> Нет, там снова какой-то велосипед с дефолтными ролями. Нужно прописать в конфиге очередной многомерный массив, плюсъ занести в базу строкой кусок кода, который будет выполняться при проверке доступа.
Хранить код в базе абсолютно глупая идея. Вэтомслучае лучше написать или унаследовать свой auth менеджер и написать код в нем.
Учись разбираться в абстракциях. Я думаю, было бы полезно разобраться во всем этом. НУ и подумай, а как бы ты сам решал аналогичную задачу: сделать расширяемую систему авторизации и проверки прав? Разумеется тут надо все разбивать на классы и абстрагировать.
> Это вообще нормальная практика, сохранять куски php-кода в базе?
Абсолютно ненормальная.
> Мне нужно всего-навсего, чтобы пользователь мог редактировать свои записи, но не мог чужие, и тут такие свистопляски.
Тогда ты мог бы не использовать RBAC, а попробовать использовать дефолтную более простую систему. RBAC это скорее для соложных систем, где например можно через админку давать и отбирать у редакторов разные роли. Ну например СМИ где есть журналисты (который пишет, но не может опубликовать новость), выпускающий редактор (которй публикует), иллюстратор (добавляет картинки) и у них у всех ограниченные права.
> У симфони случайно нет модуля для системы ролей, или что-то подобное?
Есть - еще сложнее и нагроможденнее.
Какой-то бредовый вопрос, причем тут программирование? Двух пальце вполне достаточно, если ты не собираешься соревноваться с кем-то на скорость.
Печатай так, как тебе удобно?
Задействую все, кроме безымянных.
Хотя не, нихуя, тоже их задействую.
Насчет абстракции понял, да. Цель с которой это было сделано. Реализация не очень понятная.
> Элемент авторизации однозначно идентифицируется его уникальным именем.
Так это я в своем коде должен определить это уникальное имя, поэтому и пытаюсь разобраться, что туда нужно записывать.
Выше пример
http://www.yiiframework.com/doc/guide/1.1/ru/topics.auth#sec-2
>Перекрытие метода CUserIdentity::getId() для возврата _id. По умолчанию в качестве ID возвращается имя пользователя.
Непонятно, что подразумевается под "именем пользователя". Может у меня в модели нет свойства name? Кажется, имеется ввиду свойство username класса CUserIdentity
http://www.yiiframework.com/doc/api/1.1/CUserIdentity#name-detail
То есть это та штуковина, по которой производится вход в систему: логин (уникальное имя на сайте) или имейл.
Так вот, они же его как раз "перекрывают" в примере, то есть записывают вместо name именно id записи (модели user).
$this->_id=$record->id;
>Что еще за readerA? Это как раз userId, о котором мы говорим. А где он хранится?
>А какая разница?
Разница в том, что вместо строк 'readerA', 'editorB', 'authorC' из примера я должен прописать что-то свое, вот я и пытаюсь выяснить что именно и откудова это взять.
Если ОНО хранится в какой-то из таблиц базы, то нужно выяснить в какой, чтобы это оттудова извлечь.
Но судя по всему мы (я) дошли до понимания, что это какой-то мутный идентификатор/имя пользователя (на самом деле не ползователя-модели, а его Identity), которое сохраняется куда-то в сессию/куки и доступно через компонент пользователя Yii::app()->user->id. И по-барабану что там лежит, почта, логин или настоящий id.
>подумай, а как бы ты сам решал аналогичную задачу
Для того чтобы что-то самому писать и решать такие задачи наверное лучше сначала изучить готовые решения (на этом этапе и нахожусь), и не одно.
На данный момент я бы просто хранил в модели пользователя колонку enum(список ролей). Но конечно это не решение для фреймворка, который должен уметь подстроиться под приложения использующие разные способы хранения данных, разную систему авторизации и т.д.
>попробовать использовать дефолтную более простую систему
Не вижу такой. Там есть "фильтр доступа" accessControl, но он позволит максимум отличить гостя от авторизованного пользователя и (может быть) главного админа, и разрешает/запрещает им определенные экшены.
А мне нужно именно чтобы пользователь мог редактировать только свои записи.
Ну ладно, разберусь уже до конца. Хотя плохо понятна логика фреймворка, в документации нет объяснений. Это к сожалению подталкивает к быдлокоду, то есть тупо заучить что написано в мануале и копировать те строки.
Насчет абстракции понял, да. Цель с которой это было сделано. Реализация не очень понятная.
> Элемент авторизации однозначно идентифицируется его уникальным именем.
Так это я в своем коде должен определить это уникальное имя, поэтому и пытаюсь разобраться, что туда нужно записывать.
Выше пример
http://www.yiiframework.com/doc/guide/1.1/ru/topics.auth#sec-2
>Перекрытие метода CUserIdentity::getId() для возврата _id. По умолчанию в качестве ID возвращается имя пользователя.
Непонятно, что подразумевается под "именем пользователя". Может у меня в модели нет свойства name? Кажется, имеется ввиду свойство username класса CUserIdentity
http://www.yiiframework.com/doc/api/1.1/CUserIdentity#name-detail
То есть это та штуковина, по которой производится вход в систему: логин (уникальное имя на сайте) или имейл.
Так вот, они же его как раз "перекрывают" в примере, то есть записывают вместо name именно id записи (модели user).
$this->_id=$record->id;
>Что еще за readerA? Это как раз userId, о котором мы говорим. А где он хранится?
>А какая разница?
Разница в том, что вместо строк 'readerA', 'editorB', 'authorC' из примера я должен прописать что-то свое, вот я и пытаюсь выяснить что именно и откудова это взять.
Если ОНО хранится в какой-то из таблиц базы, то нужно выяснить в какой, чтобы это оттудова извлечь.
Но судя по всему мы (я) дошли до понимания, что это какой-то мутный идентификатор/имя пользователя (на самом деле не ползователя-модели, а его Identity), которое сохраняется куда-то в сессию/куки и доступно через компонент пользователя Yii::app()->user->id. И по-барабану что там лежит, почта, логин или настоящий id.
>подумай, а как бы ты сам решал аналогичную задачу
Для того чтобы что-то самому писать и решать такие задачи наверное лучше сначала изучить готовые решения (на этом этапе и нахожусь), и не одно.
На данный момент я бы просто хранил в модели пользователя колонку enum(список ролей). Но конечно это не решение для фреймворка, который должен уметь подстроиться под приложения использующие разные способы хранения данных, разную систему авторизации и т.д.
>попробовать использовать дефолтную более простую систему
Не вижу такой. Там есть "фильтр доступа" accessControl, но он позволит максимум отличить гостя от авторизованного пользователя и (может быть) главного админа, и разрешает/запрещает им определенные экшены.
А мне нужно именно чтобы пользователь мог редактировать только свои записи.
Ну ладно, разберусь уже до конца. Хотя плохо понятна логика фреймворка, в документации нет объяснений. Это к сожалению подталкивает к быдлокоду, то есть тупо заучить что написано в мануале и копировать те строки.
Если ты пишешь в день не больше десяти строчек, то тебе достаточно конечно.
Только вот зря ты себя программистом считаешь, зря.
Будто я не могу писать быстро без десятипальцевого метода. Заканчивай с проекциями.
Выигрыш в скорости от десятипальцевого метода будет не так существенен для кодинга, ибо ты будешь писать быстрее чем думаешь.
CUserIdentity::getId() должен вернуть уникальный идентификатор пользователя. Если у пользователей есть id - то его, если они как-то по другому идентифицируются - то этот идентификатор.
> > Элемент авторизации однозначно идентифицируется его уникальным именем.
> Так это я в своем коде должен определить это уникальное имя, поэтому и пытаюсь разобраться, что туда нужно записывать.
Название роли или операции, например adminiatrator, guest, viewPost, editPost, deletePost, это описано в мануале выше.
> То есть это та штуковина, по которой производится вход в систему: логин (уникальное имя на сайте) или имейл.
Это другое, это как отображать информацию о пользователе.
> то есть записывают вместо name именно id записи (модели user).
Почему бы и нет. Если это на сайте нигде не выводится.
> Разница в том, что вместо строк 'readerA', 'editorB', 'authorC' из примера я должен прописать что-то свое, вот я и пытаюсь выяснить что именно и откудова это взять.
Идентификатор пользователя, то есть Identity->getId() как я понял.
> Если ОНО хранится в какой-то из таблиц базы, то нужно выяснить в какой, чтобы это оттудова извлечь.
У тебя должен быть обьъект Identity и определено что является id пользователя.
> И по-барабану что там лежит, почта, логин или настоящий id.
Если пользователи в базе то надо использовать первичный ключ таблицы пользователей - перечитай определение первичного ключа.
> На данный момент я бы просто хранил в модели пользователя колонку enum(список ролей). Но конечно это не решение для фреймворка, который должен уметь подстроиться под приложения использующие разные способы хранения данных, разную систему авторизации и т.д.
Это не решение так как нельзя дать больше одной роли и нельзя хранить пользователей не в базе.
Ну представь например имиджборда где пользователь имеет право редактировать свой пост если его IP совпадает с постом, и имеет право модерировать посты если у него есть определенная кука с кодом. Там нет таблицы пользователей, а права и идентити есть.
> Не вижу такой. Там есть "фильтр доступа" accessControl, но он позволит максимум отличить гостя от авторизованного пользователя и (может быть) главного админа, и разрешает/запрещает им определенные экшены.
Ну и отлично. Добавь еще проверку в контроллере на авторство и все.
Ну или ты можешь сделать на основе RBAC написав свой authManager который проверяет является ли пользователь автором поста. Но мне это кажется преусложнением.
> Хотя плохо понятна логика фреймворка, в документации нет объяснений.
Ну не знаю, попробуй сам придумать именно абстрактную систему. Не привязанную к наличии базы данных или логина/пароля. Ты придешь к тому что у тебя будут сущности:
- идентити пользователя
- права, возможно иерархические (админ имеет все остальные нижележащие права)
- менеджер, проверяющий есть ли у пользователя данное право
CUserIdentity::getId() должен вернуть уникальный идентификатор пользователя. Если у пользователей есть id - то его, если они как-то по другому идентифицируются - то этот идентификатор.
> > Элемент авторизации однозначно идентифицируется его уникальным именем.
> Так это я в своем коде должен определить это уникальное имя, поэтому и пытаюсь разобраться, что туда нужно записывать.
Название роли или операции, например adminiatrator, guest, viewPost, editPost, deletePost, это описано в мануале выше.
> То есть это та штуковина, по которой производится вход в систему: логин (уникальное имя на сайте) или имейл.
Это другое, это как отображать информацию о пользователе.
> то есть записывают вместо name именно id записи (модели user).
Почему бы и нет. Если это на сайте нигде не выводится.
> Разница в том, что вместо строк 'readerA', 'editorB', 'authorC' из примера я должен прописать что-то свое, вот я и пытаюсь выяснить что именно и откудова это взять.
Идентификатор пользователя, то есть Identity->getId() как я понял.
> Если ОНО хранится в какой-то из таблиц базы, то нужно выяснить в какой, чтобы это оттудова извлечь.
У тебя должен быть обьъект Identity и определено что является id пользователя.
> И по-барабану что там лежит, почта, логин или настоящий id.
Если пользователи в базе то надо использовать первичный ключ таблицы пользователей - перечитай определение первичного ключа.
> На данный момент я бы просто хранил в модели пользователя колонку enum(список ролей). Но конечно это не решение для фреймворка, который должен уметь подстроиться под приложения использующие разные способы хранения данных, разную систему авторизации и т.д.
Это не решение так как нельзя дать больше одной роли и нельзя хранить пользователей не в базе.
Ну представь например имиджборда где пользователь имеет право редактировать свой пост если его IP совпадает с постом, и имеет право модерировать посты если у него есть определенная кука с кодом. Там нет таблицы пользователей, а права и идентити есть.
> Не вижу такой. Там есть "фильтр доступа" accessControl, но он позволит максимум отличить гостя от авторизованного пользователя и (может быть) главного админа, и разрешает/запрещает им определенные экшены.
Ну и отлично. Добавь еще проверку в контроллере на авторство и все.
Ну или ты можешь сделать на основе RBAC написав свой authManager который проверяет является ли пользователь автором поста. Но мне это кажется преусложнением.
> Хотя плохо понятна логика фреймворка, в документации нет объяснений.
Ну не знаю, попробуй сам придумать именно абстрактную систему. Не привязанную к наличии базы данных или логина/пароля. Ты придешь к тому что у тебя будут сущности:
- идентити пользователя
- права, возможно иерархические (админ имеет все остальные нижележащие права)
- менеджер, проверяющий есть ли у пользователя данное право
Для меня весь смысл 10ти пальцевого, что бы больше на клавиатуру никогда не смотреть (шея то не казенная). Если ты и так этого не делаешь, то думаю нафиг нужно. Хотя я могу и под столом набирать. С другой стороны, я переучился где то за 2 месяца, по 15-20 минут в день на оба языка ушло.
Я вообще нуб в програмировании(
Всмысле ты 15-20 минут в день набирал 10ти пальцевым, а в остальное время как обычно?
Читаешь содержимое файла в строку.
Разбиваешь строку на массив слов.
Проходишь по массиву, проверяя каждый элемент на количество символов и, если символов меньше четырех приплюсовываешь переменную счетчик.
Очень жаль.
Помочь сделать или сделать за тебя? Если второе готовь 100$ (или туза).
Если первое, гугли:
1. php содержимое файла в строку (file_get_contents)
2. php разбить строку на слова (preg_split)
3. циклы в php (foreach, for)
4. php длина строки (strlen, mb_strlen)
Нужно знать синтаксис регулярных выражений и php.
Ну регулярные выражения знать не обязательно, можно использовать explode с пробелом.
Знаки препинания? Табуляции, переносы строк?
Значит задач в твоем учебнике недостаточно. Надо поискать еще.
Что сука характерно, не ищутся.
Вбил "задачи на регулярные выражения php", выдает только примеры, базовый синтаксис и рецепты уровня "скопируйте этот код".
Нагуглил немножко
https://habrahabr.ru/post/167015/
http://www.zcontest.ru/2008.02/zrex.php
> Значит задач в твоем учебнике недостаточно
Но ведь в главе про регулярки изучается preg_match_all и есть задача на нее (граммар наци, сбор емайлов из текста).
Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 635) like iPhone OS 7_0_3 Mac OS X AppleWebKit/537 (KHTML, like Gecko) Mobile Safari/537
Юзер-агенты - это пример маразма, который сделали криворукие верстальщики, писавшие частные случаи под определенный браузер или слово в юзер-агенте. В итоге новые браузеры стремятся вписать как можно больше слов.
Разработчики Оперы в свое время даже вынуждены были патчить яваскриптом некоторые сайты.
> к сожалению в старых версиях PHP флаг i работает только с латинскими буквами
Насколько старых? Я так понимаю, речь о 5.2 и ниже (или даже четверка), так что можно не париться?
Зачем первые уроки сделаны картинкой? Я же цитировать не могу. Защита от копирайтеров? От гугла? Зато гитхаб яростно форсится и написан в другом стиле. Писались разными людьми? Скандалы, интриги, расследования...
Спасибо, исправлю.
Смело исплоьзуй флаг i. Это все не работало несколько лет назад, сейчас работает. Также при наличии флага u символ \\w корректно находит в том числе и русские буквы.
$regex = '/\S+ \d\d/';
if (preg_match_all ($regex, $file, $match))
foreach ($match[0] as $qqq) {
echo $qqq;
echo "<br>";
}
Это то, что вышло. Проблема в том, что выводит еще и в трехзначном числе двузначное.
Может семейный акаунт.
>>689134
Несколько лет это сколько?
Вдруг мне подсунут легаси-код, написанный 10 лет? Или на собеседовании спросят о различии версий php? (В вакансиях такое часто вижу)
Не могу понять фишку с огромным кол-вом слешей при экранировании.
Для бекслеша нужно прописать его четыре раза. В чем логика? Как php разбирает эту конструкцию?
С точкой почему-то достаточно одного слеша.
http://ideone.com/Racvzp
>Может семейный акаунт.
ОП потомственный учитель пхп? Его род передает учебник по пхп из поколения в поколение?
Ой, бля, не туда.
Нет, а все-таки почему для обозначения \ нужно его продублировать четыре раза?
Остальные символы типа \s вполне достаточно написать один раз
http://ideone.com/6QNQj7
Почему так, пока неясно.
Может это касается только двойных кавычек?
"\n" в двойных кавычках действительно даст перевод строки, но '\n' в одинарных это два символа, \ и n.
Хотя нет, выше я писал в одинарных '\\' и выдавало ошибку, типа заэкранировался ограничитель.
Ерунда какая-то.
Так и рождается говнокод, потому что нигде нет подробных объяснений, или они разбросаны в совершенно неупорядоченном виде.
Я например не знаю, где искать ответ на этот вопрос. Поэтому придется бездумно "визде удваивать слеши".
Безблагодатность.
Это зависит от:
- используешь ли ты utf-8 и флаг u или нет. Если нет - я тебе вообще ничего не могу гарантировать, может и не работать. Как миниумм будет зависит от локали и ОС.
- версии PCRE (не PHP). Увы, я не помню до какой версии это не работало. Возможно проблема была в том что я не использовал utf.
Вот люди обсуждают проблему: http://stackoverflow.com/questions/5458396/php-case-insensitive-preg-replace-of-a-cyrillic-string-in-utf8
Попробуй сделать
echo '\\n';
меняя число слешей и виды кавычек. echo показывает тебе какая строка получилась в итоге в памяти и как ее видит PHP.
Соответственно ты увидишь что при вводе
"\\\\"
php (и движок регулярок) увидит просто \\
Поэкспериментируй.
Также почитай http://php.net/manual/ru/language.types.string.php
Если есть вопросы - уточняй.
Логика примерно такая: в регулярках бекслеш это спецсимвол: http://php.net/manual/ru/regexp.reference.escape.php
Значит чтобы заматчить именно сам этот символ, его надо писать 2 раза (проверь на regex101 например)
Но чтобы записть строку \\ в PHP каждый бекслеш надо писать по 2 раза. Либо использовать nowdoc который не интерпретирует спецсимволы.
Не обоссывайте только, решил намазаться веб-кодингом, нашёл видеокурсы Евгения Попова по html и css, сейчас на завершающей главе html, делаю всё за ним, разумеется, пока получается, ибо тут только дурак не справится. Этот Попов вообще норм чел?
И по какому пути следовать при обучении:
1)HTML > CSS > JavaScript (+JQuery) > PHP+MySQL;
2)HTML > CSS > PHP+MySQL > JavaScript (+JQuery);
3)HTML > PHP+MySQL > CSS > JavaScript (+JQuery)?
Сейчас объясню, что мне хочется. Я просто сам по себе пока не получу первый мало-мальски годный результат, не смогу углубиться полностью в изучение. В каком порядке мне лучше изучать всё это, чтобы я как можно быстрее смог заработать первые доллары? Это не значит, что я сразу полезу везде орать, что я у мамы программист, просто после этого я буду уверен, что время трачу не зря и заработать ТОЧНО смогу и буду углублённо изучать каждый элемент.
В общем, в какой последовательности мне это учить для достижения быстрого результата? И в какой лучше с точки зрения рациональности и вашего опыта?
И да, по времени, если можно, проконсультируйте меня, сколько дней уйдёт на обучение по двум моим веткам (быстрой и рекомендованной).
Я просто учусь и подрабатываю немного, хотелось бы рассчитать, могу ли дропнуть работу, чтобы потратить всё время на обучение и уже начать зарабатывать на жрат.
Поповщина это самое дно.
Порядок не имеет значения, все равно придется учить одновременно.
В шапке все ссылки и мануалы.
По времени уйдет от 180 до 720 дней (ты бы еще в минутах спросил).
Но энтузиазм это хорошо, ты такой бодренький. Главное не настраивайся на "быстрый результат".
Если срочно нужны небольшие деньги, лучше wordpress + html/css + базовые знания php и jquery.
Ты же ОП? Если у меня всё получится, что я запланировал, я тебе с первого приличного заказа подарочек какой оформлю, даже не знаю, как ещё выразить благодарность. За то, что ты делаешь тут, берут большие деньги.
Я бы поспорил насчет опытных, толковых синьер-девелоперов у которых 5+ лет опыта сейчас везде не хватает, и наоборот компании тебе разные профиты будут предлагать чтобы ты к ним работать пошел.
А вот джуниором и правда сложно, особенно сейчас, когда кризис. На одну джуниорскую вакансию может быть от 15 откликов.
Чатик же! Все равно 1000 постов.
Что же вы дизморалите так? Я вот на апворк сегодня зашёл чисто для ознакомления, там был заказ на 200$, время на выполнение 3 недели. Что с ним не так? Я думал, взял заказ, посидел 2 недели над ним и всё готово, нет?
Вроде разобрался.
В одинарных кавычках \ выводится как есть. Но два подряд идущих \\ будут интерптретированы как один и echo выведет один символ.
Соответственно \\\n заменит два подряд идущих бекслеша на один, вместо 3 останется 2 (слава б-гу эта замена производится один раз, а не рекурсивно).
'\\\\n' выведет \\n, потому что произошло 2 замены \\ => \.
В двойных кавычках интерпретатор распознает больше спецсимволов, поэтому например \n будет заменен на перевод строки.
Только вот нигде (или я опять не нашел) не сказано о приоритете/порядке выполнения этой автозамены.
Например в выражении "\\n" я ожидал увидеть при выводе на печать как раз \ + перенос строки, то есть что сначала преобразуется перенос, на самом деле сначала заэкранируется бекслеш, и получится \n.
Полигончик http://ideone.com/uFWAN1
>>689181
Ок, с экранированием самого бекслеша (когда мы хотим при помощи регулярного выражения найти этот символ в строке) вроде ясно.
Но зачем это проделывать с другими символами? \s, \d и так далее? С одним слешом тоже работает.
http://ideone.com/E9VTNv
Я бы еще понял, если бы \s или \d воспринимались интерпретатором php как управляющие последовательности, но это же не так (судя по табличке из мануала http://php.net/manual/ru/language.types.string.php#language.types.string.syntax.double)
Вот перенос строки \n (или табуляция \t) в двойных кавычках нужно экранировать "\\n".
Зачем это делать с точкой, с \s, \d, \w и прочими спецсимволами, которые имеют значение в регулярных выражениях, но не имеют с точки зрения интерпретатора, это непонятно.
Скорее всего чисто ради одинакового стиля кода что ли. Чтобы не было, что в одном месте "\\n", во втором '\\\\', а в третьем '\s'.
Ну ок, тогда буду писать '\\s' ради стиля. Но технически вроде бы в этом нет необходимости.
p.s. Надеюсь фильтры вакабы в свою очередь не съедят все эти слеши, а то пост и так путаный.
p.p.s. Пили новый тред, у меня дико замирает браузер, когда за тысячу постов, а если кто-то постит в тот момент когда я пишу, обновляется секунд 5. Видимо мало памяти на нетбуке, а браузер держит все это говно вместе с картинками.
Вроде разобрался.
В одинарных кавычках \ выводится как есть. Но два подряд идущих \\ будут интерптретированы как один и echo выведет один символ.
Соответственно \\\n заменит два подряд идущих бекслеша на один, вместо 3 останется 2 (слава б-гу эта замена производится один раз, а не рекурсивно).
'\\\\n' выведет \\n, потому что произошло 2 замены \\ => \.
В двойных кавычках интерпретатор распознает больше спецсимволов, поэтому например \n будет заменен на перевод строки.
Только вот нигде (или я опять не нашел) не сказано о приоритете/порядке выполнения этой автозамены.
Например в выражении "\\n" я ожидал увидеть при выводе на печать как раз \ + перенос строки, то есть что сначала преобразуется перенос, на самом деле сначала заэкранируется бекслеш, и получится \n.
Полигончик http://ideone.com/uFWAN1
>>689181
Ок, с экранированием самого бекслеша (когда мы хотим при помощи регулярного выражения найти этот символ в строке) вроде ясно.
Но зачем это проделывать с другими символами? \s, \d и так далее? С одним слешом тоже работает.
http://ideone.com/E9VTNv
Я бы еще понял, если бы \s или \d воспринимались интерпретатором php как управляющие последовательности, но это же не так (судя по табличке из мануала http://php.net/manual/ru/language.types.string.php#language.types.string.syntax.double)
Вот перенос строки \n (или табуляция \t) в двойных кавычках нужно экранировать "\\n".
Зачем это делать с точкой, с \s, \d, \w и прочими спецсимволами, которые имеют значение в регулярных выражениях, но не имеют с точки зрения интерпретатора, это непонятно.
Скорее всего чисто ради одинакового стиля кода что ли. Чтобы не было, что в одном месте "\\n", во втором '\\\\', а в третьем '\s'.
Ну ок, тогда буду писать '\\s' ради стиля. Но технически вроде бы в этом нет необходимости.
p.s. Надеюсь фильтры вакабы в свою очередь не съедят все эти слеши, а то пост и так путаный.
p.p.s. Пили новый тред, у меня дико замирает браузер, когда за тысячу постов, а если кто-то постит в тот момент когда я пишу, обновляется секунд 5. Видимо мало памяти на нетбуке, а браузер держит все это говно вместе с картинками.
Индусы, индусы еверивеар.
Ты за 200 - а они за 150.
Ты за 100 - а они за 50.
Ты за отзыв - а они ещё доплатят.
Ты смешной какой-то. Везде есть конкуренция, просто нужно быть если не лучше чем большинство, то хотя бы конкурентноспособным. А то некоторые личности рассказывают какие они скилловые программисты, а на собеседовании выясняется что он даже строку нормально перевернуть не может. Потом еще и ныть начинают что алгоритмы в реальной работе не пригодятся, или что его специально завалили.
И по личному опыту скажу что работа на апворке это мягко говоря так себе. 5 часов ты апплаишься на все под ряд, 1 час работаешь.
>Напиши программу, получающую на вход автомобильный номер, и проверяющую, правильно ли он введен. Автомобильный номер имеет вид «а123вг», то есть начинается с буквы, за которой идет 3 цифры, и еще 2 буквы. Никаких посторонних символов быть в нем не должно.
Исхожу из того, что допускается только кириллица, и что буква е с умляутом допустимый символ в номере.
http://ideone.com/fgllxR
>>689305
strrev + iconv (для юникода)
Я принят?
Неплохо было бы основать, по какой причине возбраняется пользоваться тем или иным функционалом. Самодурство эйчара не рассматривается как веская причина.
В какой ситуации функция strrev недопустима?
Если без нее, то можно сплитить по пустой строке, делать реверс и склеивать.
Это если функции implode, array_reverse и preg_split разрешены (кем?)
> Только вот нигде (или я опять не нашел) не сказано о приоритете/порядке выполнения этой автозамены.
Логика такая: интерпретатор идет по строке слева направа. Обычные символы он воспринимает как есть, а если видит бекслеш, то берет его и следующий за ним символ и смотрит:
- если это экранирующая последовательность, то она воспринимается как 1 символ: \\ -> \ , \n -> символ перевода строки
- если такой последовательности нет, то в строку вставляются оба символа как есть: \y -> \y
Последовательность \\\n воспринимается как 2 пары: \\ кодирующий слеш и \n кодирующий симовл перевда строки
Все эти сложности нужны чтобы в строку можно было вставлять любые символы включая кавычки. Приходится придумывать спецсимвол который скажет нам что эта кавычка не закрывает строку, а является ее частью.
Это работает на уровне интерпретатора, один раз, когда он разбирает программу и преобразует ее в дерево AST, а затем в байт-код. То есть это все на уровне синтаксиса. Внутри строки хранятся как есть и \n хранится как байт с кодом 10, а не как 2 символа.
> Ок, с экранированием самого бекслеша (когда мы хотим при помощи регулярного выражения найти этот символ в строке) вроде ясно.
> Но зачем это проделывать с другими символами? \s, \d и так далее? С одним слешом тоже работает.
Я подумал что проще всегда экранировать бекслеш чем думать когда можно, а когда нельзя. И мне ведь надо это как-то объяснить начинающим.
Но сейчас я не уверен, правильно ли это. Ведь везде пишут один слеш, и по правлам регулярок там действительно один слеш идет. Идеальнее всего конечно если бы в PHP был синтаксис строк который не интерпретирует никакие символы, а передает как есть.
> Вот перенос строки \n (или табуляция \t) в двойных кавычках нужно экранировать "\\n".
Это не требуется. \n вставит в строку байт с кодом 10, и регулярки его тоже понимают. То есть \n и \\n дадут один результат.
> я ожидал увидеть при выводе на печать как раз \ + перенос строки, то есть что сначала преобразуется перенос, на самом деле сначала заэкранируется бекслеш, и получится \n.
Строки парсятся слева направо, по этой причине.
> Скорее всего чисто ради одинакового стиля кода что ли.
Да но как я написал, я вижу что так никто не делает и почти все пишут один бекслеш. Придется наверно переходить на этот вариант, выписав отдельно исключения: 4 бекслеша (вроде только с ними сложность).
> p.p.s. Пили новый тред, у меня дико замирает браузер, когда за тысячу постов, а если кто-то постит в тот момент когда я пишу, обновляется секунд 5.
Там течет память - что-то копится и не очищается. Перезагружай страницу полностью и память освободится. У меня тоже притормаживает иногда.
> strrev + iconv (для юникода)
тут есть проблема что в однобайтной колировке всего 255 символов и при конвертировании utf8 -> 1-байтная мы теряем символы. Нет, это потенциальная мина замедленного действия, долго потом придется искать почему функция дает неверные результаты. Ты должен стараться писать код без таких подвохов.
Разбить на массив символов и сделать array_reverse - допустимо (хотя тут тоже есть подвохи. Например в юникоде есть составные символы, например отдельно буква и отдельно черточка дял нее - при перевороте они поменяются местами и черточка будет относиться к другому символу. По хорошему тут нужна умная библиотека которая будет разбивать строку на символы с учетом составных символов, но так уж и быть, можно обойтись preg). Подробности про составные символы: https://ru.wikipedia.org/wiki/Юникод#.D0.9C.D0.BE.D0.B4.D0.B8.D1.84.D0.B8.D1.86.D0.B8.D1.80.D1.83.D1.8E.D1.89.D0.B8.D0.B5_.D1.81.D0.B8.D0.BC.D0.B2.D0.BE.D0.BB.D1.8B
Как видишь для правильной работы с юникодом нужна библиотека, умеющая все это делать. Есть библиотека ICU, в PHP вроде есть расширение Intl использующее ее.
>>689339
Риск потери символов при конвертации.
> В какой ситуации функция strrev недопустима?
В любой так как работает только с 1-байтными кодировками
> Если без нее, то можно сплитить по пустой строке, делать реверс и склеивать
Можно
Неа, не в однобайтную, наоборот из utf8 в utf16 (или 32) с другим направлением письма.
А потом таки обратно.
Взято отсюда, велосипед не мой (кто бы мог подумать).
http://bolknote.ru/2012/04/02/~3625#56
> public function __construct($argv) {
Это не относится к сокетам, но я бы передавал части отдельно а не массивом. Разбирать аргументы не задача этого класса. Ну и аргументы логичнее передавать в функцию скачивания а не в конструктор, чтобы можно было скачать несколько файлов.
>print("Connect to ".$ip.":".$this->port."\n");
Отладочную инфомацию лучше писать не на стандартынй вывод, а на стандартный поток ошибок -чтобы она не шла в файл если программа выводит полезные данные, а ты решишь перенаправить вывод программы в файл через
.... > file.txt
> Gecko/20100101 Firefox/44.0
Лучше подписывать названием и версией своей программы
> socket_close($socket);
Это логчинее писать внутри finally, при условии что соединение установилось.
> print(sprintf(
printf
http://php.net/manual/ru/function.socket-write.php
> Замечание:
> Совершенно нормально для функции socket_write() возвращать ноль, что означает, что ни одного байта не было записано. Пожалуйста, используйте оператор === для проверки значения на FALSE в случае ошибки.
Ты это учел? (нет, не учел). Прочитай мануал внимательно.
Функция может вернуть 0 например если она ждала возможности отправить пакет, а в этот момент пришел сигнал, прервавший системный вызов.
> while(($read = socket_read($socket, 1024)) && $read !== '0') {
Какие-то костыли. Почему бы просто не проверять результат через строгое сравнение === ? Явное лучше неявного.
Ну и давай уже сделай какой-нибудь сервер, надо увидеть что ты умеешь слушать порт и принимать соединения.
> public function __construct($argv) {
Это не относится к сокетам, но я бы передавал части отдельно а не массивом. Разбирать аргументы не задача этого класса. Ну и аргументы логичнее передавать в функцию скачивания а не в конструктор, чтобы можно было скачать несколько файлов.
>print("Connect to ".$ip.":".$this->port."\n");
Отладочную инфомацию лучше писать не на стандартынй вывод, а на стандартный поток ошибок -чтобы она не шла в файл если программа выводит полезные данные, а ты решишь перенаправить вывод программы в файл через
.... > file.txt
> Gecko/20100101 Firefox/44.0
Лучше подписывать названием и версией своей программы
> socket_close($socket);
Это логчинее писать внутри finally, при условии что соединение установилось.
> print(sprintf(
printf
http://php.net/manual/ru/function.socket-write.php
> Замечание:
> Совершенно нормально для функции socket_write() возвращать ноль, что означает, что ни одного байта не было записано. Пожалуйста, используйте оператор === для проверки значения на FALSE в случае ошибки.
Ты это учел? (нет, не учел). Прочитай мануал внимательно.
Функция может вернуть 0 например если она ждала возможности отправить пакет, а в этот момент пришел сигнал, прервавший системный вызов.
> while(($read = socket_read($socket, 1024)) && $read !== '0') {
Какие-то костыли. Почему бы просто не проверять результат через строгое сравнение === ? Явное лучше неявного.
Ну и давай уже сделай какой-нибудь сервер, надо увидеть что ты умеешь слушать порт и принимать соединения.
Тогда подойдет. Ну и видна проблема с тем что игнорируются комбинации символов - ウィ превратилась в бессмысленную キィ. Ну это уже конечно особенности языка.
http://ideone.com/eDqj6h
Уважаемый абу со своим надоедливым фильтром заставляет меня вспоминать цитаты из классических фильмов ("Кровь и бетон").
Вот какое из слов на скриншоте находится в "спам-листе", м?
Как будто на русском языке от написания справа налево получится осмысленный текст.
Так, а из функций iconv и mb_convert_encoding что предпочесть?
В гугле говорят как всегда много и бестолково, из того что я понял, вроде iconv обращается к сторонней (сишной?) библиотеке, то есть работа этой функции зависит от операционной системы. mb_convert_encoding входит в расширение для php, так что от системы не зависит, но выбор кодировок меньше (какой?).
Короче наверное лучше предпочитать mb_convert_encoding, типа большая портируемость, мы же в большинстве случаев не знаем где развернут наше приложение.
А на iconv в гугле жалуются, говорят "иногда не работает".
https://toster.ru/q/6285
От чего зависит "иногда" не пишут, говорят "просто" пользоваться mb_convert_encoding.
Экспертное мнение?
Усовершенствовал проверку номеров телефонов.
Теперь не допускает варианты типа
8---)))123456789
Все строго:
1. Сначала либо цифра 8, либо +7 (допускается проебл между плюсом и семеркой).
2. Затем пробел(может отсутствовать), дефис?, пробел?.
3. Открывающая круглая скобка (может отсутствовать).
4. Комбинация пробел+цифра, пробел необязателен. Комбинация повторяется либо 3 раза, либо 4.
5. Еще один пробел, может быть, может не быть. Просто не знал с кем его сгруппировать, поэтому пусть будет отдельный пункт.
6. Если в пункте 3 попалась открывающая круглая скобка, на этом месте обязана быть закрывающая. Иначе ничего.
7. Если в пункте 4 описанная комбинация встретилась 3 раза, то повторить фрагмент регулярного выражения (пробел?дефис?пробел?цифра) семь раз. Иначе повторить вышеупомянутый фрагмент 6 раз.
Регулярка получилась конечно длинная и нечитабельная, но таков уж синтаксис. Наверное все-таки удобнее было бы перенести часть логики в js или php.
http://ideone.com/WcY3pY
Условие задачи я не понял, особенно что они подразумевают под "ставками", что в данном случае называют "хешем", и в чем состоит запрос (к чему? к базе данных?).
Возможно ты просто вырвал из контекста.
А код конечно неправильный, на пике изображен массив, у которого ключом первого элемента является массив. Такого не может быть, ключом может быть только строка или целое число.
Скорее всего тебе предлагают найти ошибки в синтаксисе, в данном случае поменять местами стрелочки с запятыми.
Вот код, описывающий объект "Объявление". В этом контексте объявление - это важная новость с прикрепленным файлом (опционально), а также со сроком ее показа на сайте.
Укажите на ошибки, пожалуйста.
http://ideone.com/ri11JH
Я бегло пробежал, пока общие советы, потом оп доест.
1. Переходи с mysqli на pdo. Как минимум не будет этих чудовищных веток условий на каждом шагу с выбросом исключений. PDO выбрасывает исключения автоматически (если передать ему опцию при создании http://php.net/manual/ru/pdo.setattribute.php ).
О других преимуществах PDO https://habrahabr.ru/post/137664/
2. Изучи паттерны для работы с базой данных. Например DataMapper и ActiveRecord.
https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md
Паттерн это общепринятый подход. Мне например лень читать весь код, что ты там изобрел. Если код написан по паттерну, то я точно знаю, какие у класса методы, свойства, что они возвращают и т.д. Стандартизация экономит время и спасает от лишних ошибок.
3. В ООП непринято писать огромные полотна текста в методах, лучше много мелких функций (бывает даже одна строка, и в функции длиннее название чем ее тело, у тех же геттеров например).
4. Каждый класс и тем более метод должен заниматься своим делом. Например у тебя в конструкторе какая-то валидация.
if (trim(strip_tags($text)) === '') throw ...
Это нужно вынести как минимум в отдельный метод. А может быть написать отдельный класс для валидации.
Ну и так далее. Код не должен идти одной шизофазийной стеной.
>>689492
Не функционально, а процедурно наверно.
Вот что я вижу:
Когда ты проектируешь класс то первое что ты должен понять - что представляет собой объект этого класса? Какие его функции? Каждый класс должен заниматься своим делом (принцип единой ответственности, single responsibility), и у тебя этот принцип явно нарушен. Вот что делает твой класс:
- хранит информацию об одном объявлении
- валидирует его
- создает соединение с базой данных
- сохраняет его в БД
- форматирует даты
Это указывает что классы спроектированы неправильно. Ты просто написал процедурный код и дописал сверху слово class.
Далее, один из главных принципов которые должен свято чтить любой программист - не копипасть - у тебя не соблюдается. Легко можно найти скопированные куски кода, например
$mysqli = new mysqli(DATABASE_SERVER, DATABASE_USER, DATABASE_PASSWORD, DATABASE_NAME); (3 раза)
Да и не стоит хранить настройки в константах так как они доступны глобально, а нам это не нужно.
Погугли про принцип DRY.
Далее, ты каждый раз создаешь новое соединение к БД - это неэффективно, надо использовать одно и то же.
Далее, ты делаешь валидацию в конструкторе, то есть предполагаешь что не может быть неправильно заполненного объявления. Но это не так. При редактировании пользователь может ввести неправильные данные и их надо где-то хранить. Так что неправильно заполненное объявление может существовать, просто нельзя разрешать сохранять его в базу.
Да и при ошибке ты выкидываешь общее исключение, которое нельзя поймать (и вообще исопльзовать исключения для валидации не лучшая идея). Почитай про исключения: https://gist.github.com/codedokode/65d43ca5ac95c762bc1a
Расширение mysqli ты тоже не освоил и не умеешь им пользоваться, так как подставляешь данные прямо в запрос:
> ($result = $mysqli->query('SELECT ann_hidden FROM announcements WHERE ann_id = ' . $id)) ||
> $query = 'UPDATE announcements SET ann_text = "' . $mysqli->escape_string($this->text) . '", ann_file = "' . $mysqli->escape_string($this->attachedFile->getFilepath()) . '", ann_expdate = ' . $sqlExpdate . ' WHERE ann_id = ' . $this->id;
Запросы у тебя иногда еще и разбиты на куски. Какой нечитаемый кошмар. Почитай про плейсхолдеры.
Далее, каждый вызов query у тебя сопровождается ифом с проверкой результата. Не надоело копипастить? Надо как минимум вынести это в отдельный класс, который выполняет запросы и выкиыдвает исключение если надо. Ну или использовать PDO который умеет делать это автоматически.
В общем ты написал стену кода (putToDatabase) хотя можно было записать это в 10 строчек.
> public static function
использование статических функций указывает на ошибку проектирования. Ведь по идее должен быть обычный класс с нестатическими методами для этого. Работа с БД это сложный функционал и она никак не может быть в статическом методе.
Также можешь почитать эти уроки, по которым у нас учатся аноны:
- https://github.com/codedokode/pasta/blob/master/student-list.md
- https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md
- https://github.com/codedokode/pasta/blob/master/forms.md
- https://gist.github.com/codedokode/e1d31a31b37d5f635057
В общем код пока на двойку с минусом, надо все переписывать.
>>689492
Не функционально, а процедурно наверно.
Вот что я вижу:
Когда ты проектируешь класс то первое что ты должен понять - что представляет собой объект этого класса? Какие его функции? Каждый класс должен заниматься своим делом (принцип единой ответственности, single responsibility), и у тебя этот принцип явно нарушен. Вот что делает твой класс:
- хранит информацию об одном объявлении
- валидирует его
- создает соединение с базой данных
- сохраняет его в БД
- форматирует даты
Это указывает что классы спроектированы неправильно. Ты просто написал процедурный код и дописал сверху слово class.
Далее, один из главных принципов которые должен свято чтить любой программист - не копипасть - у тебя не соблюдается. Легко можно найти скопированные куски кода, например
$mysqli = new mysqli(DATABASE_SERVER, DATABASE_USER, DATABASE_PASSWORD, DATABASE_NAME); (3 раза)
Да и не стоит хранить настройки в константах так как они доступны глобально, а нам это не нужно.
Погугли про принцип DRY.
Далее, ты каждый раз создаешь новое соединение к БД - это неэффективно, надо использовать одно и то же.
Далее, ты делаешь валидацию в конструкторе, то есть предполагаешь что не может быть неправильно заполненного объявления. Но это не так. При редактировании пользователь может ввести неправильные данные и их надо где-то хранить. Так что неправильно заполненное объявление может существовать, просто нельзя разрешать сохранять его в базу.
Да и при ошибке ты выкидываешь общее исключение, которое нельзя поймать (и вообще исопльзовать исключения для валидации не лучшая идея). Почитай про исключения: https://gist.github.com/codedokode/65d43ca5ac95c762bc1a
Расширение mysqli ты тоже не освоил и не умеешь им пользоваться, так как подставляешь данные прямо в запрос:
> ($result = $mysqli->query('SELECT ann_hidden FROM announcements WHERE ann_id = ' . $id)) ||
> $query = 'UPDATE announcements SET ann_text = "' . $mysqli->escape_string($this->text) . '", ann_file = "' . $mysqli->escape_string($this->attachedFile->getFilepath()) . '", ann_expdate = ' . $sqlExpdate . ' WHERE ann_id = ' . $this->id;
Запросы у тебя иногда еще и разбиты на куски. Какой нечитаемый кошмар. Почитай про плейсхолдеры.
Далее, каждый вызов query у тебя сопровождается ифом с проверкой результата. Не надоело копипастить? Надо как минимум вынести это в отдельный класс, который выполняет запросы и выкиыдвает исключение если надо. Ну или использовать PDO который умеет делать это автоматически.
В общем ты написал стену кода (putToDatabase) хотя можно было записать это в 10 строчек.
> public static function
использование статических функций указывает на ошибку проектирования. Ведь по идее должен быть обычный класс с нестатическими методами для этого. Работа с БД это сложный функционал и она никак не может быть в статическом методе.
Также можешь почитать эти уроки, по которым у нас учатся аноны:
- https://github.com/codedokode/pasta/blob/master/student-list.md
- https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md
- https://github.com/codedokode/pasta/blob/master/forms.md
- https://gist.github.com/codedokode/e1d31a31b37d5f635057
В общем код пока на двойку с минусом, надо все переписывать.
>>681206
Ой, как нехорошо - твой код перемешан с кодом фреймворка и трудно понять где что. Кодеигнайтер нельзя подключить через композер? Судя по наличию composer.json - можно. Значит, надо подключить через него.
Да и обновлять фреймворк будет неудобно - вручную сравнивать папки и смотреть чтобы не затереть свои файлы.
Также желательно выносить публичную папку отдельно, а не сваливать весь код и файлы на всеобщее обозрение. Нужно делать отдельную публичную папку и класть в нее то, что не представляет секрета.
Сам фреймворк - то еще старье, достаточно посмотреть index.php:
> if (version_compare(PHP_VERSION, '5.3', '>='))
> {
> error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT & ~E_USER_NOTICE & ~E_USER_DEPRECATED);
Включается игнорирование многих видов ошибок, так как он просто не работает нормально на новом PHP. Ну и вообще это один большой набор антипаттернов.
В коде у тебя неправильные ссылки - на главной там прописан IP адрес. Получается я должен еще пройтись по всему коду и исправлять везде эти адреса? Это неправильно. В данном случае надо использовать относительные УРЛ: https://github.com/codedokode/pasta/blob/master/network/urls.md
Далее, в тесте у тебя клик по слову "Yes" или "No" не вызывает переключения. Это неправильно - надо делать эти надписи label который привязан к радиокнопке.
Ну и конечно можно было вопросы чуть поинтереснее заложить.
IP адреса выводятся неотформатированные, числом вроде IP address: 2135647064
При переходе на вторую страницу пагинация пропадает.
Странная структура базы данных - результаты тестов хранятся в табоице пользователей -получается пользователь может пройти тест только 1 раз в жизни? Или старые результаты теряются? Выглядит как ошибка в проектировании БД, мне кажется пользователь это одна сущность, резльтат теста - другая.
Для энумов обычно указывают идентификаторы без пробелов.
У таблиц почему-то кодировка latin1
> $this->load->view('main');
> $this->load->view('footer');
наверно логичнее чтобы main сам подключал шапку и футер.
https://github.com/toppestkek/CodelgniterTest/blob/master/application/controllers/Results.php#L20
https://github.com/toppestkek/CodelgniterTest/blob/master/application/controllers/Results.php#L43
тут 2 функции в контроллере Results скопированы друг с друга. Копипаста это зло. Подумай как это исправить.
https://github.com/toppestkek/CodelgniterTest/blob/master/application/controllers/Test.php
Тут странно сделана работа с формой, почитай урок про обработку форм https://github.com/codedokode/pasta/blob/master/forms.md
Обычно вывод и обработка формы делается в одном экшене, а после обработки делается редирект.
> $results == "one type" ? $data['message'] = "You have one type." :
В таких случаях надо писать иф. ?: для выражений, а не для замены ифа.
https://github.com/toppestkek/CodelgniterTest/blob/master/application/models/Answers_model.php#L18
МОдель не должна обращаться к ПОСТ данным и вообще что-то знать о параметрах HTTP запроса - явно ошибка в проектировании. Это делает контроллер. Ну например в твоем случае ты почему-то захардкодил работу с ПОСТ данными, хотя может мы захотим программно данные массивом или объектом передать.
https://github.com/toppestkek/CodelgniterTest/blob/master/application/models/User_model.php
Не могу понять за что отвечает класс. Вроде за работу с БД, но зачем тогда поля вроде winner? Надо определиться за что отвечает класс и что хранит объект этого класса. А пока тут намешана работа с базой и какая-то логика.
Также, модель не должна обращаться к SERVER.
https://github.com/toppestkek/CodelgniterTest/blob/master/application/models/User_model.php#L28
Тут ты подставляешь переменную в запрос, надо использовать плейсхолдеры.
> if($ipRow["INET_NTOA(ip)"
Надо использовать синонимы (алиасы) в запросе.
> "INSERT INTO users (type, ip, winner) VALUES ('$this->result', INET_ATON('$this->ip'), "
> . "$this->winner)
надо использовать плейсхолдеры
В общем, я бы сказал, что тут многое надо переделывать. Мало того, что сам фреймворк неудачный, так ты еще не совсем правильно реализовал классы моделей. Ну и сама задача очень простая конечно.
>>681206
Ой, как нехорошо - твой код перемешан с кодом фреймворка и трудно понять где что. Кодеигнайтер нельзя подключить через композер? Судя по наличию composer.json - можно. Значит, надо подключить через него.
Да и обновлять фреймворк будет неудобно - вручную сравнивать папки и смотреть чтобы не затереть свои файлы.
Также желательно выносить публичную папку отдельно, а не сваливать весь код и файлы на всеобщее обозрение. Нужно делать отдельную публичную папку и класть в нее то, что не представляет секрета.
Сам фреймворк - то еще старье, достаточно посмотреть index.php:
> if (version_compare(PHP_VERSION, '5.3', '>='))
> {
> error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT & ~E_USER_NOTICE & ~E_USER_DEPRECATED);
Включается игнорирование многих видов ошибок, так как он просто не работает нормально на новом PHP. Ну и вообще это один большой набор антипаттернов.
В коде у тебя неправильные ссылки - на главной там прописан IP адрес. Получается я должен еще пройтись по всему коду и исправлять везде эти адреса? Это неправильно. В данном случае надо использовать относительные УРЛ: https://github.com/codedokode/pasta/blob/master/network/urls.md
Далее, в тесте у тебя клик по слову "Yes" или "No" не вызывает переключения. Это неправильно - надо делать эти надписи label который привязан к радиокнопке.
Ну и конечно можно было вопросы чуть поинтереснее заложить.
IP адреса выводятся неотформатированные, числом вроде IP address: 2135647064
При переходе на вторую страницу пагинация пропадает.
Странная структура базы данных - результаты тестов хранятся в табоице пользователей -получается пользователь может пройти тест только 1 раз в жизни? Или старые результаты теряются? Выглядит как ошибка в проектировании БД, мне кажется пользователь это одна сущность, резльтат теста - другая.
Для энумов обычно указывают идентификаторы без пробелов.
У таблиц почему-то кодировка latin1
> $this->load->view('main');
> $this->load->view('footer');
наверно логичнее чтобы main сам подключал шапку и футер.
https://github.com/toppestkek/CodelgniterTest/blob/master/application/controllers/Results.php#L20
https://github.com/toppestkek/CodelgniterTest/blob/master/application/controllers/Results.php#L43
тут 2 функции в контроллере Results скопированы друг с друга. Копипаста это зло. Подумай как это исправить.
https://github.com/toppestkek/CodelgniterTest/blob/master/application/controllers/Test.php
Тут странно сделана работа с формой, почитай урок про обработку форм https://github.com/codedokode/pasta/blob/master/forms.md
Обычно вывод и обработка формы делается в одном экшене, а после обработки делается редирект.
> $results == "one type" ? $data['message'] = "You have one type." :
В таких случаях надо писать иф. ?: для выражений, а не для замены ифа.
https://github.com/toppestkek/CodelgniterTest/blob/master/application/models/Answers_model.php#L18
МОдель не должна обращаться к ПОСТ данным и вообще что-то знать о параметрах HTTP запроса - явно ошибка в проектировании. Это делает контроллер. Ну например в твоем случае ты почему-то захардкодил работу с ПОСТ данными, хотя может мы захотим программно данные массивом или объектом передать.
https://github.com/toppestkek/CodelgniterTest/blob/master/application/models/User_model.php
Не могу понять за что отвечает класс. Вроде за работу с БД, но зачем тогда поля вроде winner? Надо определиться за что отвечает класс и что хранит объект этого класса. А пока тут намешана работа с базой и какая-то логика.
Также, модель не должна обращаться к SERVER.
https://github.com/toppestkek/CodelgniterTest/blob/master/application/models/User_model.php#L28
Тут ты подставляешь переменную в запрос, надо использовать плейсхолдеры.
> if($ipRow["INET_NTOA(ip)"
Надо использовать синонимы (алиасы) в запросе.
> "INSERT INTO users (type, ip, winner) VALUES ('$this->result', INET_ATON('$this->ip'), "
> . "$this->winner)
надо использовать плейсхолдеры
В общем, я бы сказал, что тут многое надо переделывать. Мало того, что сам фреймворк неудачный, так ты еще не совсем правильно реализовал классы моделей. Ну и сама задача очень простая конечно.
>>682769
>>686208
>>688758
В ридми не написано что надо еще отредактировать htaccess. Я бы советовал вынести настройки виртуалхоста из htaccess (они все равно там не работают) в конфиг Апача.
https://github.com/greenTea242/Student-list/blob/master/studentlist.sql#L25
Для таблицы не задан первичный ключ. Погугли что такое первичный ключ, естественный, искуственный, и задай.
> `groupNumber` varchar(90)
По условиям задачи должно быть меньше - перепроверь.
> loco` tinyint(1) DEFAULT NULL,
Тут лучше энум сделать
> `abiturientID` varchar(50) NOT NULL
Тут стоит добавить комментарий что это такое (COMMENT "....")
https://github.com/greenTea242/Student-list/blob/master/autoload.php
тут не совсем правильно сделано - надо проверять есть ли такой файл перед подключением - перечтай урок про автозагрузку: https://github.com/codedokode/pasta/blob/master/php/autoload.md
> ViewHelper::fixView($_GET["notify"])
Объясни почему ты на входе делаешь htmlspecialchars? По моему ты не понимаешь что ты делаешь, а просто ставишь функции в надежде что одна из них тебя защитит. htmlspecialchars должна применяться только при выводе данных в HTML код так как она для этого предназначена.
> //Защита от вызова страниц page=Ы, page=-10
Проще сделать наверно через min/max. Или сделать функцию исправления числа страниц, которая проверит что она принимает разрешенные знаечния.
> Это я писал в треде, что с 20 записями и выше начинаются волшебные баги,
Нужно их повторить и выяснить причину. Ну например какое сообщение об ошибке выводится и тд
> require_once "../autoload.php";
> require_once "../src/config.php";
> require_once "../src/ini.php";
Мне кажется хватило бы одного реквайра.
> $validator = new AbiturientValidator($abiturient, $gateway);
Валидатор одноразовый? Может лучше сделать валидатор который можно вызывать много раз для разных студентов? Можно впрочем и так оставить.
> Пробегаемся по массиву чтобы обезапасить внешние данные
> $values = array_map(array('ViewHelper', 'fixView'), $values);
это неправильно. htmlspecialchars это не функция делающая данные безопасными.
> $gateway->updateAbiturient($values, $cookie);
Почему ты ислоьзуешь глупые массивы когда у тебя есть модель студента? Логичнее использовать ее же.
> $errorMessage[$key] = "Ошибка: {$error}";
> $inputBackgrClr[$key] = "control-group has-error";
Я думаю это лучше перенести в шаблон. Это явно часть представления.
> $values = [
> "name" => $_POST["name"],
> "surname" => $_POST["surname"],
Тут ты забыл сделать trim, также нет гарантий что в ПОСТ есть нужное значение и оно является строкой. Тут лучше сделать цикл по списку разрешенных полей, брать значение из ПОСТ, тримить и обновлять модель им.
> if ($cookie) {
> $values["abiturientID"] = $cookie;
Я думfю вообще не надо перезаписывать этот id при редактировании.
> if ($cookie) {
Ты думаешь что если есть куки - студент залогинен, но не факт: может быть кука, которая не соответствует ни одной записи в БД.
Файлы бутстрапа и свои файлы лучше не смешивать и хранить в разных папках. То есть проще всего распаковать бустрап в отдельную папку.
> if (!empty($notify) == "registred")
Кстати можно сделать нотификации константами
> <?php exit(); ?>
Это не должно быть в шаьлоне. Вдруг тебе после его вывода надо еще что-то сделать. Вообще, никакие функции не должны самовольно завршать скрипт (кроме может быть контроллера, и то не факт)
> https://github.com/greenTea242/Student-list/blob/master/src/ViewHelper.class.php#L27
> preg_replace("/$search/ui"
Нельзя просто так подставлять текст в регулярку так как там могут быть точки, зведочки и тд. Надо использовать preg_quote
> <span class='paintFound'>
Есть тег mark для этого
Также функция подсветки должна правильно делать htmlspecialchars, чтобы символы вроде & или < в HTML коде выводились корректно.
> class.php
Давно уже принято не писать слово class, почитай урок https://github.com/codedokode/pasta/blob/master/php/autoload.md
> public function addAbiturient(array $values)
Почему не модель а массив?
> $counter = $stmt->fetch();
> return (int)$counter[0];
Вроде есть функция которая сразу берет одно значение, fetchOne или fetchCol
> public function getAbiturientsInPage($page, $recordsPerPage
Универсальнее использовать не номер страницы а offset/limit
https://github.com/greenTea242/Student-list/blob/master/src/config.php
Тут лучше оставить только те настройки которые имеет смысл менять. Кодировку или тип БД нет смысла держать в конфиге.
https://github.com/greenTea242/Student-list/blob/master/src/ini.php#L8
> catch(PDOException $e) {
> echo $e->getMessage();
Ну вот, еще один человек не умеет ловить исключения. Паста:
---------
Как надо обрабатывать исключения:
- записать информацию в лог
- показать пользователю заглушку
- на заглушке выставить HTTP 503 код ответа для роботов
- на компьютере разработчика (при display_errors = 1) показать подробности и стектрейс
Что будет если использовать catch + echo:
- в лог ничего не фиксируется, ты не узнаешь об ошибках
- пользователь видит непонятную белиберду на английском
- отдается код 200
Как будет если просто не ловить исключение:
- информация пишется в лог (ок)
- на компьютере разработчика выводятся подробности (ок)
- пользователь видит белую страницу (не ок)
- отдается код 200 (не ок)
Почитай также урок https://gist.github.com/codedokode/65d43ca5ac95c762bc1a
>>682769
>>686208
>>688758
В ридми не написано что надо еще отредактировать htaccess. Я бы советовал вынести настройки виртуалхоста из htaccess (они все равно там не работают) в конфиг Апача.
https://github.com/greenTea242/Student-list/blob/master/studentlist.sql#L25
Для таблицы не задан первичный ключ. Погугли что такое первичный ключ, естественный, искуственный, и задай.
> `groupNumber` varchar(90)
По условиям задачи должно быть меньше - перепроверь.
> loco` tinyint(1) DEFAULT NULL,
Тут лучше энум сделать
> `abiturientID` varchar(50) NOT NULL
Тут стоит добавить комментарий что это такое (COMMENT "....")
https://github.com/greenTea242/Student-list/blob/master/autoload.php
тут не совсем правильно сделано - надо проверять есть ли такой файл перед подключением - перечтай урок про автозагрузку: https://github.com/codedokode/pasta/blob/master/php/autoload.md
> ViewHelper::fixView($_GET["notify"])
Объясни почему ты на входе делаешь htmlspecialchars? По моему ты не понимаешь что ты делаешь, а просто ставишь функции в надежде что одна из них тебя защитит. htmlspecialchars должна применяться только при выводе данных в HTML код так как она для этого предназначена.
> //Защита от вызова страниц page=Ы, page=-10
Проще сделать наверно через min/max. Или сделать функцию исправления числа страниц, которая проверит что она принимает разрешенные знаечния.
> Это я писал в треде, что с 20 записями и выше начинаются волшебные баги,
Нужно их повторить и выяснить причину. Ну например какое сообщение об ошибке выводится и тд
> require_once "../autoload.php";
> require_once "../src/config.php";
> require_once "../src/ini.php";
Мне кажется хватило бы одного реквайра.
> $validator = new AbiturientValidator($abiturient, $gateway);
Валидатор одноразовый? Может лучше сделать валидатор который можно вызывать много раз для разных студентов? Можно впрочем и так оставить.
> Пробегаемся по массиву чтобы обезапасить внешние данные
> $values = array_map(array('ViewHelper', 'fixView'), $values);
это неправильно. htmlspecialchars это не функция делающая данные безопасными.
> $gateway->updateAbiturient($values, $cookie);
Почему ты ислоьзуешь глупые массивы когда у тебя есть модель студента? Логичнее использовать ее же.
> $errorMessage[$key] = "Ошибка: {$error}";
> $inputBackgrClr[$key] = "control-group has-error";
Я думаю это лучше перенести в шаблон. Это явно часть представления.
> $values = [
> "name" => $_POST["name"],
> "surname" => $_POST["surname"],
Тут ты забыл сделать trim, также нет гарантий что в ПОСТ есть нужное значение и оно является строкой. Тут лучше сделать цикл по списку разрешенных полей, брать значение из ПОСТ, тримить и обновлять модель им.
> if ($cookie) {
> $values["abiturientID"] = $cookie;
Я думfю вообще не надо перезаписывать этот id при редактировании.
> if ($cookie) {
Ты думаешь что если есть куки - студент залогинен, но не факт: может быть кука, которая не соответствует ни одной записи в БД.
Файлы бутстрапа и свои файлы лучше не смешивать и хранить в разных папках. То есть проще всего распаковать бустрап в отдельную папку.
> if (!empty($notify) == "registred")
Кстати можно сделать нотификации константами
> <?php exit(); ?>
Это не должно быть в шаьлоне. Вдруг тебе после его вывода надо еще что-то сделать. Вообще, никакие функции не должны самовольно завршать скрипт (кроме может быть контроллера, и то не факт)
> https://github.com/greenTea242/Student-list/blob/master/src/ViewHelper.class.php#L27
> preg_replace("/$search/ui"
Нельзя просто так подставлять текст в регулярку так как там могут быть точки, зведочки и тд. Надо использовать preg_quote
> <span class='paintFound'>
Есть тег mark для этого
Также функция подсветки должна правильно делать htmlspecialchars, чтобы символы вроде & или < в HTML коде выводились корректно.
> class.php
Давно уже принято не писать слово class, почитай урок https://github.com/codedokode/pasta/blob/master/php/autoload.md
> public function addAbiturient(array $values)
Почему не модель а массив?
> $counter = $stmt->fetch();
> return (int)$counter[0];
Вроде есть функция которая сразу берет одно значение, fetchOne или fetchCol
> public function getAbiturientsInPage($page, $recordsPerPage
Универсальнее использовать не номер страницы а offset/limit
https://github.com/greenTea242/Student-list/blob/master/src/config.php
Тут лучше оставить только те настройки которые имеет смысл менять. Кодировку или тип БД нет смысла держать в конфиге.
https://github.com/greenTea242/Student-list/blob/master/src/ini.php#L8
> catch(PDOException $e) {
> echo $e->getMessage();
Ну вот, еще один человек не умеет ловить исключения. Паста:
---------
Как надо обрабатывать исключения:
- записать информацию в лог
- показать пользователю заглушку
- на заглушке выставить HTTP 503 код ответа для роботов
- на компьютере разработчика (при display_errors = 1) показать подробности и стектрейс
Что будет если использовать catch + echo:
- в лог ничего не фиксируется, ты не узнаешь об ошибках
- пользователь видит непонятную белиберду на английском
- отдается код 200
Как будет если просто не ловить исключение:
- информация пишется в лог (ок)
- на компьютере разработчика выводятся подробности (ок)
- пользователь видит белую страницу (не ок)
- отдается код 200 (не ок)
Почитай также урок https://gist.github.com/codedokode/65d43ca5ac95c762bc1a
Нужно попытаться понять логику (что с чем выровнено) и сверстать правильно.
> Да и вообще непонятно как правильно спозиционировать тот же логотип.
Надо смотреть логически: от каких элементов зависит его расположение? Как он влияет на другие элементы? И исходя из этого выбирать: АП, флоат или что-то еще.
Ну тут например можно закрепить логотип в шапке с помощью АП, а чтобы никто под него не залез, использовать паддинг слева на шапке. Либо просто зафлоатить влево.
> margin-top:50 - $logo-font-size; в SASS?
Выглядит как переусложнение по моему. Если ты не планируешь играть с высотой шрифта, то можно просто прописать маргин.
>>681378
Копипастить неправильно. Если у тебя есть похожие куски кода, надо выносить их в функции или может применять классы и наследование, если ты силен в ООП.
Погугли принцип DRY.
Надо писать новый код, а не переделывать по 10 раз старый.
>>681229
Да совсем не чистенько.
>>681397
> в деструкторе объекта у меня иногда вылетает PHP Warning: mysqli::close(): Couldn't fetch mysqli in blabla.php on line 124
> Собственно, причина ясна - иногда я закрываю соединение еще до уничтожения объекта.
Возможно дело не в этом. Возможно ты не забрал рещультаты запроса, или пытаештся использовать закрытое соединение или что-то еще. Надо разбираться.
Таймаут у mysql по умолчанию около полчаса так что вряд ли оно протухает.
Нужно попытаться понять логику (что с чем выровнено) и сверстать правильно.
> Да и вообще непонятно как правильно спозиционировать тот же логотип.
Надо смотреть логически: от каких элементов зависит его расположение? Как он влияет на другие элементы? И исходя из этого выбирать: АП, флоат или что-то еще.
Ну тут например можно закрепить логотип в шапке с помощью АП, а чтобы никто под него не залез, использовать паддинг слева на шапке. Либо просто зафлоатить влево.
> margin-top:50 - $logo-font-size; в SASS?
Выглядит как переусложнение по моему. Если ты не планируешь играть с высотой шрифта, то можно просто прописать маргин.
>>681378
Копипастить неправильно. Если у тебя есть похожие куски кода, надо выносить их в функции или может применять классы и наследование, если ты силен в ООП.
Погугли принцип DRY.
Надо писать новый код, а не переделывать по 10 раз старый.
>>681229
Да совсем не чистенько.
>>681397
> в деструкторе объекта у меня иногда вылетает PHP Warning: mysqli::close(): Couldn't fetch mysqli in blabla.php on line 124
> Собственно, причина ясна - иногда я закрываю соединение еще до уничтожения объекта.
Возможно дело не в этом. Возможно ты не забрал рещультаты запроса, или пытаештся использовать закрытое соединение или что-то еще. Надо разбираться.
Таймаут у mysql по умолчанию около полчаса так что вряд ли оно протухает.
Там много рассказывать, попробуй все же погуглить.
>>681408
надо не копипастить а писать новый код.
>>681603
Выражения для точки и запятой можно объединить в одно.
Не стоит делать 4 переменных text1 .. 4, лучше использовать одну и ту же.
Пробельный символ (пробел или перевод строки) можно обозначить как \\s
> $text4 = str_replace($sentence, $firstLetterUpper, $text4);
Странный код, зачем заменять все предложение на первую букву?
> mb_substr($sentence, 1, mb_strlen($sentence));
Третий аргумент писать не требутся
>>681612
Прочитай в мануале по preg_replace про конструкции вроде $1 в строке для замены.
>>681707
В каких фреймворках? В Симфони кемелкейс например. Древние типа кодеигнайтера лучше вообще не рассматривать - там полно антипаттернов.
Там много рассказывать, попробуй все же погуглить.
>>681408
надо не копипастить а писать новый код.
>>681603
Выражения для точки и запятой можно объединить в одно.
Не стоит делать 4 переменных text1 .. 4, лучше использовать одну и ту же.
Пробельный символ (пробел или перевод строки) можно обозначить как \\s
> $text4 = str_replace($sentence, $firstLetterUpper, $text4);
Странный код, зачем заменять все предложение на первую букву?
> mb_substr($sentence, 1, mb_strlen($sentence));
Третий аргумент писать не требутся
>>681612
Прочитай в мануале по preg_replace про конструкции вроде $1 в строке для замены.
>>681707
В каких фреймворках? В Симфони кемелкейс например. Древние типа кодеигнайтера лучше вообще не рассматривать - там полно антипаттернов.
Там вообще статья не про PHP. У нас есть PSR.
>>681726
Смешивать стили это еще хуже. Надо использовать один и тот же.
>>681764
не использовал
>>682084
> 3. Да, похоже что в статик функциях такое не получится реализоваться, ну и ладно, я считаю, что удобней будет каждый раз в методе писать соединение, чем каждый раз когда хочешь обратиться к бд создавать обьект.
Объект создается один раз в самом начале работы скрипта. То что ты предлагаешь это копипаста, и она недопустима. Плюс есть паста про DI - в твоем варианте код получается слишком спутанным: https://gist.github.com/codedokode/e1d31a31b37d5f635057
> я так и не понял зачем нужен обьект,
Объект позволяет что-то хранить или делать в пределах своей зоны ответсвенности.
Статические функции не годятся так как с ними ты не можешь сделать 2 объекта с разными настрйками (например работающие с разными БД). Ну и вообще, объекты более надежно изолируют данные. Вот сравни:
class A
{
public $a;
public static $b;
}
В случае обычного поля я могу создать объект и записать что-то в это поле никак не влияя на остальную программу. Я удалю объект и все, никаких следов не осталось. То есть я могу что-то делать изолированно. Со статическим полем любое его изменение влияет на всю остальную программу. Получается более плохой код с большим числом побочных эффектов.
>>682119
>>682125
Что-то не открывается сайт
Там вообще статья не про PHP. У нас есть PSR.
>>681726
Смешивать стили это еще хуже. Надо использовать один и тот же.
>>681764
не использовал
>>682084
> 3. Да, похоже что в статик функциях такое не получится реализоваться, ну и ладно, я считаю, что удобней будет каждый раз в методе писать соединение, чем каждый раз когда хочешь обратиться к бд создавать обьект.
Объект создается один раз в самом начале работы скрипта. То что ты предлагаешь это копипаста, и она недопустима. Плюс есть паста про DI - в твоем варианте код получается слишком спутанным: https://gist.github.com/codedokode/e1d31a31b37d5f635057
> я так и не понял зачем нужен обьект,
Объект позволяет что-то хранить или делать в пределах своей зоны ответсвенности.
Статические функции не годятся так как с ними ты не можешь сделать 2 объекта с разными настрйками (например работающие с разными БД). Ну и вообще, объекты более надежно изолируют данные. Вот сравни:
class A
{
public $a;
public static $b;
}
В случае обычного поля я могу создать объект и записать что-то в это поле никак не влияя на остальную программу. Я удалю объект и все, никаких следов не осталось. То есть я могу что-то делать изолированно. Со статическим полем любое его изменение влияет на всю остальную программу. Получается более плохой код с большим числом побочных эффектов.
>>682119
>>682125
Что-то не открывается сайт
До ангулара надо много других вещей изучить.
>>682292
Сфинкс ищет не по частям строк, а по целым словам. Условно говоря у него есть индекс вида:
...
абажур => id документов где оно встречается
авария => id документов где оно встречается
...
И он по нему ищет с большой скоростью (фактически надо найти все слова из запроса и сделать перечечение списка id, после чего остается только отсортровать их по релевантности).
Если индекс сделан на основе двоичного дерева (то есть слова в нем отсортированы по алфавиту), это позволяет искать не по полному слову, а по префиксу, то есть по первым буквам, но не по середине или концу. Но это чуть-чуть медленнее так как в этом случае мы найдем не одно слово, а несколько, и соответствуенно будет больше результатов.
Для поиска по середине или концу слова есть префиксные/суффиксные индексы. Они более тяжелые. Фактически при их испоьзовании сфинкс делает из слова нарезку и каждый кусок слова сохраняет как отдельное слово, например "машиностроение" добавляет в индекс слова:
машиностроение
ашиностроение
шиностроение
иностроение
...
ние
Обычно задается минимальная длина слова для поиска так как поиск по 1-2 буквам дает огромное число результатов и раздувает индекс. Ну и тот факт что вместо одного слова вставились 10 слов тоже его раздувает.
В общем, полезно представлять как устроены индексы.
В случае с именами файлов можно еще поиграться с правилами разбиения на слова - например по символу подчеркивания, дефису и тд.
> Если с этой опцией задать min_word_len = 1 и min_prefix_len = 1
Ты бессмысленно забиваешь индекс. Одна буква встречается почти в каждом названии и это забивает индекс не давая никакой выгоды.
Я не очень уверен, есть ли смысл в твоем случае делать поиск по бессмысленным именам. Ну как минимум поставь длину префикса не менее 3-4 символов.
>>682674
Можно попроовать, но придется разбираться в настройках хостинга. Домен не обязателен, там дадут технический поддомен.
До ангулара надо много других вещей изучить.
>>682292
Сфинкс ищет не по частям строк, а по целым словам. Условно говоря у него есть индекс вида:
...
абажур => id документов где оно встречается
авария => id документов где оно встречается
...
И он по нему ищет с большой скоростью (фактически надо найти все слова из запроса и сделать перечечение списка id, после чего остается только отсортровать их по релевантности).
Если индекс сделан на основе двоичного дерева (то есть слова в нем отсортированы по алфавиту), это позволяет искать не по полному слову, а по префиксу, то есть по первым буквам, но не по середине или концу. Но это чуть-чуть медленнее так как в этом случае мы найдем не одно слово, а несколько, и соответствуенно будет больше результатов.
Для поиска по середине или концу слова есть префиксные/суффиксные индексы. Они более тяжелые. Фактически при их испоьзовании сфинкс делает из слова нарезку и каждый кусок слова сохраняет как отдельное слово, например "машиностроение" добавляет в индекс слова:
машиностроение
ашиностроение
шиностроение
иностроение
...
ние
Обычно задается минимальная длина слова для поиска так как поиск по 1-2 буквам дает огромное число результатов и раздувает индекс. Ну и тот факт что вместо одного слова вставились 10 слов тоже его раздувает.
В общем, полезно представлять как устроены индексы.
В случае с именами файлов можно еще поиграться с правилами разбиения на слова - например по символу подчеркивания, дефису и тд.
> Если с этой опцией задать min_word_len = 1 и min_prefix_len = 1
Ты бессмысленно забиваешь индекс. Одна буква встречается почти в каждом названии и это забивает индекс не давая никакой выгоды.
Я не очень уверен, есть ли смысл в твоем случае делать поиск по бессмысленным именам. Ну как минимум поставь длину префикса не менее 3-4 символов.
>>682674
Можно попроовать, но придется разбираться в настройках хостинга. Домен не обязателен, там дадут технический поддомен.
global использовать нельзя. Надо правильно проктировать функции.
Длинные выражения из тернарников не годятся, их плохо читать. Логика вида "если так, то ... иначе " гораздо лучше читается. У нас нет цели соревноваться кто больше операций засунет в одну строку - нам важна читаьельност и поддерживаемость. Ну вот попробуй в свой тернарник в середину какой-нибудь еще действие вроде вызова функции или цикла добавить.
Что касается массивов с написанием чисел, я не вижу смысла делать там кучу массивов, можно сделать один большой массив и функцию которая его возвращает.
> if($thou==1)$valueArr = $thouArr;
Нужно писать в 3 строки со скобками.
> if($num==000)
000 то же самое что 0 . Это же число.
> function inclineNotNum($num, $mill, $thou, $ruble){
Очень странная функция. Почему она принимает на вход 4 числа и выдает на выходе одно значение? Я не понимаю логики. Лучше сделать так:
incline(45, '%d кот', '%d кота', '%d котов') -> 45 котов
> // При помощи одноразового цикла декларируем функцию, которая возвращает
> // склонения слов.
Если тебе нужна функция то объяви ее нормально. Какой смысл в том что ты там нагородил условий для создания функици если можно просто объявить ее на верхнем уровне. Ты:
- сделал функцию менее заметной
- добавил лишний бесполезный код который не нужен если функцию объявить на верхнем уровне
Какой в этом смысл? Зачем нужен однразовый цикл? Ты по моему не понимаешь концепцию, цикл придуман для повторяющихся действий. Одноразовый цикл пишется так: if.
> $extArr, $intArr
Что значат эти названия?
> $oneNumArr = str_split($num);
С числами надо работать математическими методами.
В общем убери все эти странности, и тогда посмотрим дальше. Сразу скажу что у большинства переменных плохие названия, название должно говорить что хранится в переменной, а не то что это массив.
>>PHP Notice: что-то там offset на произвольной строчке
> Ебался много дней над этим, но, к сожалению, не пришел к какому-либо определенному ответу.
Значит код плохой и нечитаемый раз в нем нельзя найти ошибку. Надо сделать рефакторинг и сделать его простым и понятным.
global использовать нельзя. Надо правильно проктировать функции.
Длинные выражения из тернарников не годятся, их плохо читать. Логика вида "если так, то ... иначе " гораздо лучше читается. У нас нет цели соревноваться кто больше операций засунет в одну строку - нам важна читаьельност и поддерживаемость. Ну вот попробуй в свой тернарник в середину какой-нибудь еще действие вроде вызова функции или цикла добавить.
Что касается массивов с написанием чисел, я не вижу смысла делать там кучу массивов, можно сделать один большой массив и функцию которая его возвращает.
> if($thou==1)$valueArr = $thouArr;
Нужно писать в 3 строки со скобками.
> if($num==000)
000 то же самое что 0 . Это же число.
> function inclineNotNum($num, $mill, $thou, $ruble){
Очень странная функция. Почему она принимает на вход 4 числа и выдает на выходе одно значение? Я не понимаю логики. Лучше сделать так:
incline(45, '%d кот', '%d кота', '%d котов') -> 45 котов
> // При помощи одноразового цикла декларируем функцию, которая возвращает
> // склонения слов.
Если тебе нужна функция то объяви ее нормально. Какой смысл в том что ты там нагородил условий для создания функици если можно просто объявить ее на верхнем уровне. Ты:
- сделал функцию менее заметной
- добавил лишний бесполезный код который не нужен если функцию объявить на верхнем уровне
Какой в этом смысл? Зачем нужен однразовый цикл? Ты по моему не понимаешь концепцию, цикл придуман для повторяющихся действий. Одноразовый цикл пишется так: if.
> $extArr, $intArr
Что значат эти названия?
> $oneNumArr = str_split($num);
С числами надо работать математическими методами.
В общем убери все эти странности, и тогда посмотрим дальше. Сразу скажу что у большинства переменных плохие названия, название должно говорить что хранится в переменной, а не то что это массив.
>>PHP Notice: что-то там offset на произвольной строчке
> Ебался много дней над этим, но, к сожалению, не пришел к какому-либо определенному ответу.
Значит код плохой и нечитаемый раз в нем нельзя найти ошибку. Надо сделать рефакторинг и сделать его простым и понятным.
О, хорошо, теперь я вижу что есть варианты из которых можно выбирать.
> Class Table Inheritance
По моему выглядит переусложненно
> Concrete Table Inheritance
> Для каждого класса информацию хранить в отдельной таблице, вместе с общими свойствами, в отличие от class table inheritance.
ну тут тоже не все так просто. Например неудобно выбирать все лайки которые поставил пользователь (надо делать юнионы).
Давай заменим лайки на иерархические комментарии, которые можно ставить пользователям, постам и фото. Тогда получается в случае ConTI мы делаем 3 почти одинаковых таблицы.
> Нельзя выбрать все лайки для разных классов (одновременно для комментариев, фото, пользователей) без юнионов. Хотя не представляю, в какой ситуации это может понадобиться.
Страница "мои лайки" или "Васины лайки"
> Хотя я не знаю в цифрах, как влияют на производительность джойны, и как влияет большое кол-во пустых полей.
Так сказать трудно. Надо смотретьконкретную ситуацию. Думаю, что лишние маленькие поля не особо влияют. И джойны наверно тоже.
>>682974
Жаднй алгооитм годится дял простой версии, но ты ведь не хочешь на ней остановиться?
>>683051
Да, ошибки это плохо.
>>683088
Ты провалил психологический тест на программиста
О, хорошо, теперь я вижу что есть варианты из которых можно выбирать.
> Class Table Inheritance
По моему выглядит переусложненно
> Concrete Table Inheritance
> Для каждого класса информацию хранить в отдельной таблице, вместе с общими свойствами, в отличие от class table inheritance.
ну тут тоже не все так просто. Например неудобно выбирать все лайки которые поставил пользователь (надо делать юнионы).
Давай заменим лайки на иерархические комментарии, которые можно ставить пользователям, постам и фото. Тогда получается в случае ConTI мы делаем 3 почти одинаковых таблицы.
> Нельзя выбрать все лайки для разных классов (одновременно для комментариев, фото, пользователей) без юнионов. Хотя не представляю, в какой ситуации это может понадобиться.
Страница "мои лайки" или "Васины лайки"
> Хотя я не знаю в цифрах, как влияют на производительность джойны, и как влияет большое кол-во пустых полей.
Так сказать трудно. Надо смотретьконкретную ситуацию. Думаю, что лишние маленькие поля не особо влияют. И джойны наверно тоже.
>>682974
Жаднй алгооитм годится дял простой версии, но ты ведь не хочешь на ней остановиться?
>>683051
Да, ошибки это плохо.
>>683088
Ты провалил психологический тест на программиста
Программируя CMS ты вряд ли многого добьешься - это низкоквалифицированная работа.
>>683160
Значит надо было начать с книги попроще.
>>683211
Суть в том что берешь по максимуму самых крупных купюр. потому и жадный.
>>681863
Я не знаю. Смотри сайты с вакансиями.
>>683338
Установи PHP на апач, настрой виртуалхосты и запускай код там. В ОП посте есть инструкции.
>>683588
Ну и ужасный код. массивы на массиве. Зачем ты делаешь 5 однотиных переменных когда можно сделать еще один массив? Если тебе надо найти минимальные значения, просто отсортируй записи.
Это монго дб? А в SQL кстати минимальные значения находятся простым запросом. за это я люблю SQL и не люблю монгу.
>>683886
Ты неправильный запрос пишешь. Ты не можешь переключиться. Ты должен установить модуль который связывает апач и php, забыл как он называется, в ОП посте было что-то на эту тему, посомтри.
> Это проблема точно в пхпшторме, я запускал php скрипт с пхпифно из htdocs в папке апача и там server api был apache 2 handler.
Ну так и запускай из-под апача, зачем тебе пхпшторм. Ну или попробуй там с настройками похимичить.
Программируя CMS ты вряд ли многого добьешься - это низкоквалифицированная работа.
>>683160
Значит надо было начать с книги попроще.
>>683211
Суть в том что берешь по максимуму самых крупных купюр. потому и жадный.
>>681863
Я не знаю. Смотри сайты с вакансиями.
>>683338
Установи PHP на апач, настрой виртуалхосты и запускай код там. В ОП посте есть инструкции.
>>683588
Ну и ужасный код. массивы на массиве. Зачем ты делаешь 5 однотиных переменных когда можно сделать еще один массив? Если тебе надо найти минимальные значения, просто отсортируй записи.
Это монго дб? А в SQL кстати минимальные значения находятся простым запросом. за это я люблю SQL и не люблю монгу.
>>683886
Ты неправильный запрос пишешь. Ты не можешь переключиться. Ты должен установить модуль который связывает апач и php, забыл как он называется, в ОП посте было что-то на эту тему, посомтри.
> Это проблема точно в пхпшторме, я запускал php скрипт с пхпифно из htdocs в папке апача и там server api был apache 2 handler.
Ну так и запускай из-под апача, зачем тебе пхпшторм. Ну или попробуй там с настройками похимичить.
Я вообще вижу на картинке 2 блока друг под другом. Элементарно.
>>684026
У меня он называется php_pdo_mysql.dll и шел в комплекте с PHP5 (windows).
>>684731
> Алсо, тесты на XSS просто удивительны. Часть нерабочая сама по себе, часть работает на седьмом эксплорере и вообще в нетскейпе.
Главное чтобы твой парсер на выходе давал аккуратный HTML
> На пике великий и могущественный DOM в работе.
Надо варнинги перехватыват и очищать, там есть функция.
> Алсо, $dom->saveHTML() добавляет к html-коду докта
можно сохранять не весь документ, а одну ноду.
> 0 - любой другой символ
Лучше было зведочку наверно использовать.
АЛсо у тебя странная таблица переходов - например self::STATE_STARTING_TAG; дальше никуда не ведет.
Ну и код стеной, надо бы разбить на части. Например можно сделать массив вида [состояние => функция-обработчик]. Не знаю правда что со скоростью.
> if (substr($html, $i + 1, 8)
Эффективнее substr_compare - не создает новую строку
> через <?xml-* команды можно вставить инъекцию, но браузеры их не понимают
А вот кто их знает, может там что-то есть вроде вставки svg что позволяет выполнить скрипт.
Ну и у тебя алгоритм неаккуратный - вот эти вот постоянные заглядываняи вперед: $html[$i + 1] указыают что тут явно что-то не так. Машина состояний позволяет и без них обойтись.
> self::_deleteAttribute($html, $i, $currentTag, $currentAttribute, $currentAttrValue, $attrStartPosition, $allowedAttributes);
Слишком много аргументов. Алсо вместо удаления лучше просто не добавлять этот атрибут.
> (substr($currentAttrValue, 0, 11) === 'яваскрипт:')
Вот ты и попался. В HTML символы могут быть закодированы HTML мнемониками. Твой парсер их игноиирует, но ты должен сначала раскодировать содержимое атрибута, а только потом проверять.
Ну и как я вижу, там много случае где твой парсер не вырезает яваскрипт-ссылки. А ведь есть еще data-ссылки. Плоховато у тебя с теорией. Надо использовать белый список, то есть разрешить толкьо определенные протоколы в ссылках.
Я вообще вижу на картинке 2 блока друг под другом. Элементарно.
>>684026
У меня он называется php_pdo_mysql.dll и шел в комплекте с PHP5 (windows).
>>684731
> Алсо, тесты на XSS просто удивительны. Часть нерабочая сама по себе, часть работает на седьмом эксплорере и вообще в нетскейпе.
Главное чтобы твой парсер на выходе давал аккуратный HTML
> На пике великий и могущественный DOM в работе.
Надо варнинги перехватыват и очищать, там есть функция.
> Алсо, $dom->saveHTML() добавляет к html-коду докта
можно сохранять не весь документ, а одну ноду.
> 0 - любой другой символ
Лучше было зведочку наверно использовать.
АЛсо у тебя странная таблица переходов - например self::STATE_STARTING_TAG; дальше никуда не ведет.
Ну и код стеной, надо бы разбить на части. Например можно сделать массив вида [состояние => функция-обработчик]. Не знаю правда что со скоростью.
> if (substr($html, $i + 1, 8)
Эффективнее substr_compare - не создает новую строку
> через <?xml-* команды можно вставить инъекцию, но браузеры их не понимают
А вот кто их знает, может там что-то есть вроде вставки svg что позволяет выполнить скрипт.
Ну и у тебя алгоритм неаккуратный - вот эти вот постоянные заглядываняи вперед: $html[$i + 1] указыают что тут явно что-то не так. Машина состояний позволяет и без них обойтись.
> self::_deleteAttribute($html, $i, $currentTag, $currentAttribute, $currentAttrValue, $attrStartPosition, $allowedAttributes);
Слишком много аргументов. Алсо вместо удаления лучше просто не добавлять этот атрибут.
> (substr($currentAttrValue, 0, 11) === 'яваскрипт:')
Вот ты и попался. В HTML символы могут быть закодированы HTML мнемониками. Твой парсер их игноиирует, но ты должен сначала раскодировать содержимое атрибута, а только потом проверять.
Ну и как я вижу, там много случае где твой парсер не вырезает яваскрипт-ссылки. А ведь есть еще data-ссылки. Плоховато у тебя с теорией. Надо использовать белый список, то есть разрешить толкьо определенные протоколы в ссылках.
На посты с 11 по 15 марта я отвечу тут чуть позже. Можете напомнить о себе ссылкой в новом треде.
Если я кого-то пропустил - напомните о себе в новом треде.
Не пишите здесь больше. Идите в новый тред. Здесь будут только ответы на посты 12-15 марта.
http://ideone.com/dNpjm1
Это копия, сохраненная 16 марта 2016 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.