Это копия, сохраненная 24 мая 2017 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
Пожалуйста, пишите один большой пост вместо нескольких маленьких и не флудите не по теме. ОПу ведь все это читать придется.
Это тред для начинающих. Не написал за свою жизнь ни одной программы и имеешь тройку по математике? Ты наш человек.
Устанавливать пока что ничего не требуется, разве что редактор кода вроде Sublime Text 3, Notepad++, Visual Studio Code, Netbeans PHP или PhpStorm (с ним будет удобнее).
Что самое главное для программиста? Умение аккуратно оформлять код (читай второй пост, прежде чем писать код).
Правила: ведем себя воспитанно, помогаем новичкам, постим ссылки на решения задачек, ОП их проверяет и дает советы и замечания. ОП заходит редко, где-то раз в 2-3 дня, у него мало времени, не жди его, решай задачки дальше. ОП отвечает на все вопросы по его задачкам и учебнику, а вот насчет каких-то других вещей - только если останется время. Но в треде немало анонимных экспертов разного уровня, так что вряд ли вопрос останется без ответа.
У нас есть уроки по основам PHP, они собраны и выложены по адресу http://archive-ipq-co.narod.ru/ Это учебник для изучающих с нуля, то есть если ты вообще ничего не знаешь, то надо начать с него. Он простой и понятный (по крайней мере в начале). Там есть задачи, их надо решать обязательно (чтобы стать программистом, надо писать код — иначе никак). Пости ссылки на решения в тред, мы их проверим, напишем замечания и дадим советы по улучшению.
Если не знаешь как решать, запости код, напиши в каком месте остановился и попроси подсказку.
Ты прошел весь учебник? Молодец, но это были лишь основы языка PHP, этого недостаточно. Вот что в идеале надо изучить еще: ООП, как работает веб-сервер, HTML/CSS, SQL, PDO, работа с таблицами в БД, работа с формами, MVC, git, composer, JS, фреймворки, автоматизированное тестирование.
Надо переходить к более серьезным задачкам, которые научат тебя всему этому.
- для начала прочти урок https://github.com/codedokode/pasta/blob/master/soft/web-server.md
- установи Апач + PHP (советы выше и ниже) и читай туториал http://php.net/manual/ru/tutorial.php
- Учи HTML/CSS и SQL, PDO, хотя бы основы
- Далее простая, но полезная задача сделать список студентов, в ней много полезных советов: https://github.com/codedokode/pasta/blob/master/student-list.md
- Более сложная задача сделать файлообменник на микрофреймворке Slim: https://gist.github.com/codedokode/9424217
- Еще более сложная и долгая задача на Yii/Symfony: https://gist.github.com/codedokode/8733007
- После нее можно изучать автоматизированное тестирование https://gist.github.com/codedokode/a455bde7d0748c0a351a
- Если ты все решил, переходи к Symfony 2/Doctrine 2
- Почитать про паттерны http://designpatternsphp.readthedocs.org/ru/latest/README.html (если ты не изучил ни одного фреймворка, то это будет рановато), тут с примерами кода http://designpatternsphp.readthedocs.org/ru/latest/README.html . Имей в виду что без примеров использования их учить бесполезно - не поймешь, хочешь увидеть примеры использования паттернов - ковыряй исходники Симфони, например Symfony Forms. Не заучивай паттерны - смотри код и думай, зачем тут они использованы.
Чтобы делать эти задания, тебе надо установить Апач + PHP (можно заодно сразу и MySQL) на компьютер. Вот полезные инструкции:
https://github.com/codedokode/pasta/blob/master/soft/php-install.md
https://github.com/codedokode/pasta/blob/master/soft/apache-install.md
Может тебе понадобится пользоваться командной строкой, вот гайд https://github.com/codedokode/pasta/blob/master/soft/cli.md
Решения задач лучше показать мне, особенно на ООП,так как сам ты вряд ли увидишь все ошибки. Пости свой код на гитхаб и вкидывай ссылку в тред по мере решения. Я прокомментирую и укажу на ошибки.
Также, у нас есть задачи которые позволят тебе изучить или подтянуть до нормального уровня знания JS/HTML/CSS/SQL. Решай их параллельно с задачами выше.
- HTML/CSS: https://github.com/codedokode/pasta/blob/master/html/html.md
- JS: https://gist.github.com/codedokode/ce30e7a036f18f416ae0
- SPA (сложно): https://github.com/codedokode/pasta/blob/master/js/spa.md
- Проверялка решений на JS: http://dkab.github.io/jasmine-tests/
- MySQL: https://github.com/codedokode/pasta/blob/master/db/databases.md
Что почитать
- Мануал по PHP — http://www.php.net/manual/ru/langref.php
- Сайт phptherightway (перевод на русский: http://getjump.me/ru-php-the-right-way/ )
- По PHP: Профессиональное программирование на PHP Джордж Шлосснейгл
- По PHP: Мэтт Зандстра — PHP: Объекты, шаблоны, методики программирования
- JS: learn.javascript.ru
- Про Git: https://git-scm.com/book/ru/v1
Оформляй код аккуратно!!! — например пропусти через phpformatter.com . Также, если ты пользуешься IDE вроде PhpStorm, Netbeans, Eclipse, то в них эта опция встроена, подробнее: https://gist.github.com/codedokode/8759492
У ОПа нет аккаунтов и групп вконтакте, в фейсбуке, в твиттере, все "пхп-треды" там поддельные.
Платиновые вопросы
- Почему PHP? Потому что фейсбук и википедия на нем написаны, и вакансий море, и учить легко.
- Сайт опять упал!!!!! — Не паникуй, а открой http://rghost.ru/6bfCY9lfl и получи личную немного устаревшую оффлайновую копию сайта (можно читать хоть на андроиде без интернета)
- Что надо знать чтобы найти работу - разработчику: PHP, SQL, HTML/CSS, JS, ООП, Git, композер, MVC, фреймворк. Верстальщику - HTML/CSS, JS, jQuery
- Можно подробнее про поиск работы, собеседования - нет, ОП писать не будет, но может кто из анонов захочет рассказать. Поищите тред перезвонивших, а также раздел /wrk/.
- Сколько времени надо изучать все это? - все зависит от тебя, но не меньше 6-8 месяцев
- Посоветуйте редактор кода - Sublime Text 3, Notepad++, PhpStorm
- Нужен ли ООП, фреймворки, MVC, git, composer? — Да, однозначно. Посмотри любую вакансию.
- Что самое главное для программиста? Умение аккуратно оформлять код.
- ОП, сделай за меня мою работу или домашнее задание? — Это конечно, хорошая идея, но нет.
- Подскажи сайты для поиска работы, я не умею гуглить? — hh.ru, geekjob.ru, moikrug.ru (склеен с brainstorage.me), fl.ru, upwork.com (бывший одеск). Имей в виду, что кроме фриланса есть еще постоянная удаленная работа (remote job) когда тебе не надо тратить время на поиск заказов и переговоры с неадекватными заказчиками.
-------------------
Код нужно писать не как попало, а аккуратно и по правилам. Почему? Потому, что на неакуратно написанный код не хочется даже смотреть.
Если тебе лень выравнивать код руками, закачай его на http://beta.phpformatter.com/ и нажми «format». Робот исправит выравнивание и отступы в мгновение ока (да, прогресс не стоит на месте). Если ты используешь мощную IDE вроде PhpStorm, там тоже есть функция форматирования кода.
Горячие клавиши для форматирования кода в разных IDE: https://gist.github.com/codedokode/8759492
Вообще, в PHP долгое время не было единого стандарта оформления кода, все писали как попало и было много бардака, но сейчас дело лучше — есть стандарты PSR-1 и 2. Вот как надо оформлять код:
- переменные и функции пишутся с маленькой буквы, подчеркивание не используется, используется camelCase, пример: $x, $numberOfPeople, printResults()
- Название функции начинается с глагола, в стиле «сделайЧтоТо»
- не знаешь английский? Не беда, в 21 веке есть решение этой проблемы. Не пиши транслитом, открой лучше Гугл Транслейт или slovari.yandex.ru и найди название для переменной там
- в именах классов используется CamelCase, первая буква большая, «_» может использоваться
- мы предпочитаем подстановку переменных вместо конкатенации строк: "I am $age years old" — хорошо, 'I am ' . $age . ' years old' — плохо из-за обилия точек и кавычек
- мы используем для отступов 4 пробела (можно настроить редактор, чтобы при нажатии Tab он вставлял 4 пробела)
Вот ссылка на стандарты, где все это описано подробнее и даны примеры оформления:
PSR-1: https://github.com/samdark/fig-standards-ru/blob/master/accepted/ru/PSR-1-basic-coding-standard.md
PSR-2: https://github.com/samdark/fig-standards-ru/blob/master/accepted/ru/PSR-2-coding-style-guide.md
Нужно получать кол-во новых комментов к статье по последнему просмотру ее юзером.
Таблица последнего просмотра - article_id, user_id, timestamp; Сущность ActicleLastView.
Сущность Atricle, сериализация через JMS.
Как по уму сделать подсчет кол-ва комментариев появившихся после timestamp по заданному юзеру? Вытаскивать QueryBuilder через leftJoin? Как замэпить полученное число в сущность Article?
>Нужно получать кол-во новых комментов к статье по последнему просмотру ее юзером.
Типо, посмотрел коммепнты, поставил временной маркер, а при следующем просмотре просто подгружаешь, комменты которые появились после временни отмеченного временным маркером?
Скинь код и скрин и диаграмму базы.
Интересует не простейший пример, коих в инете полно. А работоспособное, проверенное решение, которое может держать пару тысяч юзеров, раздавая им свежую информацию.
В целом верно, только кол-во новых показывается в списке, типа стикера с кол-вом новых комментариев в статье после последнего просмотра.
Когда юзер открывает статью - пишу временную метку в ActicleLastView (для таблицы primary key => user_id + article_id).
Потом в списке нужно как-то получить для текущего юзера кол-во комментов оставленных в статье после этой временной метки.
В принципе я уже решил вопрос двумя leftJoin (ActicleLastView, Comments) с кучей условий джойна + groupBy(article_id), но хочется понять, есть ли более элегантное решение, например, с запросами к отношениям как в laravel.
Кстати, вызывают ли @ORM\OneToMany(targetEntity="AppBundle\Entity\Comment", mappedBy="application", orphanRemoval=true, cascade={"remove"}) дополнительные подзапросы при обращении к свойствам или вытягиваются при любом запросе (в т.ч. и через QB)?
Я бы сделал так.
Смотрим комменты.
Записываем номер последнего комментария.
Все не просмотренные комменты - это все комменты у которых собственный номер больше, чем номе последнего коммента.
Чтобы посчитать кол-во их используй конструкцию.
getQuery()->getSingleScalarResult(); Она тебе сразу цифру даст.
Тяжело обьяснять и понимать, кода не видно самой бд. Хуй знает как у тебя там таблицы организованы, какая нормальная форма и тд.
>Кстати, вызывают ли @ORM\OneToMany(targetEntity="AppBundle\Entity\Comment", mappedBy="application", orphanRemoval=true, cascade={"remove"}) дополнительные подзапросы при обращении к свойствам или вытягиваются при любом запросе (в т.ч. и через QB)?
Вроде, когда обьект удаляется, он смотрит обьекты связанные с ним по ссылке и тоже их удалят, чтобы не оставалось "висящих" ссылок, которые никуда не указываю.
Когда переделаете в супергруппу, тогда и зайду.
Нет.
Не переживай, ты не первый сюда с таким вопросом приходишь. Я тоже спрашивал где-то неделю назад.
Пример кода к задаче, который даёт ОП, слегка сбивает с толку. Перепиши весь цикл заново, попробуй решить с помощью while.
Было бы где наговнокодить, там меньше 100 строчек
Рендерить пытаюсь в Controller/Home.php
Я думал над этим. Хочу вот сейчас сделать так, что бы останавливался цикл когда баланс уже 0.
Зато появилась другая: шаблон взял с документации:
https://github.com/Si0n/fileshare-project/blob/master/App/view/form-default.twig
{
"work_status": [{
"id": 293,
"received": "2016-11-12T05:40:09.372Z",
"status_current": "suspended", // rejected suspended finished
"status_date": {
"rejected": false,
"suspended": "2016-11-12T05:40:09.372Z",
"finished": false
}
}]
}
Длинный json с таким контентом.
В php у меня j,sxysq парсер для вывода этого всего через foreach. Считаю общее количество работы вот так <?php echo count($json['work_status']) ?>. Даже сумел сортировать рабjту по status_current и выводить её по запросу одного из 3х статусов, но как ни пытался, не получается подсчитать и вывести, сколько всего
status_current suspended, к примеру.
Ну по логике я попробовал конечно
<?php echo count($json['work_status']['status_current'] == 'suspended') ?> или <?php echo count($item['status_current'] == 'suspended') ?> но нифига.
array_sum(array_map(function ($w) { return $w['status_current'] == 'suspended'; }, $json['work_status']))
На аппликухе на андроиде есть логин, который посылает мне в АПИ данные. Но при сравнении двух паролей генерируется разная хеш-функция, и в итоге проверить на равность неполучается. Есть какие-то способы это сделать? Laravel 5.4
Ну и сложности. Я даже и близко не рыл в эту сторону. Спасибо анон, всё работает как надо. Теперь пойду разберу на части и выясню, почему это работает.
Анон, помоги с регулярными выражениями. Никак не получается написать шаблон. Вот что у меня есть - $regexp='/[(\+7)|8][0-9]{10}/';. Не понимаю как сюда впихнуть условие на любое количество скобок, пробелов или минусов.
Не туда ответил.
Если подумать как следует, то задача становится легкой. Тебе всего лишь надо написать:
Пока кредит больше нуля - считаем общую сумму с учетом сервиса и процента. Если эта сумма больше 5000, то вычитаем из неё 5000 и прибавляем эти 5000 к $total, иначе вычитаем из неё остаток кредита и прибавляем эту сумму к $total. Всё.
Охуенно пофиксил. Пора, наверное, спать идти.
Удалил все ОПовские $amount1 = mt_rand(1,99999999);, кроме одной, т.к. eval все равно гоняет по всем версиям php.
Теперь мы не просто группа, а публичная супергруппа , прости Господи! Добро пожаловать!:
https://t.me/PHP_club
count() не принимает параметром что-то сложнее массива, никаких условий, функций и тому подобного.
array_map() принимает функцию и массив, потом применяет функцию к каждому элементу и возвращает новый массив. То есть после её применения тебе вернется массив вроде [1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1] или с булинами, хз.
С array_sum() думаю уже сам сообразишь как и что.
Success!
Метод, у которого в аргументы будет передаваться массив $previousDropDown, что-то такое. При этом в нём будет создаваться новый $previousDropDown - из только что выбранного.
Js+ Ajax
Вчера лёг спать до этого поста, а утром читал про array_map и пробовал примерчики. Но это >>967022 как-то слишком ювелирно выглядит, толком в логику не вник - с толку сбивала функция и ретурн.
Вот спасибо за разжёвывание.
Для начала поясни зачем тебе там вообще жаваскрипт и что за проект такой. Про echo и то как пхп-скрипт должен отдавать аякс-ответ - ну блин, если ты уж и пользуешься технологией то знать должен.
>Only variables should be passed by reference
Разверните суть сего посыла в целом плз.
>Про echo и то как пхп-скрипт должен отдавать аякс-ответ - ну блин, если ты уж и пользуешься технологией то знать должен.
Когда я читал про аякс, там было сказано только, что он возвращает данные одним куском через echo.
Проект следующий: есть большая таблица (типа экселевской) с данными. В каждой строке информация об отдельном заказе(кто, что, когда, и т.д.). Её вносит менеджер через браузер. А тот, кто имеет дело с конкретным заказом, должен внести некоторые данные (например, серийный номер и точное время принятия). Для этого он заходит на сайт, авторизуется и видит календарь, на котором отмечены дни, в которые у него запланированы заказы. Кликает по любому из них - появляется модальное окно. Сверху инфа о заказе, вынутая из таблицы в БД, снизу поля для ввода инфы.
JS нужен всю дорогу, как же без него?
В данном случае - тебе надо обычное MVC-приложение, такое можно сделать за пару часов. Так и не понял зачем тебе там аякс, только лишнее усложнение.
>Кликает по любому из них - появляется модальное окно. Сверху инфа о заказе, вынутая из таблицы в БД, снизу поля для ввода инфы.
А, епты, не дочитал. Вообще такое лучше в фреймворке делать, там все вообще просто.
>тебе надо обычное MVC-приложение
Да блин. Я НЕ ПОНИМАЮ, как это грёбаное обычное приложение сделать. Вернее, сделать-то я могу, но вот что бы MVC и по фен-шую - не понимаю. Вот конкретно. Написано, что модель не должна срать в эхо. Не должна, блядь, и всё тут. Но как она передаст обратно в контроллер данные? У меня этим занимается аякс. Получается, айск выкинуть? Они там совсем охуели? Что происходит? По идее, паттерн (любой) - это некой HOW TO, призванное облегчать разработку, поддержку и использование. А тут что? Набор гнуси, вот это что такое. Причём переусложнённой и запутанной. Я уже штук пять разных описаний MVC для веба прочитал и все они разные.
>что модель не должна срать в эхо. Не должна, блядь, и всё тут
Ну правильно, модель должна что-то возвращать в контроллер, а контроллер уже передаст данные в твой скрипт, что непонятного то?
Ты прикалываешься?
Через EventDispatcher кидаешь событие, а сервис перехватывает и записывает их в статический объект, за которым в режиме бесконечного лупа следит контроллер
Ну а если ты серьезно не в курсе, то гугли return.
Ну хз как надо, я это сделал в виде 1 индекс.пхп и 1-й папки рядом. Ну типа юзер через форму загружает файл на сервер и этот файл становится тут же виден на страничке и его можно скачать. Если это картинка, то можно сделать валидацию на это дело и выдавать в обёртке <img>. Без фреймворка всё отлично работает. Теперь осталось как-то усложнить всё в MVC.
Я думал, для того чтобы оно заработало в терминале, надо поставить апач,а оно и без апача работает. Объясните, пожалуйста этот момент.
"Оно" это что? Фреймворк, файлик? Если ты про интерпритатор php то для него никакой сервер не нужен.
> А как он не нужен-то?
Так для IDE, например. Где достаточно php.exe и указать к нему путь. Там же и консолька. Смотря что и для чего оно тебе нужно.
ОП сидит в основном треде: >>958715 (OP)
Если у тебя вопросы к ОПу или по каким-то задачам ОПа или хочется проверить решение, то стоит запостить хотя бы ссылку на пост в тот тред, ближайшие несколько дней ОП точно будет там, не тут.
Уже 5 лет пишу на пхп и последние 2 года использую ларавель в своих проектах. В милдварях нет ничего сложного.
Чем ларавель лучше yii2, чому многие прогеры на него переходят, особенно для своих проектов? Я смотрю уроки по yii - ну вроде заебок, всё чётко, понятно, gii хорош.
А что в ларавеле так привлекает?
Ну как бы со стороны архитектуры - уии полное говно. Пройдись по классам и дойди до классов Object \ Component , там лютый трешак. Или посмотри на govnokod.ru . Ларавел также может и покруче создать админку причем более изи см SleepingOwl. Есть крутой DI (IoC container) в отличии от галимого локатора в уии. В уии идут после того как написал на пхп "хелло ворд я вася 2+2=4" но порог входа в Ларавел будет совсем иной. Ну и еще как бы ларку на сколько знаю то финансируют т.е есть инвестиции а уии пишется в свободное время и то судя по репозиторию там все очень плохо ( посмотри сколько пр висит даже), я сам контрибьютил немного в ларку и там как то нормально принимают, в уии аж стремно чет пр кидать сразу понимаешь что упустят (хз). Но есть + в уии что раб сила очень дешевая и создать типичный говносайт не дорого на нем. Но для чего то серьезнее говносайта я категорически против уии. (ору с конфигов в адванседе)
Поясню, что я нашел:
- Отфильтровать расширения файлов, и тогда не смогут залить какой-нибудь yobaskriptxss.php
Резонно. Но я тут провел эксперимент:
>написал в блокноте <?php echo '<img src="dir://yoba.jpg">';?>
>сохранил это в формате .jpg
>залил на сайт через форму
>заинклудил этот jpg на главную страницу
>выдало пикрелейтед
-Так проверь MIME!
Проверял. На уровне post-запроса всё заебись. Вот только где-то я вычитал, что этот самый mime легко подделать.
Т.е., даже getimagesize() иногда за милую душу хавает запрятанный php-код!
Может, нужно как-то аплоудить, проверять файл, а потом его удалять в той же итерации, если он какой-то не правильный? А что, если там скриптина гадкая, которая всё мне сломает нахуй?
Помоги, анон!
Юии это что-то спизженное с асп дот нета, а ларавель это скорее спизженные рельсы.
Лично мне сразу не понравился кодстайл юии и я толком его даже не ковырял и никаких серьезных прожектов на нем не мутил. Ларавел же дал нормальный кодстайл, симпатичный сайт, толковый хелп (но всё же не всё покрывает, но сорцы поглядеть и понять не проблема), всякую хуйню вроде кучи блогов, кастов, плугинов для редакторов итп. Фрилансил на нем без проблем.
Но потом я прозрел и перешел на слим, а сейчас вообще частично перевел некоторую свою хуйню на опенрести
Выноси аплоады в отдельную папку или на отдельный поддомен который про пхп ничего не знает, а просто отдаёт файлы.
Возьми пока на пробу вот это, тут тредов 10-20 с картинками:
- http://www.mediafire.com/file/e8jt8v4fny3m5sk/threads-archive-66-72.zip
- http://www.mediafire.com/file/urj17w5s4w00jqc/threads-60-80.zip
- http://www.mediafire.com/file/gza5360wdzqd743/threads-archive-pr-1..17.zip
Если все нормально получится импортировать, я и оставшееся скину. Учти, что там верстка со временем менялась.
Я сам собирался когда-нибудь сделать архив, но все руки не доходили.
Также, есть еще такой архив, тут все HTML-файлы вcех тредов, без картинок, в исходном необработанном виде. Часть тредов была восстановлена из гуглокеша, что-то было восстановлено из DOM в браузере уже после того как тред был удален, потому там верстка может различаться: http://www.mediafire.com/file/aahizd9bi5kvmnk/threads-1-86-html-only.zip
Ну и если есть более важные дела, не трать слишком много времени на это.
И если будешь писать парсер, я советую предусмотреть возможность заново распарсить тред, это наверно не раз пригодится, если будет найден какой-нибудь баг.
>>966596
Такое решение тоже подходит, оно чем-то даже лучше STI, так как защищает от ситуаций, когда один лайк ссылается на несколько записей.
> Если захочу запретить пользователю ставить лайк самому себе, то в MySQL нужно писать триггер, а Postgres просто использовать CHECK?
Видимо, да. Судя по http://stackoverflow.com/questions/2538786/how-to-abort-insert-operation-in-mysql-trigger/8559284#8559284 там есть костыль, чтобы выбросить ошибку в ходе операции. Но конечно CHECK лучше так как он виден в SQL коде таблицы.
>>966516
Да, на яваскрипте. Программы на яваскрипте можно встраивать в страницу. В ОП посте есть задачки на JS, но изучать придется с самого начала, а не с того как что-то сделать с формой.
>>966393
Есть мнение что главная цель ампа - лучше отслеживать действия пользователей гуглом и контролировать размещение рекламы.
Возьми пока на пробу вот это, тут тредов 10-20 с картинками:
- http://www.mediafire.com/file/e8jt8v4fny3m5sk/threads-archive-66-72.zip
- http://www.mediafire.com/file/urj17w5s4w00jqc/threads-60-80.zip
- http://www.mediafire.com/file/gza5360wdzqd743/threads-archive-pr-1..17.zip
Если все нормально получится импортировать, я и оставшееся скину. Учти, что там верстка со временем менялась.
Я сам собирался когда-нибудь сделать архив, но все руки не доходили.
Также, есть еще такой архив, тут все HTML-файлы вcех тредов, без картинок, в исходном необработанном виде. Часть тредов была восстановлена из гуглокеша, что-то было восстановлено из DOM в браузере уже после того как тред был удален, потому там верстка может различаться: http://www.mediafire.com/file/aahizd9bi5kvmnk/threads-1-86-html-only.zip
Ну и если есть более важные дела, не трать слишком много времени на это.
И если будешь писать парсер, я советую предусмотреть возможность заново распарсить тред, это наверно не раз пригодится, если будет найден какой-нибудь баг.
>>966596
Такое решение тоже подходит, оно чем-то даже лучше STI, так как защищает от ситуаций, когда один лайк ссылается на несколько записей.
> Если захочу запретить пользователю ставить лайк самому себе, то в MySQL нужно писать триггер, а Postgres просто использовать CHECK?
Видимо, да. Судя по http://stackoverflow.com/questions/2538786/how-to-abort-insert-operation-in-mysql-trigger/8559284#8559284 там есть костыль, чтобы выбросить ошибку в ходе операции. Но конечно CHECK лучше так как он виден в SQL коде таблицы.
>>966516
Да, на яваскрипте. Программы на яваскрипте можно встраивать в страницу. В ОП посте есть задачки на JS, но изучать придется с самого начала, а не с того как что-то сделать с формой.
>>966393
Есть мнение что главная цель ампа - лучше отслеживать действия пользователей гуглом и контролировать размещение рекламы.
В формах есть пара специальных типов полей:
- http://symfony.com/doc/current/reference/forms/types/collection.html
- также, можно вкладывать поля друг в друга (то есть у класса формы может быть поле-подформа) для отношений один-к-одному
Добавление/удаление вопросов и переключение их типов придется скорее всего делать яваскриптом.
Роуты может быть удобнее описывать не аннотациями, а в отдельном конфиге.
> if (!$tests) {
> throw $this->createNotFoundException(
> 'No tests'
Если тестов пока нет, то стоит выводить вместо списка сообщение об этом.
> ->createQuery("select a from AppBundle\Entity\User a
> where a.id=".$test->getAuthor()->getId())
Надо использовать плейсхолдеры, так же для поиска по простым условиям есть функции findBy(), findOneBy(), find().
Также, возможно стоит выносить функции вроде "найти тест", "найти все тесты определенного вида" в отдельный сервис. Так как позже там будут добавляться условия (вроде того, что тест должен быть не скрыт), и придется копипастить проверки этих условий.
> if (isset($_GET['status'])){
Надо использовать Request
>>966146
Ты про класс HttpKernel или компонент? Если посмотреть компонент https://github.com/symfony/http-kernel то там довольно много, так что наверно вопрос был про класс.
Вот интерфейс: https://github.com/symfony/http-kernel/blob/master/HttpKernelInterface.php
Вот реализация по умолчанию: https://github.com/symfony/http-kernel/blob/master/HttpKernel.php
Как видно, HttpKernel является чем-то вроде Front Controller, он обеспечивает нахождение и вызов контроллера, который будет обрабатывать запрос, обработку исключений и генерацию событий. События довлоьно важны, например, роутер в Симфони вызывается по одному из событий вроде REQUEST (а по событию EXCEPTION запускается обработчик, выводящий страницу ошибки). Хотя мне это не очень и нравится, так как такой неявный вызов роутера создает свои сложности.
В формах есть пара специальных типов полей:
- http://symfony.com/doc/current/reference/forms/types/collection.html
- также, можно вкладывать поля друг в друга (то есть у класса формы может быть поле-подформа) для отношений один-к-одному
Добавление/удаление вопросов и переключение их типов придется скорее всего делать яваскриптом.
Роуты может быть удобнее описывать не аннотациями, а в отдельном конфиге.
> if (!$tests) {
> throw $this->createNotFoundException(
> 'No tests'
Если тестов пока нет, то стоит выводить вместо списка сообщение об этом.
> ->createQuery("select a from AppBundle\Entity\User a
> where a.id=".$test->getAuthor()->getId())
Надо использовать плейсхолдеры, так же для поиска по простым условиям есть функции findBy(), findOneBy(), find().
Также, возможно стоит выносить функции вроде "найти тест", "найти все тесты определенного вида" в отдельный сервис. Так как позже там будут добавляться условия (вроде того, что тест должен быть не скрыт), и придется копипастить проверки этих условий.
> if (isset($_GET['status'])){
Надо использовать Request
>>966146
Ты про класс HttpKernel или компонент? Если посмотреть компонент https://github.com/symfony/http-kernel то там довольно много, так что наверно вопрос был про класс.
Вот интерфейс: https://github.com/symfony/http-kernel/blob/master/HttpKernelInterface.php
Вот реализация по умолчанию: https://github.com/symfony/http-kernel/blob/master/HttpKernel.php
Как видно, HttpKernel является чем-то вроде Front Controller, он обеспечивает нахождение и вызов контроллера, который будет обрабатывать запрос, обработку исключений и генерацию событий. События довлоьно важны, например, роутер в Симфони вызывается по одному из событий вроде REQUEST (а по событию EXCEPTION запускается обработчик, выводящий страницу ошибки). Хотя мне это не очень и нравится, так как такой неявный вызов роутера создает свои сложности.
Если ты используешь синтаксис вроде $this->... внутри коллбека, то надо проставить как-то тайп-хинт для this, может через @var $this, но не уверен, что это будет работать. Или откуда ты берешь объект ContainerWrapper? Надо как-то на эту переменную поставить тайп-хинт или phpDoc конструкцию.
>>966100
Ты просто неправильно поделил приложение на M/V/C.
Твое приложение можно рассматривать двояко:
- либо как единое целое, где MVC приложение находится на сервере, а JS-код - это лишь часть интерфейса, часть HTML-страницы, "тонкий клиент", который просто передает запросы на сервер и отображает ответы. То есть является дополнением к View.
- либо как 2 независимых приложения: серверное на PHP, и отдельное на JS, которое взаимодействует с сервером, но содержит свои модели, свое хранилище данных, может само их обрабатывать. Тут будет 2 набора M/V/C на клиенте и сервере.
Если JS код это отдельное приложение, то код на JS - долгоживущий, и ему нужен вариант MVC с активной моделью. Если что, вот тут на примере игры разбираются такие реализации MVC: https://github.com/codedokode/pasta/blob/master/js/minesweeper-mvc.md
Проще наверно рассматривать JS код как "тонкого" (с маленьким объемом логики) клиента, а PHP-код как отдельное MVC приложение. Тогда у нас на сервере мы используем обычные контроллеры, модели и вью. А задача JS приложения просто передать запрос пользователя на сервер и отобразить результат, оно просто служит продолжением контроллера и вью в PHP.
Делать JS как отдельное приложение - это значит, надо делать хранилище данных на клиенте, синхронизировать его с сервером, делать какие-то операции независимо от сервера. Это дает преимуещства вроде возможности работать в оффлайне или обрабатывать данные на клиенте, но тебе это вряд ли нужно. Если ты видел мобильные приложения, они примерно так же работают - они берут данные с сервера, но какие-то операции могут делать сами, и многда могут работать при пропадании интернета.
> написано, что он должен возвращать результат через return. Но пхп-скрипт, который вызывается в аяксе, оформлен у меня просто кодом на пхп, а не функцией (вернее, функции там тоже есть, но уже внутри).
Потому что ты не совсем верно разделил код. Если мы считаем что JS - это полноценное приложение, то в JS коде должна быть модель, а в ней функция, которая принимает данные, отправляет запрос, и позже возвращает результат. Если мы считаем что приложение у нас только на сервере, то эта функция должна быть только там.
> Там же написано, что пхп-скрипт не должен выдавать ничего в echo.
Выводом должен заниматься только View. Модель точно не должна, контроллер обычно тоже.
> Единственный вариант, который я вижу - json.
Это то же самое, что вывод HTML.
> Первый стул - это вернуть из пхп-скрипта (Модели) эти значения и уже в js-скрипте (Вид) подставить их в ячейки документа
> Второй стул - это оставить в index.php только место для вставки, а полностью весь код таблицы набрать в пхп-скрипте, передать его через айкс обратно js-скрипту и вставить одним действием
Это просто выбор, где делать шаблонизацию: на сервере или клиенте. Надо взвесить достоинства и недостатки и выбрать более подходящий вариант.
> Но в том же гайде пишут, что нельзя Виду работать с document.
Виду как раз можно, это модели нельзя.
Если ты используешь синтаксис вроде $this->... внутри коллбека, то надо проставить как-то тайп-хинт для this, может через @var $this, но не уверен, что это будет работать. Или откуда ты берешь объект ContainerWrapper? Надо как-то на эту переменную поставить тайп-хинт или phpDoc конструкцию.
>>966100
Ты просто неправильно поделил приложение на M/V/C.
Твое приложение можно рассматривать двояко:
- либо как единое целое, где MVC приложение находится на сервере, а JS-код - это лишь часть интерфейса, часть HTML-страницы, "тонкий клиент", который просто передает запросы на сервер и отображает ответы. То есть является дополнением к View.
- либо как 2 независимых приложения: серверное на PHP, и отдельное на JS, которое взаимодействует с сервером, но содержит свои модели, свое хранилище данных, может само их обрабатывать. Тут будет 2 набора M/V/C на клиенте и сервере.
Если JS код это отдельное приложение, то код на JS - долгоживущий, и ему нужен вариант MVC с активной моделью. Если что, вот тут на примере игры разбираются такие реализации MVC: https://github.com/codedokode/pasta/blob/master/js/minesweeper-mvc.md
Проще наверно рассматривать JS код как "тонкого" (с маленьким объемом логики) клиента, а PHP-код как отдельное MVC приложение. Тогда у нас на сервере мы используем обычные контроллеры, модели и вью. А задача JS приложения просто передать запрос пользователя на сервер и отобразить результат, оно просто служит продолжением контроллера и вью в PHP.
Делать JS как отдельное приложение - это значит, надо делать хранилище данных на клиенте, синхронизировать его с сервером, делать какие-то операции независимо от сервера. Это дает преимуещства вроде возможности работать в оффлайне или обрабатывать данные на клиенте, но тебе это вряд ли нужно. Если ты видел мобильные приложения, они примерно так же работают - они берут данные с сервера, но какие-то операции могут делать сами, и многда могут работать при пропадании интернета.
> написано, что он должен возвращать результат через return. Но пхп-скрипт, который вызывается в аяксе, оформлен у меня просто кодом на пхп, а не функцией (вернее, функции там тоже есть, но уже внутри).
Потому что ты не совсем верно разделил код. Если мы считаем что JS - это полноценное приложение, то в JS коде должна быть модель, а в ней функция, которая принимает данные, отправляет запрос, и позже возвращает результат. Если мы считаем что приложение у нас только на сервере, то эта функция должна быть только там.
> Там же написано, что пхп-скрипт не должен выдавать ничего в echo.
Выводом должен заниматься только View. Модель точно не должна, контроллер обычно тоже.
> Единственный вариант, который я вижу - json.
Это то же самое, что вывод HTML.
> Первый стул - это вернуть из пхп-скрипта (Модели) эти значения и уже в js-скрипте (Вид) подставить их в ячейки документа
> Второй стул - это оставить в index.php только место для вставки, а полностью весь код таблицы набрать в пхп-скрипте, передать его через айкс обратно js-скрипту и вставить одним действием
Это просто выбор, где делать шаблонизацию: на сервере или клиенте. Надо взвесить достоинства и недостатки и выбрать более подходящий вариант.
> Но в том же гайде пишут, что нельзя Виду работать с document.
Виду как раз можно, это модели нельзя.
замечу еще что mysql-функции уже давно устарели.
>>965899
>>Сделай все в одной функции, можно даже без классов.
> Я же ООП учу, зачем мне это?
Ну например чтобы проверить, насколько запутаннее получается код без применения ООП.
> public function getEmpolyees($position, $rank, $boss, $quantity)
Во-первых, название неправильное. Функции getSomething обычно что-то возвращают, но здесь это не так (здесь подойдет add). Во-вторых, ты искуственно ограничиваешь возможности по добавлению работников. Можно было бы сделать так:
addEmployee(Employee $employee)
Это позволяет добавлять любых работников с любыми свойствами. Ты же искуственно добавляешь ограничение, что можно добавлять только работников с определенным конструктором и ровно с 2 аргументами в конструкторе. Мой подход дает больше свободы и с ним департамент не обязан знать про то, как создаются объекты работников, меньше зависимостей между классами.
Также, у тебя почему-то в getEmployees не проставляется поле quantity, хотя оно исплоьзуется в других функциях ниже. Почему?
Также, у тебя в коде ошибки:
> Notice: Undefined index: allDepSalary in /in/28B8k on line 186
> public function calculateall() //Произвести все расчеты и вывести на экран.
Это не задача департамента, что-то выводить на экран, это лучше сделать снаружи класса.
В классе Employee есть поле quantity, но оно почему-то почти нигде не используется. Зачем оно тогда?
> $salary = $salary + ($salary)*25/100;
Тут проще было определять только коэффициент, вместо того чтобы копипастить эту формулу несколько раз.
> If ($this->boss) $salary=$salary
Надо ставить фигурные скобки.
Слова class, if пишутся с маленькой буквы.
Сумму можно считать либо отдельной функцией, либо сделать класс Компания, а в нем методы для подсчета суммы.
Насчет поля quantity - надо его либо использовать, либо убрать. Либо ты помещаешь его в класс ГруппаРаботников, либо еще куда-то, либо убираешь. Но не как сейчас, что поле есть, но не используется.
Если ты хочешь, ты можешь сделать класс для группы работников, а не одного работника. Только назови его правильно. Но сделай тогда и вторую часть задачи, про антикризисные меры, иначе ООП не поймешь.
> Может перенести это поле в департамент?
Количество разное для разных групп работников и свойством департамента оно быть не может.
В реализации наследования работников есть небольшая проблема. У тебя при наследовании надо обязательно прописать значения зарплаты, потребления кофе итд. Но как об этом догадаться? Как это проконтроллировать? Никак. Здесь лучше исользовать абстрактные методы вроде получитьБазовуюЗарплату(), сделать эти методы в базовом классе, чтобы нельзя было унаследоваться, не переопределив их.
замечу еще что mysql-функции уже давно устарели.
>>965899
>>Сделай все в одной функции, можно даже без классов.
> Я же ООП учу, зачем мне это?
Ну например чтобы проверить, насколько запутаннее получается код без применения ООП.
> public function getEmpolyees($position, $rank, $boss, $quantity)
Во-первых, название неправильное. Функции getSomething обычно что-то возвращают, но здесь это не так (здесь подойдет add). Во-вторых, ты искуственно ограничиваешь возможности по добавлению работников. Можно было бы сделать так:
addEmployee(Employee $employee)
Это позволяет добавлять любых работников с любыми свойствами. Ты же искуственно добавляешь ограничение, что можно добавлять только работников с определенным конструктором и ровно с 2 аргументами в конструкторе. Мой подход дает больше свободы и с ним департамент не обязан знать про то, как создаются объекты работников, меньше зависимостей между классами.
Также, у тебя почему-то в getEmployees не проставляется поле quantity, хотя оно исплоьзуется в других функциях ниже. Почему?
Также, у тебя в коде ошибки:
> Notice: Undefined index: allDepSalary in /in/28B8k on line 186
> public function calculateall() //Произвести все расчеты и вывести на экран.
Это не задача департамента, что-то выводить на экран, это лучше сделать снаружи класса.
В классе Employee есть поле quantity, но оно почему-то почти нигде не используется. Зачем оно тогда?
> $salary = $salary + ($salary)*25/100;
Тут проще было определять только коэффициент, вместо того чтобы копипастить эту формулу несколько раз.
> If ($this->boss) $salary=$salary
Надо ставить фигурные скобки.
Слова class, if пишутся с маленькой буквы.
Сумму можно считать либо отдельной функцией, либо сделать класс Компания, а в нем методы для подсчета суммы.
Насчет поля quantity - надо его либо использовать, либо убрать. Либо ты помещаешь его в класс ГруппаРаботников, либо еще куда-то, либо убираешь. Но не как сейчас, что поле есть, но не используется.
Если ты хочешь, ты можешь сделать класс для группы работников, а не одного работника. Только назови его правильно. Но сделай тогда и вторую часть задачи, про антикризисные меры, иначе ООП не поймешь.
> Может перенести это поле в департамент?
Количество разное для разных групп работников и свойством департамента оно быть не может.
В реализации наследования работников есть небольшая проблема. У тебя при наследовании надо обязательно прописать значения зарплаты, потребления кофе итд. Но как об этом догадаться? Как это проконтроллировать? Никак. Здесь лучше исользовать абстрактные методы вроде получитьБазовуюЗарплату(), сделать эти методы в базовом классе, чтобы нельзя было унаследоваться, не переопределив их.
На мой взгляд, в ларавель слишком много статических методов. После Симфони как-то не очень.
>>967822
Нужно не инклудить что попало. Либо жестко прописывать пути к файлам. Инъекция полявляется когда ты путь формируешь на основе переданных от пользователя перемеенных.
Про меры безопасности при загрузке файлов можно прочесть в комментариях к задаче про файлообменник: https://gist.github.com/codedokode/9424217
Возможно, что проще всего SQL-запросом. У тебя на пару (user, article) хранится только последний просмотр или все? Если второе, то конечно запрос будет посложнее.
> Как замэпить полученное число в сущность Article?
Никак. Одна сущность - одна таблица. Можно сделать только связь M-N между User, Article через промежуточную таблицу с timetamp, но я думаю, что эффективнее просто брать нужные данные SQL запросом.
> Вытаскивать QueryBuilder через leftJoin?
QueryBuilder нужен при сборке запроса в зависимости от условий
>>966678
Был какой-то php multiplexor.
>>966706
SQL запросом лучше всего, не в сущности, а в отдельном сервисе. Получив дату, мы выбираем комментарии по условию time > ?
Зачем усложнять? Сущности/DQL надо использовать когда тебе нужен маппинг, получить 1 цифру из БД проще SQL или DQL запросом (DQL запрос тоже может возвращать 1 число, а не сущность).
> Кстати, вызывают ли @ORM\OneToMany(targetEntity="AppBundle\Entity\Comment", mappedBy="application", orphanRemoval=true, cascade={"remove"}) дополнительные подзапросы при обращении к свойствам или вытягиваются при любом запросе (в т.ч. и через QB)?
OneToMany не должен вызывать запросов, при загрузке сущности там в поле просто прописывается прокси-коллекция которая лениво загрузится только при обращении к ней.
Имей в виду, что это может вызывать свои проблемы. Представь что у тебя у Поста 1000 комментариев. Если ты сделаешь count($this->comments) то даже это приведет к выборке всех 1000 комментариев в память. Добавление 1 комментария в коллекцию скорее всего тоже вызовет подгрузку существующих.
Хотя по моему, именно для COUNT там есть какая-то опция, которая позволяет сделать SELECT COUNT в такой ситуации.
А вот обратная сторона OneToOne отношения (та сторона, где нет внешнего ключа) по моему вызвает дополнительный джойн, так как без него неясно, что записать в поле - null или прокси-объект с определенным id.
Ну то есть, если представить как работает ленивая загрузка, станет понятно, когда какие запросы вызываются. по умолчанию доктрина пытается откладывать загрузку всего на потом.
Возможно, что проще всего SQL-запросом. У тебя на пару (user, article) хранится только последний просмотр или все? Если второе, то конечно запрос будет посложнее.
> Как замэпить полученное число в сущность Article?
Никак. Одна сущность - одна таблица. Можно сделать только связь M-N между User, Article через промежуточную таблицу с timetamp, но я думаю, что эффективнее просто брать нужные данные SQL запросом.
> Вытаскивать QueryBuilder через leftJoin?
QueryBuilder нужен при сборке запроса в зависимости от условий
>>966678
Был какой-то php multiplexor.
>>966706
SQL запросом лучше всего, не в сущности, а в отдельном сервисе. Получив дату, мы выбираем комментарии по условию time > ?
Зачем усложнять? Сущности/DQL надо использовать когда тебе нужен маппинг, получить 1 цифру из БД проще SQL или DQL запросом (DQL запрос тоже может возвращать 1 число, а не сущность).
> Кстати, вызывают ли @ORM\OneToMany(targetEntity="AppBundle\Entity\Comment", mappedBy="application", orphanRemoval=true, cascade={"remove"}) дополнительные подзапросы при обращении к свойствам или вытягиваются при любом запросе (в т.ч. и через QB)?
OneToMany не должен вызывать запросов, при загрузке сущности там в поле просто прописывается прокси-коллекция которая лениво загрузится только при обращении к ней.
Имей в виду, что это может вызывать свои проблемы. Представь что у тебя у Поста 1000 комментариев. Если ты сделаешь count($this->comments) то даже это приведет к выборке всех 1000 комментариев в память. Добавление 1 комментария в коллекцию скорее всего тоже вызовет подгрузку существующих.
Хотя по моему, именно для COUNT там есть какая-то опция, которая позволяет сделать SELECT COUNT в такой ситуации.
А вот обратная сторона OneToOne отношения (та сторона, где нет внешнего ключа) по моему вызвает дополнительный джойн, так как без него неясно, что записать в поле - null или прокси-объект с определенным id.
Ну то есть, если представить как работает ленивая загрузка, станет понятно, когда какие запросы вызываются. по умолчанию доктрина пытается откладывать загрузку всего на потом.
кстати, раз уж ларавель-кун в треде, ответь на вопрос, будь ласка. мне надо админку делать к тестовому заданию, как правильно и грамотно? что читать, куда копать?
Ссылка не работает, но по моему в сообщении черным по белым написана причина. Или у тебя использован этот тег, но все равно ошибка?
При использовании форм обрати внимание, что в отдельном компоненте форм не доступны все фичи, которые есть при использовании форм в составе фреймворка симфони.
>>967018
Сравнить хеши от разных функций нельзя. Либо ты что-то делаешь неправильно.
>>967026
Напиши выражение для
"ровно 1 цифра, за ней любое число пробелов-минусов-скобок"
Затем возьми его в скобки и напиши что оно повторяется ровно 10 раз.
>>967265
Ответ чуть выше.
>>967318
Поищи статьи вроде "N лучших адаптивных сайтов". Посмотри, какие решения использованы.
Изучи:
- тег meta viewport, подробно
- CSS-медиазапросы @media (max-width) подробно
- атрибуты srcset, теги picture, source
Для начала наверно хватит.
>>967347
Если у функции аргумент, который принимает не значение, а ссылку на переменную:
function (&$x)
То в нее можно передать только переменную, элемента массива, но нельзя например передать число или строку. Потому что функции нужна ссылка, по которой что-то можно записать, а в число записать ничего неьзя, это значение, а не переменная или элемент массива.
Почитай PHP мануал про ссылки.
>>967397
Читай оповское на гитхабе.
>>967431
Через return. Открой пример кода у ОПа и посмотри как сделан PostService: https://github.com/codedokode/pasta/blob/master/arch/mvc.md
Это и есть модель.
>>967454
Зачем пишешь бред?
>>967394
По определению, публичная папка это та, из которой раздает файлы веб-сервер. Из непуьличной можно раздавать только на уровне приложения, например PHP скрипт читает этот файл и потихоньку склармливает браузеру.
>>967527
В PHP встроен мленький веб-сервер, почитай: https://github.com/codedokode/pasta/blob/master/soft/web-server.md
>>967666
foreach нужен для перебора массива, for для циклов со счетчиком или условием.
Ссылка не работает, но по моему в сообщении черным по белым написана причина. Или у тебя использован этот тег, но все равно ошибка?
При использовании форм обрати внимание, что в отдельном компоненте форм не доступны все фичи, которые есть при использовании форм в составе фреймворка симфони.
>>967018
Сравнить хеши от разных функций нельзя. Либо ты что-то делаешь неправильно.
>>967026
Напиши выражение для
"ровно 1 цифра, за ней любое число пробелов-минусов-скобок"
Затем возьми его в скобки и напиши что оно повторяется ровно 10 раз.
>>967265
Ответ чуть выше.
>>967318
Поищи статьи вроде "N лучших адаптивных сайтов". Посмотри, какие решения использованы.
Изучи:
- тег meta viewport, подробно
- CSS-медиазапросы @media (max-width) подробно
- атрибуты srcset, теги picture, source
Для начала наверно хватит.
>>967347
Если у функции аргумент, который принимает не значение, а ссылку на переменную:
function (&$x)
То в нее можно передать только переменную, элемента массива, но нельзя например передать число или строку. Потому что функции нужна ссылка, по которой что-то можно записать, а в число записать ничего неьзя, это значение, а не переменная или элемент массива.
Почитай PHP мануал про ссылки.
>>967397
Читай оповское на гитхабе.
>>967431
Через return. Открой пример кода у ОПа и посмотри как сделан PostService: https://github.com/codedokode/pasta/blob/master/arch/mvc.md
Это и есть модель.
>>967454
Зачем пишешь бред?
>>967394
По определению, публичная папка это та, из которой раздает файлы веб-сервер. Из непуьличной можно раздавать только на уровне приложения, например PHP скрипт читает этот файл и потихоньку склармливает браузеру.
>>967527
В PHP встроен мленький веб-сервер, почитай: https://github.com/codedokode/pasta/blob/master/soft/web-server.md
>>967666
foreach нужен для перебора массива, for для циклов со счетчиком или условием.
Это не статика наверное, а фасады. Инфа гуглится
Спроси у своего Мб погонщика нужна ли админка. Может тебя просто наябывают . И если нужна спроси прокатит ли вариант с совой
>ты можешь сделать класс для группы работников
nananananan
Мы уже проходили это. Это очень бредовая идея.
>Насчет поля quantity - надо его либо использовать, либо убрать.
Используется же для создания работников в цикле getEmpolyees.
>У тебя при наследовании надо обязательно прописать значения зарплаты, потребления кофе итд.
Это подразумевается, когда ты создаёшь новую профессию, зачем её создавать не задав ей никаких параметров?
Уже не знаю, что делать. В общем есть два блока:
<div>Блок1</div>
<div>Блок2</div>
Хочу разместить их строго друг за другом. Для этого прописываю в css display: inline-block; - везде пишут, что блоки приобретают свойство строчных элементов и располагаются строго друг за другом, а не переносятся наследующую строку. В Html-academy написано то же самое.
В результате у меня блок2 все равно переносится на новую строку. Вообще блядь ничего не меняется. Меня это дерьмо уже заебало. Помогите пожалуйста.
Ебани бутстрап точнее отдельно сетку оттуда, номером с нуля делаешь то враппать 2 твоих блока надо классом с инлайном и ширину в % блока которые вложены. Считай все правильно делаешь, врапни и чилдам ширину добавь
Ты все курсы в htmlacademy прошел? Такое ощущение, что нет.
Внезапно, браузер начинает тормозить. В консоли сайта вот такая хрень. Штоэта? У меня таких js-ок вообще нет, а в шапке подгружаются только такие:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script><!-- для загрузки фото -->
<script type="text/javascript" src="http://scriptjava.net/source/scriptjava/scriptjava.js"></script><!-- для загрузки фото -->
<script type="text/javascript" src="js/external/jquery/jquery.js"></script>
<script type="text/javascript" src="js/jquery-ui.js"></script>
<script type="text/javascript" src="js/jquery-ui-datepicker-ru.js"></script>
<script type="text/javascript" src="js/jquery.main.js"></script>
<script type="text/javascript" src="core.js"></script><!-- Основная логика сайта -->
И так постоянно теперь. Зашёл на страницу, нажал что-нибудь - и пошло поехало. Проверял винду на вирусы - чисто. В другом браузере то же самое.
Главное, я не понимаю, откуда вообще это подгружается? Как определить?
На хостинг - в смысле на модную одминку для веб-сайтов уровня бложеков, в которой даже ssh нет? Или на секурный тобою лично настроенный сервер?
Получаю, мамкину. Ну и второе тоже.
Но ведь это решит его проблему.
Работаю админом-эникеем.
Возможно это от хостинга. 200 лет тому назад, на бесплатных хостингах былла такая фича, как инжект скриптов в сайты юзеров. Так же бывало в настройках, подключались так библиотеки разные.
Ну вот и говорю - если бы настроил сам все порты, базы, поставил бы всё вручную - никто бы не взломал.
Я уже, кстати, не первый раз сталкиваюсь с таким - жил был сайт на уважаемом "хостинге", а потом хуяк и взломали.
Почему-то если соблюдать элементарные правила, то всё работает как часы годами.
Всё работает, о чём ты?
<div style="display:inline-block">Блок1</div>
<div style="display:inline-block">Блок2</div>
Просканил сайт через virustotal.com и 2ip.ru/site-virus-scaner - пишут, что чисто.
Так вирустотал же не может залезть во всю логику и внутренний код. Какой-то ты совсем профан, не понимаешь элементарных вещей.
Лучше подучись юниксам и прочим девопсам, в жизни пригодится.
>Лучше подучись юниксам и прочим девопсам, в жизни пригодится.
Не пригодится. Админство умирает.
>Какой-то ты совсем профан
Раньше как-то не приходилось сталкиваться с вирусами на сайтах.
И ещё я выяснил, что запросы начинают идти сразу после процедуры логина. Странно. Там у меня цепочка login.php -> index.php -> manager.php либо guard.php. Всё по гайду из https://habrahabr.ru/post/13726/
login.php просто стучит в дыню в бд, генерирует хеш, сравнивает пароли, ставит куки и редиректит на index.php.
header("Location: index.php"); exit();
Что тут можно сломать - хрен знает. Я даже все файлы уже заменил на заведомо чистые. Не помогло.
>Админство умирает.
А кто будет разворачивать всё и поддерживать? Дед Мороз?
Даже чтобы paas типа амазоновских приблуд настроить нужно дофига знания.
>А кто будет разворачивать всё и поддерживать? Дед Мороз?
Данный срач не для этого треда. Но всё же не удержусь: количество админских вакансий с каждым годлом уменьшается, зарплата либо стоит на месте, либо уменьшается при очередном кризисе, а требования растут. Это статистика. Что там внутри происходит, какие процессы влияют - разговор отдельный. Но по итогу админство умирает. Я сейчас получаю килобакс за эникейство. Это с MCSA и CCNA. Могу я получать больше? Ну, положим, могу. 80к за въёбывание от рассвета до заката и ещё чуть-чут. Но это уже уровень руления цисковскими шеститонниками. Нужен мне такой геморрой за лишние 20к? Нет.
И как бороться с повторным отправлением файла при возврате или обновлении странички? Вот это вот "повторная отправка формы".
Я сделал какую-то хуйню, чтоб избежать этого: заставил вылезать поп-ап после отправки файла - "файл отправлен" и когда тыкаешь на закрытие поп-апа, то идёт переход на страницу загрузки - ну слишком убогий костыль. Анон, что делать, а?
Не, если так, то при обновлении страницы или переходе назад - повторная отправка. Ну я и сделал по сути редирект, только через джаваскрипт и диалог, но это не очень.
Купи уже нормальную линукс-впску и установи lamp.
Ты не будешь разворачивать на винде заказчику.
я и спрашиваю как с нуля ебашить. добавить страницу, роут и разрешить только юзеру админ туда войти? надо мидлваре контроллер написать?
Ты нахуй бампаешь свой пост, который оставил меньше 20 минут назад, и который даже уплыть не успел сука? Вот нихуя тебе не буду подсказывать. Сиди думай сам, а не бампай, как ебанутый.
ну лол, я сижу думаю уже часа 4 наверное. заебался если честно , уже хочется дальше пойти.
Э бля, там че та качать надо, иди ка ты нахуй со своими зондами, репорт.
Это телега же, лол
Диды без двачей писали духам завещали дидов не увожаешь
Даже стэковерфлоу не было
Дана тебе документация, есть куча книг - жуй не хочу, нет, буду ждать идиотских ответов на дваче.
На дваче только поверхностное могут сказать, беги отсюда, пока молодой мелокбуквенный, оно тебя сожрет.
в гугеле не знаю как сформулировать вопрос. блядь, разве так сложно мне ответить? Просто я не знаю как указать в массиве то что записано в $random
$op = '+';
$result = 5 $op 4;
и результат будет 9.
Хотя уже не надо, я задачу с калькулятором так решил. Проверьте/посоветуйте, пожалуйста.
https://3v4l.org/1ensi
Ты свой покажи.
Короче, тебе нужна функция mt_rand() - выберешь число из количества элементов в массиве - посчитай это количество, а ещё нужно вспомнить, как доставать значение из простого массива, имея ключ - число.
Это как-то сложно, там сайт с сотовым.
>Электросеть
https://jsfiddle.net/6591a2sL/7/
>> Если что, я не согласен с вашим замечанием - потому что мне не нужно было давать ссылку на Сеть, только передать уже посчитанный баланс. Можно было считать Сеть за контроллер, а ЛЭП за модель которая содержит вспомогательные методы расчета. А теперь в эти методы нужно передавать ссылку на ЛЭП. Мне из-за этого кажется что я понял и сделал всё ещё более худшим образом.
>Я уже не очень понимаю, о чем речь. Тот метод, что используется сейчас, вполне подходит. Если хочется обсудить другой вариант, то хорошо бы увидеть хотя бы кусочек кода.
Было:
function ElectricalNetwork(...) {
...
}
function PowerLine(..., price) {
...
this.price = price;
}
PowerLine.prototype.countPowerAfterPass= function(power) {
...
}
PowerLine.prototype.countPrice = function(power) {
...
}
Потом стало:
function ElectricalNetwork(...) {
...
}
ElectricalNetwork.prototype.countPowerAfterPass= function(linkToPowerLine, power) {
...
}
ElectricalNetwork.prototype.countPrice = function(linkToPowerLine, power) {
...
}
function PowerLine(..., price) {
...
this.price = price;
}
>> Можно я не буду эту менять? Придётся заново переосмысливать мою программу.
>По идее, ты должен стараться писать программу так, что в ней было легко разобраться. И соответственно небольшие изменения не должны вызывать сложностей и ради них не требуется всю программу переделывать, а только небольшую часть. А если все оставить как есть - может ты и дальше будешь писать цикл там, где он не требуется.
На самом деле, сейчас я припоминаю, что сначала я пытался решить через min()\max(), но у меня что-то не получалось и я решил написать счетчик через цикл, как и должно быть работают счетчики в реальном мире.
>Определение типа переменной
https://jsfiddle.net/5q3r473h/5/
>Напиши функцию неглубокого копирования объектов и массивов
https://jsfiddle.net/uyey3at1/6/
>> var clone = object.bind(clone);
>Тут ошибка. Во-первых, клонировать функции не требуется (да и это невозможно наверно), во-вторых, если уж клонировать, то непонятно почему надо привязывать this к пустому на тот момент значению clone. Что делает этот bind?
Я пытался получить новую функцию из старой.
>> Включая примитивные значения, которые на самом деле тоже объекты?
>Это не так. Почитай пожалуйста еще раз про боксинг, например в моих заданиях по JS ( https://gist.github.com/codedokode/ce30e7a036f18f416ae0#Боксинг ) или в других статьях: http://www.jisaacks.com/javascript-boxing/
>
>Примитивные значения - это не объекты, но если пытаться их использовать как объекты (обращаться к свойствам или методам), для них автоматически создается временный объект, в который заворачивается примитивное значение.
Ах да точно, я забыл про это.
>Глубокое копирование
>Тут те же замечания, что и к предыдущей задаче.
https://jsfiddle.net/b0a7tk75/3/
>Электросеть
https://jsfiddle.net/6591a2sL/7/
>> Если что, я не согласен с вашим замечанием - потому что мне не нужно было давать ссылку на Сеть, только передать уже посчитанный баланс. Можно было считать Сеть за контроллер, а ЛЭП за модель которая содержит вспомогательные методы расчета. А теперь в эти методы нужно передавать ссылку на ЛЭП. Мне из-за этого кажется что я понял и сделал всё ещё более худшим образом.
>Я уже не очень понимаю, о чем речь. Тот метод, что используется сейчас, вполне подходит. Если хочется обсудить другой вариант, то хорошо бы увидеть хотя бы кусочек кода.
Было:
function ElectricalNetwork(...) {
...
}
function PowerLine(..., price) {
...
this.price = price;
}
PowerLine.prototype.countPowerAfterPass= function(power) {
...
}
PowerLine.prototype.countPrice = function(power) {
...
}
Потом стало:
function ElectricalNetwork(...) {
...
}
ElectricalNetwork.prototype.countPowerAfterPass= function(linkToPowerLine, power) {
...
}
ElectricalNetwork.prototype.countPrice = function(linkToPowerLine, power) {
...
}
function PowerLine(..., price) {
...
this.price = price;
}
>> Можно я не буду эту менять? Придётся заново переосмысливать мою программу.
>По идее, ты должен стараться писать программу так, что в ней было легко разобраться. И соответственно небольшие изменения не должны вызывать сложностей и ради них не требуется всю программу переделывать, а только небольшую часть. А если все оставить как есть - может ты и дальше будешь писать цикл там, где он не требуется.
На самом деле, сейчас я припоминаю, что сначала я пытался решить через min()\max(), но у меня что-то не получалось и я решил написать счетчик через цикл, как и должно быть работают счетчики в реальном мире.
>Определение типа переменной
https://jsfiddle.net/5q3r473h/5/
>Напиши функцию неглубокого копирования объектов и массивов
https://jsfiddle.net/uyey3at1/6/
>> var clone = object.bind(clone);
>Тут ошибка. Во-первых, клонировать функции не требуется (да и это невозможно наверно), во-вторых, если уж клонировать, то непонятно почему надо привязывать this к пустому на тот момент значению clone. Что делает этот bind?
Я пытался получить новую функцию из старой.
>> Включая примитивные значения, которые на самом деле тоже объекты?
>Это не так. Почитай пожалуйста еще раз про боксинг, например в моих заданиях по JS ( https://gist.github.com/codedokode/ce30e7a036f18f416ae0#Боксинг ) или в других статьях: http://www.jisaacks.com/javascript-boxing/
>
>Примитивные значения - это не объекты, но если пытаться их использовать как объекты (обращаться к свойствам или методам), для них автоматически создается временный объект, в который заворачивается примитивное значение.
Ах да точно, я забыл про это.
>Глубокое копирование
>Тут те же замечания, что и к предыдущей задаче.
https://jsfiddle.net/b0a7tk75/3/
Весь код: https://jsfiddle.net/ex16zd7h/
>«(function($){…})(jQuery) » создает анонимную функцию, и тут же
>вызывает ее, передавая в качестве параметра объект jQuery, таким
>образом внутри анонимной функции мы можем использовать алиас $
>не боясь за конфликты с другими библиотеками — так как теперь $
>находится лишь в области видимости нашей функции, и мы имеем
>полный контроль над ней.
Как её правильно вынести в отдельный файл?
Ты же в начале своё барахло запускать пытаешься?
https://learn.jquery.com/using-jquery-core/document-ready/
Или запускай его в конце, когда весь документ уже создан.
Не понял тебя. По ссылке правила для $( document ).ready(), но у меня скрипт должен срабатывать не после загрузки страницы, а при клике по ссылке. JS-файл загружается в head самым последним. А код, который хочу перенести из html-файла, в js-файле вставляю тоже в самый низ.
Браузер выполняет твой html (именно html, не js) сверху вниз. Когда ты подрубаешь свой js файл через тег <script> у тебя в доме находятся только те теги которые выше него в html файле. В твоём коде за авторством Тимура эвент вешается на ссылку через $('.submit.button').click но видимо в этот момент дом пуст, там еще нет этой ссылки. Твои варианты:
1) дерунть код в конце html файла руками через чет типа <script>init();</script>
2) дернуть код через $(document).ready
3) использовать $().live или $().on или как он блять сейчас в этой параше называется чтобы вешать эвенты на те элементы, которых еще нет в доме.
>2) дернуть код через $(document).ready
То есть, обернуть js-код в эту обёртку? Спасибо, попробую.
Спасибо, получилось.
Бамп
Ячейку в таблице student назвать avatar.
Затем функционал по загрузке изображения - экшн actionSetAvatar(), там метод по загрузке изображения, проверке-валидации, затем убрать прежний аватар, если есть, а потом сохранить и отрендерить.
Что-то такое, наверное.
А, да: при этом в ячейке avatar сохранять кодированное имя изображения - md5 какой-нибудь. Чтобы у всех студентовских аватарок было своё имя, уникальное.
Довольно много всего нужно, конечно.
data:
{
data1:data1,
data2:data2,
},
Не работает. Хотя в другом скрипте работает.
>Как я должен выбрать именно то число которое выпало?
Наверное, ты имеешь в виду:
$selector = mt_rand (0, 999) % 1000;
Где тысяча — количество элементов в массиве (это я так написал, чтобы понятно было).
не, смотри. я думал об этом. У меня условие, что надо выбрать 4 элемента из массива, и указать их индекс. Как узнать индексы рандомом я понимаю, как вывести тоже, но как узнать то, что записано в эти индексы и вывести это? Вот это я не понимаю.
Ты читал мануал? array_rand выбирает случайный элемент из массива и возвращает его ключ (в твоем случае это скорее всего будет число, так как ты при создании массива не указал ключи явно, то PHP просто присвоил им порядковые номера). Проверить что именно в переменной, можно командой echo или var_dump.
А теперь открой урок про массивы и поищи, как имея массив и ключ элемента, получить значение этого элемента? Это и будет искомый слог. Если не найдешь, напиши, я или кто-то еще напишет правильный ответ.
Ты смотри, мелкобуквенный пидр заговорил по-человечески!
Выше тебе уже объяснили всё и не раз.
>>968782
За 4 дня ты не смог дойти до того, что $randomText = $letter[$random]?
Объяснил же тебе выше всё.
Делай вар_дампы постоянно, пробуй, тыкайся, уточняй ответы анонов, хули ж ты.
чувствую себя парнем с пика. Пиздец просто. Я тупо ставил () перед [] и из за этого нихуя не работало, ибо в гайде такой синтаксис был. Вот я еблан
Я посмотрел, на самом деле я еблан, но все же в разделе Повторим в массивах, нету Того как выводить определенный элемент зная его индекс. и там только в обучалке написан пример с echo 'Lalala {$weather[0]} , а я не заметил что там { и ставил(.
А, фигурные скобки они нужны для отделения выражения от остальной части строки (которая просто выводится как есть). Подробнее в мануале: http://php.net/manual/ru/language.types.string.php#language.types.string.parsing
https://kettlenyc.com/
https://3v4l.org/WDC9X
Код страницы открывать не пробовал? Стоит сразу в body:
-webkit-transition: background-color 0.5s ease-out,fill 0.5s ease-out;
transition: background-color 0.5s ease-out,fill 0.5s ease-out;
background-color: #fffb93;
background-color меняется через добавление класса с другим background-color через js, плавность через transition
Спасибо, добрый анон, я попробую.
Что такое бандл? Это просто часть проекта? Нормально ли создавать бандл без контроллеров и вьюшек чисто для хранения бизнес-логики, чтобы использовать этот бандл в других бандлах? Можно ли настроить роутинг так, чтобы в зависимости от субдомена использовался определенный бандл? Можно ли создать бандл чисто для отдельной части сайта? Например для всех путей сайта бандл MainBundle, а для http://site.com/api использовался ApiBundle?
Бандл это компонент сайта, который можно повторно использовать. Что-то вроде сторонних библиотек, которые подключаются через композер, с той разницей, что бандл может вносить изменения в конфиги проекта, например, добавлять свои роуты или ключи конфига.
http://symfony.com/doc/current/bundles.html
Бандл может предоставлять:
- сервисы в контейнере
- роуты
- контроллеры
- сущности доктрины
- шаблоны
- статические файлы
Бандл это что-то повторно используемое. Ну например, бандл форума, который можно прикрутить к любому проекту. Или бандл, добавляющий новые виджеты для форм.
В качестве примеров можно посмотреть бандлы в составе симфони или сторонние бандлы.
Бандлы в большинстве случаев самодостаточны и друг от друга не зависят.
Если ты делаешь приложение то скорее всего тебе бандлы не нужны и хватит одного AppBundle. Некоторые пишут, что можно даже без него, не оформлять код сайта в виде бандла.
> Можно ли создать бандл чисто для отдельной части сайта? Например для всех путей сайта бандл MainBundle, а для http://site.com/api использовался ApiBundle?
Можно
> Можно ли настроить роутинг так, чтобы в зависимости от субдомена использовался определенный бандл?
Можно, но не автоматически, а вручную прописать в разные роуты контроллеры из разных бандлов
Бандл это компонент сайта, который можно повторно использовать. Что-то вроде сторонних библиотек, которые подключаются через композер, с той разницей, что бандл может вносить изменения в конфиги проекта, например, добавлять свои роуты или ключи конфига.
http://symfony.com/doc/current/bundles.html
Бандл может предоставлять:
- сервисы в контейнере
- роуты
- контроллеры
- сущности доктрины
- шаблоны
- статические файлы
Бандл это что-то повторно используемое. Ну например, бандл форума, который можно прикрутить к любому проекту. Или бандл, добавляющий новые виджеты для форм.
В качестве примеров можно посмотреть бандлы в составе симфони или сторонние бандлы.
Бандлы в большинстве случаев самодостаточны и друг от друга не зависят.
Если ты делаешь приложение то скорее всего тебе бандлы не нужны и хватит одного AppBundle. Некоторые пишут, что можно даже без него, не оформлять код сайта в виде бандла.
> Можно ли создать бандл чисто для отдельной части сайта? Например для всех путей сайта бандл MainBundle, а для http://site.com/api использовался ApiBundle?
Можно
> Можно ли настроить роутинг так, чтобы в зависимости от субдомена использовался определенный бандл?
Можно, но не автоматически, а вручную прописать в разные роуты контроллеры из разных бандлов
Любой фреймворк бери, разбирайся и делай на нём, это же не возбраняется.
Или ты прямо с нуля хочешь?
<form enctype="multipart/form-data" action="photos.php" method="POST">
<input name="filename" type="file" />
<input type="submit" value="Send File" />
</form>
Хочется передать переменную $get вместе с изображением, но я не знаю как. Как сделать так, чтобы эта форма передавала и переменную и изображение?
Поясните за source страницы. Почему в инспекторе я вижу нормальные значения, а когда захожу в код или беру dom скриптом, то некоторых значений нет? Как мне распарсить dom уже с финальными значениями из инспектора?
l33tspeak
Если ты когда-нибудь видел хакеров (например, в кино или в интернете), то знаешь, что у них есть свой, особый язык, который позволяет отличать своих от чужих. Он называется l33tspeak, и объяснен в википедии: http://en.wikipedia.org/wiki/Leet (как видишь, википедисты обладают элитными знаниями).
Чем мы хуже хакеров? Давай напишем программу для перевода текста на элитный язык. Опять же, воспользуемся массивом перекодировки и функцией strtr
Задачка: доделай программу по ссылке http://codepad.org/5XEkSKHI для перевода текста на l33tspeak. Покажи нам результат.
я только начинаю изучать и это задача на самом начале изучения строк. я просто не понимаю в чем заключается вопрос, что не так работает в программе?
а, так это правда очень легко.
Чтоб бабаос с лохов рубить, очевидно же.
Ну он не понимает просто пока ничего, и ему отправная точка нужна и цель какая-то. В общем что бы можно было проложить маршрут. Причем не длинный, а по конкретным ключевым точкам. Ну тип вроде как пришел на собеседование. А там:какие паттерны вы знаете? И ты такой ну вот эти 10 знаю, и рассказал. И на тебя уже как на человека смотрят. Хочется вот так же что бы было. А то, что на самом деле это за вечер "учится", никого не ебет.
А не дрочишься 2 года такой в разработке. А у тебя всё на сингтоне и норм. А на собеседовании ты такой, ну тип синглтон. А они такие: и что, всё? Ну вы знаете, мы вам перезвоним.
При просмотре страницы прогресс-бар внизу увеличивается, показывая, сколько ещё осталось.
Тут анон ещё спрашивал об эизменениия фона при скролле 0 в ту же тему.
Чтобы я мог уже не столько учить новые команды, сколько мог уже улучшать понимание изученных. То есть тот уровень, при котором основами я владею хорошо.
echo "<img src='/images/".$id.".jpg'>"
Все нормально вывелось. Затем, если заменить это изображение в папке другим изображением с таким же именем, то на сайте все равно остается старое изображение, хотя в папке новое.
А, все, чет не работало не работало, а потом стало работать. Странно.
Какие книжечки читали по нем ?или прочее
>Notice: Trying to get property of non-object on line 16
Помоги анон.
Foreach + массив - могу
Foreach + объекты - могу
For + массив - могу
For + объекты - не врубаюсь как
Ох, спасибо. Я уже и методом тыка кучу вариантов перебрал... Не нашёл примеров.
Кстати, пишут, что ++$i вроде как работает быстрей.
Я попробовал, визуально ничего не изменилось.
Стоит ли использовать в этом примере?
меньше недели учу php, извиняйте
Не быстрее, это просто пре-инкремент, когда сначала происходит математическая операция, а затем возвращается значение. А $i++ это пост-инкремент, сначала возвращается значение, а потом происходит математическая операция. В этом >>970087 коде если поменять $i++ на ++$i, то код выведет все элементы массива начиная с индекса 1, пропустив при этом 0 (самый первый).
Это так же имеет отношение к декременту, подробнее можешь тут почитать
http://php.net/manual/en/language.operators.increment.php
Как сделать?
Бамп
>за что там могут платить
За вредность.
>Ты вот тянешь для разработки html/css/js + php, паттерны там какие то учишь, фремворки, а можно просто делать сайтики на wp?
Ты всю свою карьеру собираешься сайтики на WP разрабатывать?
Советую не тратить на это время, потому что заебет не через год, так через три.
А приобретенные за это время навыки и практики тебе нигде не пригодятся, или чего хуже только навредят.
WP, друпал и прочие джумлы это тупик. Если хочешь быть разработчиком, а не администратором CMS, начни с изучения основ.
>senior wordpress developer
Петушара это зашкваренный. Ни один серьезный разраб не будет такое про себя писать.
>Я с wp не работал, но за что там могут платить?
Говносайтов туча на нем, заказчиков много. Паттерны-фреймворки там не нужны, достаточно доку по вордпрессу прочитать. Платят мало, ибо скиллов особо не требуется.
Может кто скинет годный урок по созданию первого простенького сайта с подключением БД и какими-то действами в php? Хотя бы понять алгоритм действий и увидеть как это всё строится.
>Может кто скинет годный урок
Я сам недавно вникал в это, нашёл такое:
http://phpfaq.ru/pdo
Попробуй, мне нормально зашло.
Вообще, если ты читал урок по MVC, то можно для начала сделать как там, без базы данных, просто пример данных в коде записать. А позже добавить работу с базой данных.
Senior Microsoft Word VBA Scripts Developer
зы. Задачку на рекурсию про "Ханойскую башню" с другого сайта решил за пару минут, не заглядывая в подсказки (просто почитав, что такое вообще рекурсия), а эта что-то вообще не зашла, но очень заинтересовала. Что курить для её решения своими силами?
Автоподключение и pdo это не фреймворки, а часть php же, в любой книге по php их проходят. Фреймворки это когда symphony какой-нибудь натягиваешь.
Норм все. Я когда начинал, тоже всякое такое примитивное осилить не мог неделями, щас достаточно сложные проекты пилю. Мозги раскачиваются постепенно на программирование, сразу ничего не бывает. Просто пробуй дальше каждый день, потом легче пойдет.
>тоже всякое такое примитивное
>всякое такое примитивное
>такое примитивное
>примитивное
>алгоритм дейкстры-хуекстры
я не могу банкомат решить на не жадном алгоритме, так что ты даже умнее меня
Никто не может вообще-то из присутсвующих.
За 2 дня была успешно сделана система постинга без картинок картинки постараюсь сделать завтра если не буду сильно занят
Мне интересно, насколько некорректно делать отображение как я сделал ? с использованием хтмл тегов в пхп коде
Посоветуйте как прикрутить по больше функционала и сделать код красивее.
нихуя, тут были гайды всё это время, пошёл читать, раз такое дело просто оцените моё говно по степени говняности \10, где-то 7-10 часов моего старания вот.
а ещё вопрос, насколько предпочтительнее ООП нежели его не использование.
Слишком много писать, по этому все собрали воедину и запилили одним гуидом.
Сразу же в начале куча не известных мне слов. Объяснятся очевидно для тех кто уже работать с БД.
>- во-вторых, потому что исключение всегда содержит в себе незаменимый stack trace,
- в-третьих - исключения чрезвычайно удобно обрабатывать.
Плюс очень удобно задать FETCH_MODE по умолчанию, чтобы не писать его в КАЖДОМ запросе, как это очень любят делать прилежные хомячки.
Также здесь можно задавать режим pconnect-а, эмуляции подготовленных выражений и много других страшных слов.
Вот абсолютно ничего не понятно.
С объектами проще управляться в крупном проекте.
Представь, у тебя куча функций простых, которые явно никак друг с другом не связаны, замучаешься разбираться.
А представь класс, у которого всё определено в свойствах и методах, методы (те же функции) относятся только к этому классу (не обязательно, можно статические методы, которые будут работать независимо), всё удобно и понятно.
Понял, что без PDO уже нихуя не сделать, дайте по нему нормальный гайд для даунов, потому что въехать в prepare и execute просто не возможно, на php-manuale как обычно хуйня написана без пояснений.
Хочу сделать блог с курсами: от сих до сих изучаешь что-нибудь, после чего можешь считать себя тем-то тем-то.
Курсы там будут по Photoshop, PHPStorm, по Yii2 уже почти готов, ну вот и хочу сделать по РНР, скопировав структуру, задачи (но там и куча других будет разных, а многих сложных и не будет - из "дополнительных").
Сам текст я переработаю, но вот структуру могу ли взять, формулировку задач?
Часть у тебя, часть у Робина Никсона, там тоже толково многое и понятно.
Аноны так-то возмутятся всё равно, наверное.
А что ты подразумеваешь под структурой? Если ты используешь такие же темы уроков, но тексты сам напишешь, то это будет твое самостоятельное произведение, и тут даже мое разрешение не нужно.
Насчет задач - я в общем-то не против, бери безо всякий условий (я их все равно хочу переделать как-нибудь), но советую добавить пояснения, как их решать, примеры правильных ответов, а то как видно из треда, люди часто путаются.
Тексты/картинки копировать целиком не советую, хотя бы потому что поисковые системы увидят плагиат и пессимизируют твой сайт и его никто не найдет.
Вообще, я давно собирался опубликовать тексты и картинки под какой-нибудь открытой лицензией creative commons (но пока не выбрал, под какой), но в этом случае там свои подвохи - надо указывать автора и надо публиковать свой текст под аналогичной лицензией. Если ты на такое готов в будущем (когда я выберу лицензию), то можешь копировать. Нет - пиши сам.
https://github.com/someApprentice/maintaskforlayout/ >>919288
https://github.com/someApprentice/Students/ >>926219
https://github.com/sylenien/php-news-site/ >>927983
https://github.com/grigoryMovchan/zuihitsu >>932473
https://github.com/anotherCodeMunkey/fileshare >>938323
Если я еще кого-то пропустил, напомните о себе.
Так и задумано. В браузере для некоторых тегов прописаны правила CSS по умолчанию. Например, для заголовков задан увеличенный жирный шрифт, для абзацев - вертикальные отступы сверху и снизу, а для body или html - задан margin, чтобы текст на странице по умолчанию не прилипал к краям окна браузера. В книгах тоже ведь поля делают.
Если тебя это не устраивает, просто задай свои значения через CSS.
Не используй CSS reset, так как он отменяет много полезных вещей (те же отступы между абзацами, отступы в списках).
>>971682
Я обычно использую такие термины:
- margin: отступ
- padding: поля
Так как padding - это поля внутри элемента (как поля на странице книги), а margin - это отступы между соседними элементами (хотя в английском да, поля на странице называют page margins).
>>971643
Тут тебе бы лучше не копировать готовый код из учебника, где специально вставлена ошибка, а попробовать написать самому. Логика должна быть примерно такая:
- прибавляем проценты и комиссию к остатку долга (!не вычитаем ничего пока!)
- если остаток маленький, выплачиваем сколько осталось и уходим
- иначе платим 5000
«Платим» здесь значит уменьшаем долг и увеличиваем общую сумму выплаченного.
Код в учебнике явно неправильный, так как он вычитает 5000 даже если там осталось 1000 долга, он все равно пытается вычесть 5000 и уходит в минус.
>>971513
ООП нужен для двух целей:
1) класс объектов сочетает в себе свойства (что-то вроде переменных) и методы для работы с ними (что-то вроде функций). Многие вещи из реального мира хорошо описываются именно в виде объектов. Ну например, мы можем сделать класс Компания, у которого будут свойства "название", "список работников", "прибыль" и методы "нанять работника", "уволить работника".
Без объектов получается менее удобно - мы должны отдельно где-то хранить информацию о компании и отдельно функции для работы с ними. Удобнее, когда это собрано в одном классе с помощью ООП.
2) классы используют для организации кода, когда его много. Чтобы разбить код на N классов, каждый из которых отвечает за свою область, умеет решать одну задачу. Вообще, ООП тут не единственное решение, можно например разбивать код на модули (этого нет в PHP, но есть в других языках)
ООП описан в учебнике из ОП поста, в последней главе, подробно, и даны задачи для закрепления знаний.
Если ты хочешь работать программистом, то без знания ООП шансов мало. Везде он нужен. Фреймворки без него тоже не понять.
>>971546
Урок по исключениям, лучше изучать после ООП: https://github.com/codedokode/pasta/blob/master/php/exceptions.md
Так и задумано. В браузере для некоторых тегов прописаны правила CSS по умолчанию. Например, для заголовков задан увеличенный жирный шрифт, для абзацев - вертикальные отступы сверху и снизу, а для body или html - задан margin, чтобы текст на странице по умолчанию не прилипал к краям окна браузера. В книгах тоже ведь поля делают.
Если тебя это не устраивает, просто задай свои значения через CSS.
Не используй CSS reset, так как он отменяет много полезных вещей (те же отступы между абзацами, отступы в списках).
>>971682
Я обычно использую такие термины:
- margin: отступ
- padding: поля
Так как padding - это поля внутри элемента (как поля на странице книги), а margin - это отступы между соседними элементами (хотя в английском да, поля на странице называют page margins).
>>971643
Тут тебе бы лучше не копировать готовый код из учебника, где специально вставлена ошибка, а попробовать написать самому. Логика должна быть примерно такая:
- прибавляем проценты и комиссию к остатку долга (!не вычитаем ничего пока!)
- если остаток маленький, выплачиваем сколько осталось и уходим
- иначе платим 5000
«Платим» здесь значит уменьшаем долг и увеличиваем общую сумму выплаченного.
Код в учебнике явно неправильный, так как он вычитает 5000 даже если там осталось 1000 долга, он все равно пытается вычесть 5000 и уходит в минус.
>>971513
ООП нужен для двух целей:
1) класс объектов сочетает в себе свойства (что-то вроде переменных) и методы для работы с ними (что-то вроде функций). Многие вещи из реального мира хорошо описываются именно в виде объектов. Ну например, мы можем сделать класс Компания, у которого будут свойства "название", "список работников", "прибыль" и методы "нанять работника", "уволить работника".
Без объектов получается менее удобно - мы должны отдельно где-то хранить информацию о компании и отдельно функции для работы с ними. Удобнее, когда это собрано в одном классе с помощью ООП.
2) классы используют для организации кода, когда его много. Чтобы разбить код на N классов, каждый из которых отвечает за свою область, умеет решать одну задачу. Вообще, ООП тут не единственное решение, можно например разбивать код на модули (этого нет в PHP, но есть в других языках)
ООП описан в учебнике из ОП поста, в последней главе, подробно, и даны задачи для закрепления знаний.
Если ты хочешь работать программистом, то без знания ООП шансов мало. Везде он нужен. Фреймворки без него тоже не понять.
>>971546
Урок по исключениям, лучше изучать после ООП: https://github.com/codedokode/pasta/blob/master/php/exceptions.md
Функции mysql.. устарели. Я бы советовал сразу переходить на PDO. Но там надо знать ООП.
Далее, у тебя еще есть такая проблема. Начинающие, когда пишут свои первые программы, просто пишут команды подряд, не разбивая код на части. Пока программы маленькие, это приемлемо. Но веб-приложения сложнее и больше и тут такой подход плохо работает. Надо отучаться писать стены кода и надо приучаться разбивать его на части, на отдельные функции. Разделять логику и HTML-шаблоны. Для этого можно почитать мой урок по MVC https://github.com/codedokode/pasta/blob/master/arch/mvc.md
Далее, у тебя банально идет незнание синтаксиса PHP. Нельзя писать $array[x], надо $array['x']. PHP должен выдавать ошибку, просто у тебя наверно отключен display_errors и ты их не видишь. Тебе надо перечитать мануал PHP внимательно.
Дальше, у тебя там скорее всего могут быть уязвимости. Мне лень тут все объяснять, предлагаю взять задание про студентов из ОП поста и прочесть там все комментарии, там все подробно расписано и большинство из написанного относится и к твоей задаче.
А пока у тебя просто не хватает знаний, код очень низкокачественный, ты пытаешься борду написать в том стиле, в котором начинающие пишут простые скрипты на 20 строчек.
Ну и HTML/CSS тоже надо подучить - <br> в HTML пишется без слеша в конце. Это не XHTML.
Советую изучить ООП, потом читать задачу про студентов.
>>971336
Ну там логика примерно такая: берем старшую купюру, считаем, сколько их надо выдать, берем купюру поменьше, считаем и так до самой младшей.
>>971171
А ты читал описание алгоритма Дейкстры? И вообще, про алгоритмы поиска пути? В Википедии есть список. Надо просто реализовать Дейкстру или любой другой алгоритм поиска пути на PHP. Вообще, алгоритмов много, есть например А-star и другие. В играх например они часто нужны.
>>970784
Еще добавлю, что по автозагрузке классов у меня есть отдельный урок https://github.com/codedokode/pasta/blob/master/php/autoload.md
Функции mysql.. устарели. Я бы советовал сразу переходить на PDO. Но там надо знать ООП.
Далее, у тебя еще есть такая проблема. Начинающие, когда пишут свои первые программы, просто пишут команды подряд, не разбивая код на части. Пока программы маленькие, это приемлемо. Но веб-приложения сложнее и больше и тут такой подход плохо работает. Надо отучаться писать стены кода и надо приучаться разбивать его на части, на отдельные функции. Разделять логику и HTML-шаблоны. Для этого можно почитать мой урок по MVC https://github.com/codedokode/pasta/blob/master/arch/mvc.md
Далее, у тебя банально идет незнание синтаксиса PHP. Нельзя писать $array[x], надо $array['x']. PHP должен выдавать ошибку, просто у тебя наверно отключен display_errors и ты их не видишь. Тебе надо перечитать мануал PHP внимательно.
Дальше, у тебя там скорее всего могут быть уязвимости. Мне лень тут все объяснять, предлагаю взять задание про студентов из ОП поста и прочесть там все комментарии, там все подробно расписано и большинство из написанного относится и к твоей задаче.
А пока у тебя просто не хватает знаний, код очень низкокачественный, ты пытаешься борду написать в том стиле, в котором начинающие пишут простые скрипты на 20 строчек.
Ну и HTML/CSS тоже надо подучить - <br> в HTML пишется без слеша в конце. Это не XHTML.
Советую изучить ООП, потом читать задачу про студентов.
>>971336
Ну там логика примерно такая: берем старшую купюру, считаем, сколько их надо выдать, берем купюру поменьше, считаем и так до самой младшей.
>>971171
А ты читал описание алгоритма Дейкстры? И вообще, про алгоритмы поиска пути? В Википедии есть список. Надо просто реализовать Дейкстру или любой другой алгоритм поиска пути на PHP. Вообще, алгоритмов много, есть например А-star и другие. В играх например они часто нужны.
>>970784
Еще добавлю, что по автозагрузке классов у меня есть отдельный урок https://github.com/codedokode/pasta/blob/master/php/autoload.md
Установка плагинов, верстка, натягивание верстки, написание своих тем и плагинов. Я бы не советовал, это чуть лучше просто верстальщика.
>>970242
Изучи расширение gd к PHP, там есть функция imagecopyresampled для изменения размера картинки. Обычно пользователь загружает картинку, из нее делают 1 или несколько уменьшенных и далее выводят на сайте. Дополнительно иногда еще используют CSS, если размеры картинки должны как-то адаптироваться под размеры экрана.
>>970121
> Кстати, пишут, что ++$i вроде как работает быстрей.
А ты померяй.
>>970087
Прочитай мануал по json_decode. Он умеет выдавать массив, а не пародию на объект. Там по задумке по умолчанию для словарей JS создается объект класа stdClass в PHP, но на практике это не имеет особого смысла, лучше массив.
>>969877
В браузере есть кеш откуда он и взял старую картинку. Надо жать Ctrl + F5 по моему, чтобы заставить его принудиительно использовать картинку с сайта. Можешь почитать подробнее про кеширование в HTTP, но надо понимать протокол HTTP.
Также, советую не формировать ссылку прямо в HTML, а сделать функцию, которая генерирует ссылку на картинку.
>>969566
Если ты хочешь работать PHP-разработчиком, то от тебя потребуется писать и поддерживать веб-прилоежния, скорее всего на фреймворке, с использованием ООП и MVC, работать с SQL базой данных, писать скрипты на JS.
>>969499
Первая и вторая строка формируются одинаково, можно было использовать цикл из 2 шагов. Также, можно убрать промежуточные переменные $w1-$w8
Установка плагинов, верстка, натягивание верстки, написание своих тем и плагинов. Я бы не советовал, это чуть лучше просто верстальщика.
>>970242
Изучи расширение gd к PHP, там есть функция imagecopyresampled для изменения размера картинки. Обычно пользователь загружает картинку, из нее делают 1 или несколько уменьшенных и далее выводят на сайте. Дополнительно иногда еще используют CSS, если размеры картинки должны как-то адаптироваться под размеры экрана.
>>970121
> Кстати, пишут, что ++$i вроде как работает быстрей.
А ты померяй.
>>970087
Прочитай мануал по json_decode. Он умеет выдавать массив, а не пародию на объект. Там по задумке по умолчанию для словарей JS создается объект класа stdClass в PHP, но на практике это не имеет особого смысла, лучше массив.
>>969877
В браузере есть кеш откуда он и взял старую картинку. Надо жать Ctrl + F5 по моему, чтобы заставить его принудиительно использовать картинку с сайта. Можешь почитать подробнее про кеширование в HTTP, но надо понимать протокол HTTP.
Также, советую не формировать ссылку прямо в HTML, а сделать функцию, которая генерирует ссылку на картинку.
>>969566
Если ты хочешь работать PHP-разработчиком, то от тебя потребуется писать и поддерживать веб-прилоежния, скорее всего на фреймворке, с использованием ООП и MVC, работать с SQL базой данных, писать скрипты на JS.
>>969499
Первая и вторая строка формируются одинаково, можно было использовать цикл из 2 шагов. Также, можно убрать промежуточные переменные $w1-$w8
Нужно кириллические буквы заменить на другие похожие на них символы.
>>969462
На странице могут быть программы на языке Яваскрипт, которые изменяют DOM в процессе работы. Также, если исходный код содержит ошибочный HTML код, то он не попадет в DOM или будет исправлен браузером. view-source показывает тот код, который пришел с сервера.
Получить текущий DOM можно так в хромоподобных браузерах: открыть отладчик в браузере (Ctrl + Shift + I) и набрать команды:
var html = document.documentElement.outerHTML;
copy(html);
Текущий HTML-код страницы будет скопирован в буфер обмена.
Насчет ФФ не знаю, может сработает, может нет, надо проверять.
>>969451
Можно освоить фронтенд, задания по HTML/CSS/JS ждут тебя в ОП-посте. И тогда половинка тебе не понадобится.
>>969450
Изучи HTML формы. Там есть возможность добавлять скрытые поля в форму.
>>968998
Ты создаешь локальную переименную Super, которая видна только внутри той маленькой функции и никак не видна снаружи нее. Лучше в момент вызова функции копировать ее название и прототип предка в глобальные переменные. А mySuper будет использовать эти переменные:
mySuper.currentParentFunction = Object.getPrototypeOf(object)[name];
Также, ты вызываешь this() не передавая родительской функции правильный контекст (она будет вызвана не на объекте, а с this = window).
Но тут есть еще один подвох: что, если функция, вызванная через super(), вызовет super() еще раз? Поясню кодом:
Есть классы Parent extends Grandparent, Child extends Parent:
addMethod(Child.prototype, 'test', function () {
console.log('in Child');
var a = super(1, 2);
var b = super(3, 4);
return a + b;
});
addMethod(Parent.prototype, 'test', function (x, y) {
console.log('in Parent');
return super() + x + super() + y;
});
addMethod(Grandparent.prototype, 'test', function() {
console.log('in Grandparent');
return 100;
});
var child = new Child;
console.log(child.test()); // 410 если не ошибаюсь
Тут при исплоьзовании глобальных переменных они затрут друг друга и будет ошибка. Предлагаю подумать над решением этой проблемы.
Вместо __proto__ я советую использовать стандартный getPrototypeOf из ES5.
Также, есть еще одна оптимизация. Добавление обертки над методом делает его немного медленнее. Некоторые JS движки позволяют получить код функции в виде строки и проверить, есть ли там вызов super(). Если нет - можно не добавлять обертку. Так делает например бибилиотека classy. Хотя тут есть свой подвох: можно сохранить ссылку на super в другую переменную и вызывать через нее.
Ты можешь потом, если хочешь, посмотреть, как проблему решили авторы библиотек:
- classy: https://github.com/mitsuhiko/classy/
- наследование от John Resig: http://ejohn.org/blog/simple-javascript-inheritance/
- klass: https://github.com/ded/klass
Сейчас эти библиотеки отмирают потхоньку, так как в JS в ES6 (?) появился синтаксис для классов.
Нужно кириллические буквы заменить на другие похожие на них символы.
>>969462
На странице могут быть программы на языке Яваскрипт, которые изменяют DOM в процессе работы. Также, если исходный код содержит ошибочный HTML код, то он не попадет в DOM или будет исправлен браузером. view-source показывает тот код, который пришел с сервера.
Получить текущий DOM можно так в хромоподобных браузерах: открыть отладчик в браузере (Ctrl + Shift + I) и набрать команды:
var html = document.documentElement.outerHTML;
copy(html);
Текущий HTML-код страницы будет скопирован в буфер обмена.
Насчет ФФ не знаю, может сработает, может нет, надо проверять.
>>969451
Можно освоить фронтенд, задания по HTML/CSS/JS ждут тебя в ОП-посте. И тогда половинка тебе не понадобится.
>>969450
Изучи HTML формы. Там есть возможность добавлять скрытые поля в форму.
>>968998
Ты создаешь локальную переименную Super, которая видна только внутри той маленькой функции и никак не видна снаружи нее. Лучше в момент вызова функции копировать ее название и прототип предка в глобальные переменные. А mySuper будет использовать эти переменные:
mySuper.currentParentFunction = Object.getPrototypeOf(object)[name];
Также, ты вызываешь this() не передавая родительской функции правильный контекст (она будет вызвана не на объекте, а с this = window).
Но тут есть еще один подвох: что, если функция, вызванная через super(), вызовет super() еще раз? Поясню кодом:
Есть классы Parent extends Grandparent, Child extends Parent:
addMethod(Child.prototype, 'test', function () {
console.log('in Child');
var a = super(1, 2);
var b = super(3, 4);
return a + b;
});
addMethod(Parent.prototype, 'test', function (x, y) {
console.log('in Parent');
return super() + x + super() + y;
});
addMethod(Grandparent.prototype, 'test', function() {
console.log('in Grandparent');
return 100;
});
var child = new Child;
console.log(child.test()); // 410 если не ошибаюсь
Тут при исплоьзовании глобальных переменных они затрут друг друга и будет ошибка. Предлагаю подумать над решением этой проблемы.
Вместо __proto__ я советую использовать стандартный getPrototypeOf из ES5.
Также, есть еще одна оптимизация. Добавление обертки над методом делает его немного медленнее. Некоторые JS движки позволяют получить код функции в виде строки и проверить, есть ли там вызов super(). Если нет - можно не добавлять обертку. Так делает например бибилиотека classy. Хотя тут есть свой подвох: можно сохранить ссылку на super в другую переменную и вызывать через нее.
Ты можешь потом, если хочешь, посмотреть, как проблему решили авторы библиотек:
- classy: https://github.com/mitsuhiko/classy/
- наследование от John Resig: http://ejohn.org/blog/simple-javascript-inheritance/
- klass: https://github.com/ded/klass
Сейчас эти библиотеки отмирают потхоньку, так как в JS в ES6 (?) появился синтаксис для классов.
> if ($i <= $quantity){
> }else {
Тут можно избавиться от if используя конструкцию: число купюр = наименьшее из (результат деления), (число купюр в банкомате).
Работает верно.
>>968669
Во-первых, оборачивать все в функцию не требуется. Никаких конфликтов там не будет, если ты только не пытаешься подключить несколько версий джейквери на страницу.
Во-вторых, как тебе написали ниже, DOM создается не мгновенно, а постепенно, по мере разбора документа. Если ты подключаешь свой скрипт в head, то в этот момент body еще не создано и поля с файлом нет, и повесить на него событие не получится.
Тебе там советуют использовать событие ready, но я дам другой совет. Помести во внешний файл функцию вроде function initFileUpload, а в HTML-коде под формой с файлом вставь ее вызов. Тогда она вызовется уже после того как форма появится в DOM.
А с ready надо ждать пока страница загрузится целком, это значит что событе будет навешено позже, может даже уже после того как пользователь что-то сделает на странце.
>>968673
Лучше не ready, а поместить вызов инициализации сразу после формы. Так она раньше иницииализируется, а в твоем случае достаточно одного долго грузяющегося скрипта чтобы ready задержалось.
Электросеть
> PowerLine.prototype.countPowerAfterPass= function(power) {
Вот в этом варианте мне не нравится то, что мы должны вызывать Powerline чтобы просто вычесть 2 числа. И там ведь не может быть других вариантов, что остаток непереданной энергии вычисляется как-то по другому. То есть мне не очень нравится идея делегировать эту операцию вычистания в PowerLine.
Мне больше нравится вариант, когда мы запрашиваем у PowerLine, сколько она может передать энергии и сколько это стоит, а потом сами решаем, что делать, сколько мы передадим. Но каких-то рациональных объяснений я дать не могу, мне так просто больше нравится.
> и я решил написать счетчик через цикл, как и должно быть работают счетчики в реальном мире.
Ну а моделировать работу счетчика можно и делением.
> function House(apartments = 0) {
Тут интересное значение по умолчанию, видимо бывают жилые дома без квартир? Мне кажется, что с точки зрения логики тут не должно быть значения по умолчанию, число квартир обязательно надо указывать.
Ну и еще одно, я тут подумал, что если совсем-совсем идеально стараться делать, то правильнее всего было бы в базовом классе не делать свойств power/nightPower, а только 2 абстрактных метода getPower или getNightPower (в JS правда нет абстрактных методов, но это не моя вина). Ведь когда мы делаем свойство power, мы предполагаем что мощность - это какое-то свойство, которое сохраняет свое значение. Но в каких-то случаях она вычисляется по формуле, в House например это поле даже не заполняется, получается что в базовом классе его быть не должно. Извини, если сбил с толку противоречивыми объяснениями, просто сейчас это стало заметно в коде. Ну и это уже совсем придирки, в принципе текущий вариант меня устраивает полностью.
Определение типа переменной
> whatIsType
Имя функции начинают с глагола, getType().
А так, все верно.
Напиши функцию неглубокого копирования объектов и массивов
> Я пытался получить новую функцию из старой.
Ну да, но ты привязал не то значение this, ты привязал значение clone в качестве this, и при таком вызове:
function fn() {}
var fnCopy = clone(fn);
fnCopy.call({});
Функция fn получит другой this.
Клонировать функцию можно наверно так:
function () { return fn.apply(this, arguments); }
и потом скопировать свойства объекта, но в задаче этого все равно не требуется.
> var clone = new Date();
> clone.setTime(object.getTime());
лучше new Date(object.getTime())
Решение теперь верное.
Глубокое копирование
Ок, верно.
Электросеть
> PowerLine.prototype.countPowerAfterPass= function(power) {
Вот в этом варианте мне не нравится то, что мы должны вызывать Powerline чтобы просто вычесть 2 числа. И там ведь не может быть других вариантов, что остаток непереданной энергии вычисляется как-то по другому. То есть мне не очень нравится идея делегировать эту операцию вычистания в PowerLine.
Мне больше нравится вариант, когда мы запрашиваем у PowerLine, сколько она может передать энергии и сколько это стоит, а потом сами решаем, что делать, сколько мы передадим. Но каких-то рациональных объяснений я дать не могу, мне так просто больше нравится.
> и я решил написать счетчик через цикл, как и должно быть работают счетчики в реальном мире.
Ну а моделировать работу счетчика можно и делением.
> function House(apartments = 0) {
Тут интересное значение по умолчанию, видимо бывают жилые дома без квартир? Мне кажется, что с точки зрения логики тут не должно быть значения по умолчанию, число квартир обязательно надо указывать.
Ну и еще одно, я тут подумал, что если совсем-совсем идеально стараться делать, то правильнее всего было бы в базовом классе не делать свойств power/nightPower, а только 2 абстрактных метода getPower или getNightPower (в JS правда нет абстрактных методов, но это не моя вина). Ведь когда мы делаем свойство power, мы предполагаем что мощность - это какое-то свойство, которое сохраняет свое значение. Но в каких-то случаях она вычисляется по формуле, в House например это поле даже не заполняется, получается что в базовом классе его быть не должно. Извини, если сбил с толку противоречивыми объяснениями, просто сейчас это стало заметно в коде. Ну и это уже совсем придирки, в принципе текущий вариант меня устраивает полностью.
Определение типа переменной
> whatIsType
Имя функции начинают с глагола, getType().
А так, все верно.
Напиши функцию неглубокого копирования объектов и массивов
> Я пытался получить новую функцию из старой.
Ну да, но ты привязал не то значение this, ты привязал значение clone в качестве this, и при таком вызове:
function fn() {}
var fnCopy = clone(fn);
fnCopy.call({});
Функция fn получит другой this.
Клонировать функцию можно наверно так:
function () { return fn.apply(this, arguments); }
и потом скопировать свойства объекта, но в задаче этого все равно не требуется.
> var clone = new Date();
> clone.setTime(object.getTime());
лучше new Date(object.getTime())
Решение теперь верное.
Глубокое копирование
Ок, верно.
>reporting($op, $result, $number, $char);
Это можно было не копировать 4 раза а просто поставить перед if.
А так, верно решено.
>>968288
Нет, нельзя. Есть eval, но от него вреда больше чем пользы.
>>968256
$letters[$random] наверно?
>>968254
"найти значение элемента массива по индексу в PHP". Эти термины по моему описаны в начале урока про массивы.
>>968103
Наверно потому что сервер работает от какого-нибудь пользователя вроде SYSTEM. Ты там umask или chmod не вызывал?
>>968081
Надо делать редирект на страницу с файлом после успешной загрузки. Это назвается паттерн Post/Redirect/Get.
>>967927
Скорее всего сервер взломан. Самые популярные способы взлома:
- кто-то сохранил пароль от FTP, вирус его нашел и закачал вирус на сервер
- на сервере стоит какая-нибудь старая дырявая CMS
- кто-то упер пароль от панели управления хостингом
В простейших случаях вирус дописывает вредоносный код в HTML/PHP файлы, в более сложных - прописывается куда-нибудь в .htaccess. Лучше всего забекапить файлы, очистить папку на хостинге, проверить файлы и закачать заново. И поменять пароли.
>reporting($op, $result, $number, $char);
Это можно было не копировать 4 раза а просто поставить перед if.
А так, верно решено.
>>968288
Нет, нельзя. Есть eval, но от него вреда больше чем пользы.
>>968256
$letters[$random] наверно?
>>968254
"найти значение элемента массива по индексу в PHP". Эти термины по моему описаны в начале урока про массивы.
>>968103
Наверно потому что сервер работает от какого-нибудь пользователя вроде SYSTEM. Ты там umask или chmod не вызывал?
>>968081
Надо делать редирект на страницу с файлом после успешной загрузки. Это назвается паттерн Post/Redirect/Get.
>>967927
Скорее всего сервер взломан. Самые популярные способы взлома:
- кто-то сохранил пароль от FTP, вирус его нашел и закачал вирус на сервер
- на сервере стоит какая-нибудь старая дырявая CMS
- кто-то упер пароль от панели управления хостингом
В простейших случаях вирус дописывает вредоносный код в HTML/PHP файлы, в более сложных - прописывается куда-нибудь в .htaccess. Лучше всего забекапить файлы, очистить папку на хостинге, проверить файлы и закачать заново. И поменять пароли.
Тут ддос, крупный хостинг таким заниматься не будет.
>>967885
Может у тебя там маргины какие стоят или просто блоки слишком широкие и не помещаются? Бери отладчик в браузере и изучай.
>>967873
> Используется же для создания работников в цикле getEmpolyees.
Там переменная, а не поле. Поле в объекте не используется.
>>У тебя при наследовании надо обязательно прописать значения зарплаты, потребления кофе итд.
> Это подразумевается, когда ты создаёшь новую профессию, зачем её создавать не задав ей никаких параметров?
Это подразумывается в твоей голове, а я предлагаю заложить это ограничение в код, чтобы любому сразу было видно. Для этого и придуманы абстрактные методы - чтобы указать, что обязан задать тот, кто пишет класс-наследник.
>>971699
>>971925
А как теперь остаток минуснуть? Я вроде это прописал, но что-то не так http://ideone.com/T5CDtr
public function download(\Slim\Http\Request $request, \Slim\Http\Response $response, $args)
{
$id = $request->getAttribute('fileId');
$file = $this->container->getFilesGateaway()->getFileByID($id);
$path = '..\\' . $file->link;
$fileName = $file->realName;
if (PHP_OS == 'WINNT') {
$path = iconv('utf-8', 'windows-1251', $path);
$fileName = iconv('utf-8', 'windows-1251', $fileName);
}
$newResponse = $response->withHeader('Content-type', 'application/octet-stream')
->withHeader('Content-Description', 'File Transfer')
->withHeader('Content-Disposition', 'attachment; filename=' . $fileName)
->withHeader('Content-Length', filesize($path));
readfile($path);
return($newResponse);
}
Короче, анон. Я тут в этом треде html&css учу, сам с java работаю. У тебя какой-то хуевый очень выходит цикл, ты берешь for на 20 итераций, который делает 12 из них и выходишь из него через break. Это индийский стиль программирования, за него православные пацаны могут с вертухи прописать. Гугли, в php должен быть цикл while, когда ты точно не знаешь какое число итераций сделает цикл. Чуть позже детально вникну почему у тебя остаток там.
Спасибо!
Картинки не думал брать, конечно. Я как раз хотел всё сделать текстом, чтобы удобно было искать интересующие моменты: я когда сам проходил всё по твоему учебнику, часто путался, постоянно пересматривал всё (в принципе, в этом тоже был плюс).
Задачи - только формулировки, пояснения и прочее хочу сделать для совсем начинающих.
Хочу ещё много добавить простых задач, чтобы после просто машинально применяли циклы разные, switch, допустим, разные встроенные функции. По ООП хочу гораздо больше всего сделать, но не с такими сложными задачами. Зандстра страницы с 80-й показался совсем сложным, не таким наглядным, каким хотелось бы всё видеть. Многое пропустил у него, а сейчас читаю про проектирование - ну неплохо, вроде бы многое понятно.
Всё это хочу сделать и для того, чтобы самому лучше понять многое.
Люблю наглядность, прогресс-бары, всякие milestones - вот просто в духе этого хочу многое реализовать, сделать такой чёткий курс.
Чувствую, что так или иначе буду и из твоего учебника черпать, вот и хотелось испросить разрешения.
https://github.com/codedokode/pasta/blob/master/html/html.md
Вот сам код:
https://codeshare.io/a3yENm
Проблема собственно с чем:
- Как правильно сделать внутри картинки заголовок? Я делал через position: relative и в него вложил position:absolute. Не уверен, что так и задумывалось.
- Как кусочек текста из figure который обвернут в span перенести на след строку? Его тоже делать absolute и выравнивать/выставлять margin`ом?
- Я никак не могу нагуглить, как сделать сноски слева от текста. Там в тег em вставлен собственный атрибут, я как понимаю, нужно его как-то использовать, но как именно? Можно ссылку какую-то или как это называется?
- так пойдет
- display:block
- предполагаю, что что-то вроде этого:
em[data-ref="1"]:before {
left: 20px;
display: block;
position: absolute;
color: grey;
font-size: 0.7em;
content: '[1]';
}
Единственное, что уразумел, так это то, что это, по сути своей, взаимодействие классов, которые имеют разные добавляемые опции, вроде интерфейсов. Хотя, очень вероятно я могу и ошибаться
$apple->type = "apple";
Зачем эти стрелочки >? Что оно относится к типу, указанному в главклассе?
<?php
class Person {
public $isAlive = true;
public $firstname;
public $lastname;
public $age;
}
$teacher = new Person();
$student = new Person();
echo $teacher->isAlive;
?>
Оно мне 1 показало. Почему? Откуда?
То есть $teacher имеет только одно isAlive? Или isAlive только один учитель?
Почитай ОП пост.
Выгода для всезнаек и не нуфагов сомнительна от такого кооператива.
Например вынес подключение к БД в отдельный файл bd.php, в нём прописаны настройки подключения и собственно подключение к бд, подключаю этот файл к скрипту, в котором необходимо выполнить действия с БД, но внезапно записанный объект в $database не является глобальной переменноq, т.е использовать его в своём коде я не могу, нужно походу объявлять глобальную переменную или ещё какой-нибудь хуйни наворотить.
Ну так запиши это в виде класса, подключить класс и создай объект класса, использовать лучше синглетон
Иди, собирайся. Тут сидят люди которые не пользуются социалочками и прочей ебаниной.
Булево значение true - это 1, а false - 0, NULL.
Поставь там свойство public $isAlive = false; - посмотри сам.
Иногда нужно для работы чего-либо возвращать true или false.
Например, ты дойдёшь до задачи про "Вектор", там у работника будет свойство $isBoss. Вот если $isBoss = true, то от этого зарплата в два раза выше, а количество отчётов в два раза меньше.
Но как так ты дошёл до ООП, а с таким не сталкивался? Непонятно.
В контроллер запихнул метод, который тригерится в определённом случае и отправляет всем email через Mail::to...
Пока в базе около 5 юзеров, и оно нормально работает, но какова вероятность что когда их будет несколько сотен, оно всё наебнётся?
Кратко тут не пояснить. В ОП посте есть учебник, в нем глава про ООП - прочти ее и реши задачи в ней, а если что-то непонятно - то напиши вопрос.
Такие вещи вряд ли завалят основной процесс, но если пользователей будет несколько тысяч, то запрос к серверу, который вызвал это событие будет достаточно медленоват. Лучше такие блокирующие вещи выносит в фон, почитай про сервера очереди задач типа gearman или rabbitMQ.
Вообще, рассылка может отвалиться по таймауту. Обычно там стоит execution_time_limit или как оно называется.
>Также, если интересен вопрос оптимизации выборки, то тут придется усложнять схему БД. Сейчас, чтобы вывести посты на главной, приходится делать много запросов, и они не очень эффективные (например, подсчет числа постов в каждом треде отдельно).
>
>Можно добавить в тред поля для хранения числа постов, а также ссылки на последние посты (либо сделать это через отдельную таблицу связи тред - последние посты). Соответственно данные можно будет выбрать в 2 захода: выбираем треды, затем собираем из них id ОП-поста и последних постов и выбираем их одним запросом. Но это конечно немного усложнит работу с базой, так как при изменениях надо обновлять эти дополнительные поля. Но зато снизит нагрузку на базу при выборке.
Этот совет будет актуален, если я перешел на Доктрину? Я реализовал ассоциацию Один-Ко-Многим и теперь, когда я получаю Тред, я получаю его Посты и Файлы, и теперь подсчет количества постов выполняется посредством метода count() класса ArrayCollection.
https://github.com/someApprentice/phpClub/blob/master/src/Threader.php#L115
https://github.com/someApprentice/phpClub/blob/master/src/Thread.php#L15
https://github.com/someApprentice/phpClub/blob/master/src/Post.php#L12
К тому же, из-за того что в этом классе не предусмотрена возможность получения только определенных записей, мне приходиться "выкидывать" лишние посты чтобы получить первый и последние три поста.
https://github.com/someApprentice/phpClub/blob/master/src/Threader.php#L117-L125
Мне следует получать посты через свои запросы?
>Также, строить цепочку постов через выбор всех постов в БД очень неэффективно. Лучше сделать таблицу связи "многие-ко-многим", связывающую посты, может быть такого вида:
>
>from_id | to_id
>
>или такого
>
>from_id | to_id | depth
>
>То есть мы берем пост, и для каждой ссылки в нем вставляем записи в таблицу связи. Можно вставлять только ссылки из самого поста, тогда надо делать несколько SQL запросов, чтобы построить цепочку, а можно вставлять ссылки еще и на посты с большей глубиной вложенности, тогда цепочка выбирается одним запросом, но таблица будет больше по объему.
А как из с таблицы с глубиной вложенности получить всю цепочку одним запросом?
Из примера выше (http://phpclub.rf.gd/pr/res/945059.html#956138):
>2) таблица хранит для каждого поста ссылки на все листья дерева, то есть для примера выше там будут записи
>A -> B
>A -> C
>A -> D
>B -> C
>B -> D
>C -> D
Допустим нужно получить цепочку поста B. Ссылки на дочерние ветки он имеет, но на родительские нет. В любом случае, нужно будет искать родителей в несколько запросов.
>И еще, может стоит добавить опцию, чтобы сохранялись и выводились ссылки на тред в архиве /pr/ и в архиваче, если они есть. Просто, чтобы было.
А как это реализовать? В /pr/ к ссылке на архив треда добавляется дата сохранения, которую неизвестно как получить, а на архиваче используются свои собственные id тредов.
>Также, если интересен вопрос оптимизации выборки, то тут придется усложнять схему БД. Сейчас, чтобы вывести посты на главной, приходится делать много запросов, и они не очень эффективные (например, подсчет числа постов в каждом треде отдельно).
>
>Можно добавить в тред поля для хранения числа постов, а также ссылки на последние посты (либо сделать это через отдельную таблицу связи тред - последние посты). Соответственно данные можно будет выбрать в 2 захода: выбираем треды, затем собираем из них id ОП-поста и последних постов и выбираем их одним запросом. Но это конечно немного усложнит работу с базой, так как при изменениях надо обновлять эти дополнительные поля. Но зато снизит нагрузку на базу при выборке.
Этот совет будет актуален, если я перешел на Доктрину? Я реализовал ассоциацию Один-Ко-Многим и теперь, когда я получаю Тред, я получаю его Посты и Файлы, и теперь подсчет количества постов выполняется посредством метода count() класса ArrayCollection.
https://github.com/someApprentice/phpClub/blob/master/src/Threader.php#L115
https://github.com/someApprentice/phpClub/blob/master/src/Thread.php#L15
https://github.com/someApprentice/phpClub/blob/master/src/Post.php#L12
К тому же, из-за того что в этом классе не предусмотрена возможность получения только определенных записей, мне приходиться "выкидывать" лишние посты чтобы получить первый и последние три поста.
https://github.com/someApprentice/phpClub/blob/master/src/Threader.php#L117-L125
Мне следует получать посты через свои запросы?
>Также, строить цепочку постов через выбор всех постов в БД очень неэффективно. Лучше сделать таблицу связи "многие-ко-многим", связывающую посты, может быть такого вида:
>
>from_id | to_id
>
>или такого
>
>from_id | to_id | depth
>
>То есть мы берем пост, и для каждой ссылки в нем вставляем записи в таблицу связи. Можно вставлять только ссылки из самого поста, тогда надо делать несколько SQL запросов, чтобы построить цепочку, а можно вставлять ссылки еще и на посты с большей глубиной вложенности, тогда цепочка выбирается одним запросом, но таблица будет больше по объему.
А как из с таблицы с глубиной вложенности получить всю цепочку одним запросом?
Из примера выше (http://phpclub.rf.gd/pr/res/945059.html#956138):
>2) таблица хранит для каждого поста ссылки на все листья дерева, то есть для примера выше там будут записи
>A -> B
>A -> C
>A -> D
>B -> C
>B -> D
>C -> D
Допустим нужно получить цепочку поста B. Ссылки на дочерние ветки он имеет, но на родительские нет. В любом случае, нужно будет искать родителей в несколько запросов.
>И еще, может стоит добавить опцию, чтобы сохранялись и выводились ссылки на тред в архиве /pr/ и в архиваче, если они есть. Просто, чтобы было.
А как это реализовать? В /pr/ к ссылке на архив треда добавляется дата сохранения, которую неизвестно как получить, а на архиваче используются свои собственные id тредов.
Понял, спасибо. Пойду гуглить
> Я реализовал ассоциацию Один-Ко-Многим и теперь, когда я получаю Тред, я получаю его Посты и Файлы, и теперь подсчет количества постов выполняется посредством метода count() класса ArrayCollection.
Ну так это сверхнеэффективно, выбрать кучу постов в память только для того, чтобы получить их количество или получить первые 3.
> Мне следует получать посты через свои запросы?
Да.
> А как из с таблицы с глубиной вложенности получить всю цепочку одним запросом?
Давай я пример приведу. Допустим пост A ссылается на B, C, пост B ссылается на D, E. Получаются такие записи:
post | reference | depth
A | B | 1
A | C | 1
A | D | 2
A | E | 2
B | D | 1
B | E | 1
Соответственно чтобы получить всю цепочку начиная с A, бы делаем выборку WHERE post = A
Если же мы делаем одноуровневую таблицу, то получается так:
post | ref
A | B
A | C
B | D
B | E
И мы должны сделать 3 запроса:
WHERE post = A // получаем B, C
WHERE post IN (B, C) // получаем D, E
WHERE post IN (D, E) // ничего
> А как это реализовать? В /pr/ к ссылке на архив треда добавляется дата сохранения, которую неизвестно как получить, а на архиваче используются свои собственные id тредов.
Прописывать в конфиг какой-нибудь вручную.
> Я реализовал ассоциацию Один-Ко-Многим и теперь, когда я получаю Тред, я получаю его Посты и Файлы, и теперь подсчет количества постов выполняется посредством метода count() класса ArrayCollection.
Ну так это сверхнеэффективно, выбрать кучу постов в память только для того, чтобы получить их количество или получить первые 3.
> Мне следует получать посты через свои запросы?
Да.
> А как из с таблицы с глубиной вложенности получить всю цепочку одним запросом?
Давай я пример приведу. Допустим пост A ссылается на B, C, пост B ссылается на D, E. Получаются такие записи:
post | reference | depth
A | B | 1
A | C | 1
A | D | 2
A | E | 2
B | D | 1
B | E | 1
Соответственно чтобы получить всю цепочку начиная с A, бы делаем выборку WHERE post = A
Если же мы делаем одноуровневую таблицу, то получается так:
post | ref
A | B
A | C
B | D
B | E
И мы должны сделать 3 запроса:
WHERE post = A // получаем B, C
WHERE post IN (B, C) // получаем D, E
WHERE post IN (D, E) // ничего
> А как это реализовать? В /pr/ к ссылке на архив треда добавляется дата сохранения, которую неизвестно как получить, а на архиваче используются свои собственные id тредов.
Прописывать в конфиг какой-нибудь вручную.
>Соответственно чтобы получить всю цепочку начиная с A, бы делаем выборку WHERE post = A
Но если мы хотим получить всю цепочку начиная с B, нужно будет сделать ещё один запрос WHERE reference=B, и так далее, пока мы не найдем всех предков.
И думает, что выкрутился.
Гугл, поиск картинок, "SQL JOIN" вон там -->>
A JOIN B ON cond берет по очереди каждую запись из таблицы A и присоединяет к ней по очереди все строки из таблицы B. Это называется полное декартово произведение таблиц. Если указано условие ON, то соединяются только пары записей, соответствующие условию в нем.
Допустим таблица A содержит записи A1, A2, A3, а таблица B - B1 и B2.
SELECT * FROM A JOIN B вернет такую таблицу:
A1 | B1
A1 | B2
A2 | B1
A2 | B2
A3 | B1
A3 | B2
То есть результат содержит все возможные сочетания записей из 2 таблиц. Если добавить условие ON, то будут взяты только пары, соответствующие указанному условию. Оно может быть любым, и будет проверяться по очереди для каждой пары.
Если в таблице A - N записей, а в B - M то в итоге после джойна без условия получится N*M записей.
LEFT JOIN отличается от STRAIGHT JOIN тем, что если для записи Ax не нашлось ни одной пары в B, соответствующей условию, то в результат добавляется пара
Ax | NULL
То есть при LEFT JOIN в результате гарантированно встретится хотя бы 1 раз каждая запись из A.
RIGHT JOIN - то же самое, то только для таблицы B, гарантируется что в результате будут все записи из нее, даже если им не найдется пары, соответствующей условию.
Если что-то непонятно - уточняй.
У нас в ОП посте есть задачи по SQL. Советую решить.
A JOIN B ON cond берет по очереди каждую запись из таблицы A и присоединяет к ней по очереди все строки из таблицы B. Это называется полное декартово произведение таблиц. Если указано условие ON, то соединяются только пары записей, соответствующие условию в нем.
Допустим таблица A содержит записи A1, A2, A3, а таблица B - B1 и B2.
SELECT * FROM A JOIN B вернет такую таблицу:
A1 | B1
A1 | B2
A2 | B1
A2 | B2
A3 | B1
A3 | B2
То есть результат содержит все возможные сочетания записей из 2 таблиц. Если добавить условие ON, то будут взяты только пары, соответствующие указанному условию. Оно может быть любым, и будет проверяться по очереди для каждой пары.
Если в таблице A - N записей, а в B - M то в итоге после джойна без условия получится N*M записей.
LEFT JOIN отличается от STRAIGHT JOIN тем, что если для записи Ax не нашлось ни одной пары в B, соответствующей условию, то в результат добавляется пара
Ax | NULL
То есть при LEFT JOIN в результате гарантированно встретится хотя бы 1 раз каждая запись из A.
RIGHT JOIN - то же самое, то только для таблицы B, гарантируется что в результате будут все записи из нее, даже если им не найдется пары, соответствующей условию.
Если что-то непонятно - уточняй.
У нас в ОП посте есть задачи по SQL. Советую решить.
> Я никак не могу нагуглить
Я загуглил "css data attributes" и нашёл такую статью: https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes
>>972436
> дебилу простым ЧЕЛОВЕЧЕСКИМ языком
>>972216
> Поясните кратко за ООП
Почему у вас такой странный подход к изучению: "поясните кратко", "объясните дебилу", "простым языком"? За что вам платить тогда, вас же с таким подходом любой заменить может.
> - Как правильно сделать внутри картинки заголовок? Я делал через position: relative и в него вложил position:absolute. Не уверен, что так и задумывалось.
Тут надо использовать абс. поз., так как темная плашка позиционируется поверх блока с картинкой, не влияет на расположение других блоков
> - Как кусочек текста из figure который обвернут в span перенести на след строку? Его тоже делать absolute и выравнивать/выставлять margin`ом?
Какой способ позиционирования позволяет располагать блоки вертикально? Очевидно, display: block
> - Я никак не могу нагуглить, как сделать сноски слева от текста. Там в тег em вставлен собственный атрибут, я как понимаю, нужно его как-то использовать, но как именно? Можно ссылку какую-то или как это называется?
Тебе надо почитать про генерируемый контент и CSS-свойство content:
http://htmlbook.ru/css/content
http://htmlbook.ru/css/attr
http://htmlbook.ru/css/counter-increment
http://htmlbook.ru/css/before
http://www.umade.ru/resources/specifications/CSS2/generate.html
>All Unicode regex engines discussed in this tutorial treat any single Unicode code point as a single character. When this tutorial tells you that the dot matches any single character, this translates into Unicode parlance as "the dot matches any single Unicode code point". In Unicode, à can be encoded as two code points: U+0061 (a) followed by U+0300 (grave accent). In this situation, . applied to à will match a without the accent. ^.$ will fail to match, since the string consists of two code points. ^..$ matches à.
>Matching a single grapheme, whether it's encoded as a single code point, or as multiple code points using combining marks, is easy in Perl, PCRE, PHP, Boost, Ruby 2.0, and the Just Great Software applications: simply use \X. You can consider \X the Unicode version of the dot.
http://www.regular-expressions.info/unicode.html
Это правда, что с юникодом регексы надо писать иначе, чем до юникода? В том, что касается "количества символов", например в "этот символ повторяется n раз", речь идёт о юникод-графемах или о "code points"? Я как-то не замечал этого, работая с юникодовскими регексами.
Юникод - сложная штука, к сожалению. действительно, буквы вроде "а с кружочком сверху" может быть закодирована 2 способами: как один символ или как буква a + модификатор-кружочек. Это не единственный подвох, в Юникоде полно других.
Более того, если ты пишешь эту букву в регулярке, тоже неизвестно, как текстовый редактор ее закодирует.
Данная проблема отчасти решается нормализацией строки перед применением регулярки. Нормализация приводит такие символы к единому виду.
Про \X кстати первый раз слышу.
> В том, что касается "количества символов", например в "этот символ повторяется n раз", речь идёт о юникод-графемах или о "code points"?
Число повторений идущего перед квантификатором выражения, то есть:
.{10} = 10 codepoints
\X{10} = 10 graphemes
К счастью, ситуации, когда надо отмерять ровно N сложносочиненных символов, довольно редки.
>Мэтт Зандстра — PHP: Объекты, шаблоны, методики программирования
Качай это, он тебе кратко за одну книгу весь ООП пояснит.
нет, у нас в конторе уровень гораздо выше ваши школо-задачек из оп-поста.
сейчас уже одна практика и рефакторинг от коллег мне, наверное, поможет. или не поможет.
Есть две таблицы, piki_tochenu и hui_drochenu.
piki_tochenu
pika_id sidit_id
1 я
3 мать
hui_drochenu
hui_id sidit_id
1 я
2 мать
3 я
select * from piki_tochenu
join hui_drochenu on hui_drochenu.sidit_id = piki_tochenu.sidit_id
where piki_tochenu.sidit_id = 'я';
Сделаешь джойн, будешь сидеть сразу на хуе 1 и пике 1, потом на хуе 1 и пике 3. До джойна сразу на стольких не мог сидеть.
> > В том, что касается "количества символов", например в "этот символ повторяется n раз", речь идёт о юникод-графемах или о "code points"?
> Число повторений идущего перед квантификатором выражения, то есть:
> .{10} = 10 codepoints
> \X{10} = 10 graphemes
Бло, я мог бы так критически облажаться. Не попадись мне эта статья.
А php вполне мог бы заменять кодпойнты на графемы, если ему указать флаг u, это вроде как логично. Теперь кроме флага u придётся ещё и \X ставить, если есть хотя бы намёк, скажем, на шведский алфавит, или на китайские знаки.
Да, посмотрел все, спасибо. Вроде внешне вышло все как и должно быть, но меня не покидает ощущение, что я гавнокожу. Я правильно понимаю, что по CSS и HTML вообще нету никаких code conventions, или канонов по оформлению разметки? Если не впадлу и есть время скажите, где кривая реализация в CSS. P.S. Все тот же урок с котом.
https://codeshare.io/21V8Z1
Двачую этого. Есть где-то свод правил по типу PSR для PHP, как CSS и HTML оформлять? Имена классов, селекторы и прочее.
А вот дефисы \w не видит, чтобы проверять слова,интересно, почему так сделали. Чтобы проверять слова с ними, придётся дописать его отдельно.
занимательный юникод
git checkout commit-id
Это не удалит коммиты из репозтория, но приведет файлы в рабочей дректории в соответствие с указанным коммитом.
git reset --hard
https://www.owasp.org/index.php/AJAX_Security_Cheat_Sheet#Always_return_JSON_with_an_Object_on_the_outside
>Прочитай мануал по json_decode. Он умеет выдавать массив, а не пародию на объект. Там по задумке по умолчанию для словарей JS создается объект класа stdClass в PHP, но на практике это не имеет особого смысла, лучше массив.
Не всё так просто, если я не знаю тонкостей json и php. Читал. Про массив-то я знаю. Собственно почему в этом случаее объекты хуже массивов я так и не понял. Расскажи пожалуйста. Видел комменты в стаковерфлоу к похожим задачкам и там видел пару реакций на stdClass - что это зло, но не понял сути.
Т.к. я нуб, то погуглив, наткнулся на это
http://stackoverflow.com/questions/18640607/what-is-better-stdclass-or-object-array-to-store-related-data
Там был тест скорости, который показал, что у меня объекты быстрей на 0.5ms.
И такой тип записи выглядит полее удобочитаемым
$json_array->sub_1->sub_2[$i]->sub_3
чем такой
$json_array["sub_1"]["sub_2"]["sub_3"]
А так, конечно хотелось бы знать, что правильней и применять это.
Для массивов есть много функций для работы с ними (array_keys и так далее), а для stdClass - нет. При этом stdClass это пародия на нормальный класс (у него нет ни полей ни методов). Таким образом, плюсов у stdClass нет, а минусы есть - для него нет удобных функций, как для массивов.
width: 100% на все
Собственно сам код: https://codeshare.io/aJ7x76
Блин, ОП - линковал похожее, тут такое ощущение что трабла какая-то из-за того что input вложен в label. Если его достать и прописать через for и id, что просили не делать, то кнопка нажимается, но слетает почему то border-radius. Как так жить, ОП надежда на тебя.
+ ОП, еще пишет что для кнопки использовал три тэга, label + input + i. Зачем нужен i?
Задача с sql-ex.ru: "Get the makers who produce only one product type and more than one model. Output: maker, type."
Я написал вот такой запрос:
select maker from product
group by maker
having count(model) > 1 and count(distinct type) = 1
Он правильный, но в решении требуется помимо maker выбрать ещё и type, пишу так:
select maker, type from product
...
И получаю ошибку: "Column is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause SQL Server". Насколько понял, это из-за того, что SQL-сервер не понимает, какой type выбрать из сгрупированных. Переписываю запрос так:
select maker, max(type) from product
...
Такое решение мне засчитали. Но не выглядит ли это костыльно? Тут полный перебор сгруппированных значений, когда хватило бы получения первого значения.
> Тут полный перебор сгруппированных значений, когда хватило бы получения первого значения.
А какое из них первое? Порядок ведь не задан. Конечно если они одинаковые то разницы нет, но видимо в SQL решили не заморачиваться с исключениями и обязать всегда использовать агрегатные функции.
Алсо у тебя в COUNT(model) по моему DISTINCT пропущен.
COUNT(model) это SUM(model IS NOT NULL) и это явно не то что нужно.
$i = 2;
do {
$i++;
echo $i;
}
while($i == 10);
echo $i;
Он мне показывает 3. Но разве он, после while($i == 10);, не должен показывать 10? Ведь задал условие, что бы $i = 10.
Бамп, так и не разобрался. У меня вышло сделать с не вложенным input в label. По другому никак.
>>973312
Смотри, ты задаешь условие в while, а не конечный результат. У тебя сейчас цикл выглядит таким образом, пока i РАВНО - 10, выполнять условие цикла. После первой итерации (которая выполнится даже если условие выполнено, это особенность do-while) i у тебя равен 3 и происходит выход из цикла. Короче говоря, тебе нужно поменять условие в цикле с i равно 10, на - пока i не станет равно 10.
То-есть изначально мне надо выбрать все данные по дням, но у меня есть дни в которые данных в нужной таблице нет, и мне нельзя эти дни пропускать, а надо вывести день и 0 результатов.
К примеру '2017-04-14', 0. In не подходит, так как он игнорит эти дни, идеальным вариантом взять список дней и приJOIN'ить их к таблице нужной по которой шла бы группировка, но я не могу написать в виде SELECT * FROM ('2017-04-14', '2017-04-13')
http://www.sql-ex.ru/help/select13.php#db_1
Извиняюсь, что сразу схему не показал. Столбец model в таблице product уникален, поэтому от DISTINCT ничего не поменяется.
Ещё вопрос, в таком запросе:
select from A where id > (select min(id) from B)
Сколько раз выполнится вложенный запрос? Столько, сколько строк в A? Если да, то можно ли как-то это оптимизировать?
Как вариант - создавать временную таблицу но думаю это будет довольно медленный вариант в 4 хода - создание временной таблицы, наполнение данными, выборка, удаление таблицы
Что то наподобие вышло
SELECT d.date, if (o.count is null, 0, o.count) as count, if(o.salary is null, 0, o.salary) as salary FROM `#date` as d
LEFT JOIN (SELECT count(*) as count, sum(total) as salary, DATE(date_added) as `date` FROM `order`) as o on o.date = d.date
Но лучше бы без временной таблицы.
Извините что нафлудил - забыл группировку по DATE(date_added) во внутреннем запросе
Кстати, интересует еще опыт местных в масштабирвоание базы под инсерты апдейты.
Нет, не правильно. Можно сделать и без него. В задании есть подсказка:
>подсказка: http://habrahabr.ru/post/138020/
>>973387
Если кому понадобится, решил без временных таблиц:
SELECT
d.date,
IF(o.count IS NULL, 0, o.count) AS count,
IF(o.salary IS NULL, 0, o.salary) AS salary
FROM
(SELECT
`date`
FROM
(SELECT ('2017-04-01') AS date UNION SELECT ('2017-04-02') AS date UNION SELECT ('2017-04-03') AS date UNION SELECT ('2017-04-04') AS date UNION SELECT ('2017-04-05') AS date UNION SELECT ('2017-04-06') AS date UNION SELECT ('2017-04-07') AS date UNION SELECT ('2017-04-08') AS date UNION SELECT ('2017-04-09') AS date UNION SELECT ('2017-04-10') AS date UNION SELECT ('2017-04-11') AS date UNION SELECT ('2017-04-12') AS date UNION SELECT ('2017-04-13') AS date UNION SELECT ('2017-04-14') AS date) AS date_tables) AS d
LEFT JOIN
(SELECT
COUNT(*) AS count,
SUM(total) AS salary,
DATE(date_added) AS `date`
FROM
`order`
GROUP BY DATE(date_added)) AS o ON o.date = d.date
Точнее можно ещё избавиться от одного лишнего селекта в первом селекте
Сама по себе цифра ничего не говорит. Если на эту машину поставить нгинкс и раздавать текстовый файл - он наверняка выдаст намного больше.
Там приложение на фалконе, которое полгода уже разрабатывается. В структуре базы 40 таблиц, активное использование связей. Энжинкс само собой. Сейчас просто посматриваю на то, как нагрузку держит текущий вариант.
Тайпхинтинг же для такого и нужен, разве не?
Хранить ли в модели файла, а также в базе данных полный путь на скачку (http://fileshare.loc/download/id) и полный путь к папке downloads (C:\Apache24\htdocs\file-sharing\app\Controller/../../public/downloads/2017/04/14) или же обойтись короткими как у меня? /downloads/2017/14/04 папка и /download/id скачка соответственно.
Также неизбежно ли отказываться от конструктора класса-модели и создавать отдельный метод setProperties из-за того, что set_fetch_type(\PDO::fetch_class, 'ClassName') будет требовать третьим аргументом передачу свойств для конструктора, которые проблематично в моем FIleGateway получить?
Это все не в модели хранится, а в конфиг файле/классе. Модели либо конфиг класс передается, либо готовые значения из конфиг класса (лучше). В конфиг классе может как относительный через _DIR_, так и абсолютный храниться, на то он и конфиг.
А какой смысл этого? Метод принимает объект, ему надо понять, к какому классу он относится. При чем тут интерфейс сам по себе?
В методе условия ставить для вытягивания соответствующих свойств из объекта соответствующего класса и т.п.?
You doing it wrong. Если метод может принимать два разных объекта и делать с ними разные вещи в зависимости от того, какой объект был ему скормлен, значит у тебя один метод, который выполняет роль двух методов, а это значит, что тебе надо разделить этот метод на два метода, каждый из которых принимает свой объект. Если у тебя метод может принимать больше одного класса объектов, но делает с ними одинаковые вещи, то тогда он должен принимать интерфейс. Либо так, либо говнокодить bad practice и тогда тебя не должны волновать type hinting и прочие ништяки нормального адекватного кода.
Если тебе нужно получать одинаковые данные, но с разных параметров объекта, то надо сделать два прокси метода, которые каждый выдергивает нужные параметры с твоих объектов и вызывает один основной метод, который уже делает всю логику вне зависимости от того, какие там объекты вначале были. Это позволит тебе затем, не переопределяя этот основной логический метод, добавить еще один прокси-метод, который будет принимать третий вид объекта и также скармливать нужные данные основному методу, которому по прежнему будет пофиг, от какого объекта эти данные были получены.
Чисто для примера:
public function proxyMethod1(objectType1 $object)
{
$this->logicMethod($object->$c, $object->d);
}
public function proxyMethod2(objectType2 $object)
{
$this->logicMethod($object->e, $object->f);
}
public function logicMethod(int $a, int $b)
{
return $a + $b;
}
>>973763
Я ничего не пони.
Но я был мимо, просто интерсно тоже, Зандстра что-то писал об этом, но у него вроде именно с проверкой класса у объекта.
Я бы избегал кода, в котором метод может принимать два разных вида объектов в качестве одного аргумента. Либо делаешь два метода, каждый из которых принимает нужный объект, либо пилишь интерфейс с методом, который позволяет получить нужные данные, а твои объекты реализуют этот интерфейс и позволяют получить эти данные независимо от того какого типа сам объект.
Короче чтобы долго не объяснять, вот пример кода:
https://github.com/MakeevD/MicroCrm/blob/master/app/Http/Controllers/OrderController.php#L121 - этот метод вызывает статический метод TempHandler'а (метод сохраняет изменения в базу), https://github.com/MakeevD/MicroCrm/blob/master/app/Helpers/TempHandler.php , у которого есть метод destroy (44 строка). Модель Temp имеет два внешних ключа, к двум моделям.
Короче я создал пустой интерфейс для обеих моделей, но уже убедился в том, что этот метод TempHandler'а вообще не нужен, как и сам TempHandler как класс, а его метод store переписать в конструктор модели Temp.
http://archive-ipq-co.narod.ru/l1/regexp.html - тут естессна сама задача,там с массивом правильных и неправильных номеров.
Сейчас посмотрел: Зандстра советует делать суперкласс и одинаковы методы в каждом дочернем, которые будут вытягивать, допустим, количество страниц или время прослушивания для дочерних классов CdProduct или BookProduct.
При этом у него в конструктор суперкласса передаются и время прослушивания, и количество страниц, то есть не одно вместо другого, но и то, и сё.
Ещё он говорит про instanceof, но мне такое не нравится тоже.
Так у меня динамически создаются эти пути (год/месяц/день), как мне это хранить в конфиге-то.
Что повторяется, то сокращай.
Я вообще не понимаю этого сайта с регулярками, сама тема такая, что редко пригождается (уже подо всё написаны регулярки, а сам начнёшь использовать - обязательно где-нибудь проколешься).
так,если тебе конечно не сложно,можешь попробовать написать руглярку для этой задачки,чтобы я понял?
забудь
проблема для детишек - не поставил в начале и конце регулярного выражения ^ $ как писалось в уроке...
public function getUsers()
{
$sql = "SELECT * FROM users";
$result = $this->db->query($sql);
$users = $result->fetchAll(PDO::FETCH_OBJ);
return $users;
}
Как правильно проверить что запрос сработал, достаточно будет сделать просто вот так?
if($result = $this->db->query($sql)) {
//остальной код
}
public function addQuestion(Question $question) {
if($stmt = $this->db->prepare("INSERT INTO question (id, question_text, user_ip, user_cookie) VALUES (NULL, ?, ?, ?)")) {
$stmt->execute(array($question->question_text, $question->user_ip, $question->user_cookie));
}
}
Что лучше вернуть из такой функции? Чтобы можно было как-то проверить успешность выполненного запроса уже вне класса?
Зачем тебе XML, может тебе на самом деле Json нужен?
$stmt->execute(array(':test' => $sort));
Аноны, почему это не работает? Если делать сортировку без prepare, то все отлично работает.
$stmt = $pdo->query('SELECT FROM students ORDER BY test DESC'); - работает.
Точнее в таком случае у тебя должно быть так:
$stmt = $pdo->prepare('SELECT FROM students ORDER BY :test DESC');
$stmt->bindValue(':test', $sort);
$stmt->execute();
Короче ты путаешься в синтаксисе. Почитай про подстановку значений в ПДО, у ОПа еще есть где-то.
Т.е., допустим, по фокусу на инпут идёт один запрос на сервер, откуда в потоке приходят записи и колбэком заносятся в общий селект. Мне кажется, что это задача простая, но сходу в голову ничего не лезет.
На клиенте запоминай сколько записей вернул ajax запрос, потом при необходимости догрузить еще записей, отправляй такой же запрос, только с параметром count, который будет использоваться бэкендом для выборки данных с оффсетом.
Выбирай: https://packagist.org/search/?q=XML Serializer
>>973968
После подстановки твой запрос будет выглядеть примерно так: SELECT FROM students ORDER BY 'column' DESC
То есть вместо :test - строка, а нужен столбец (без кавычек).
Почему строка написано тут: https://secure.php.net/manual/en/pdostatement.execute.php
В качестве параметров PDO не используют столбцы или названия таблиц, так как параметры - это какие-то значения (строки, числа), пришедшие от пользователя. Для столбцов на голом PDO обычно пишут руками проверку: if (!in_array($column, ['age', 'name', ...])) { ...
>>973871
Если произошла ошибка, то PDO выбросит исключение. Это в старых MySQL расширениях для PHP нужно было постоянно проверки писать.
>>973998
Это синтаксис для массивов в PHP < 5.4
>>974000
В этом примере тоже будет ORDER BY 'строка' и сортировка не сработает. Строка потому что bindParam по дефолту всё приводит к PDO::PARAM_STR https://secure.php.net/manual/en/pdostatement.bindparam.php
>В этом примере тоже будет ORDER BY 'строка' и сортировка не сработает. Строка потому что bindParam по дефолту всё приводит к PDO::PARAM_STR
Да, забыл. Можно эмуляцию отключить, ну или там просто отдельно пихать параметр сортировки.
Ну это понятно, типа обычная пагинация по скроллу или кнопке. А в реальном времени? Типа, допустим, 10 000 записей, выводить по 100 => написать рекурсивную функцию, которая отправит 100 запросов? Просто хочется всё это в один запрос уместить.
> А в реальном времени?
Что ты сделать-то хочешь? Тут два варианта, или пагинация или отправка всего списка сразу, сохранение его на клиенте и вывод его по кускам. Мне кажется делать несколько аякс запросов будет логичнее, если учитывать что список огромный.
$string = 'April 15, 2003';
$pattern = '/(\w+) (\d+), (\d+)/i';
$replacement = '${1}1,$3';
echo preg_replace($pattern, $replacement, $string);
Что непонятного то?
Окей, если ты такой молодец, можешь помочь еще кое с чем? Мне бы знать, как букву из нижнего в верхний регистр свичнуть
Если горит сделать с регуляркой - напиши регулярку которая ищет нужную тебе букву в нижнем регистре и меняй ну букву в верхнем, делов то.
$string = "qwe rty tyu ";
$string = preg_replace (‘/\s+/’, ‘ ‘, $string) ;
Такие вещи легко гуглятся, на самом деле.
В этом то и проблема...
Не знаю как просто
Я сейчас напишу свой реплейс и ты скажешь,что не так:
preg_replace("/^(\s+)?([а-яё]/u"#но только проблема в том,что мне надо все предложение просмотреть,а я только первый символ смотрю(а как сделать я хз)#,'вот тут то я и не знаю,что написать',$'какой-то текст')
Не совсем понял что ты хочешь, если ты хочешь чтобы искалось по всей фразе, то метасимвол ^ лишний в твоем выражении.
>("/^(\s+)?([а-яё]/u"
> ^декларирует начало данных (или строки в многострочном режиме)
https://secure.php.net/manual/ru/regexp.reference.meta.php
Если не сложно,помоги(кинь реплейс весь для замены первой буквы со строчной на заглавную):3
На вопрос отвечают рекомендации по оформлению кода PSR:
http://www.php-fig.org/psr/psr-2/#method-arguments
PSR это не совсем стандарт, это рекомендации, которым следуют разработчики нескольких популярных фреймворков, но лучше у нас все равно ничего нет.
IDE умеют форматировать код в соответствии со стандартом, если настроить нужные опции: https://ratanparai.wordpress.com/2014/10/16/prepare-eclipse-for-php-psr-standard/
Раз уж тут появился вопрос про оформление кода, то спрошу -
как относятся к такому оформлению:
// \t - табуляция
$entity = new Entity();
\t$entity->setFoo();
\t$entity->setBar();
\t$entity->set...;
Нашел сначала в группе вк одну, работаем понемножку, с оплатой по задачам, но работы очень мало сейчас.
Нашел вторую, там же, писать модули под одну систему. 8 тысяч рублей за один модуль, поговорили по скайпу, оплатили уже первые 2 задачи по текущему модули, все четко, все получается почти всегда
Но хочу немного больше нагрузки, а в офис лень идти. Нравится удаленная работа, вкатился недавно, уже есть что показать.
Может фриланс?Или есть еще где то места, где публикуются обьявления по рабте
Да почитай документацию на сайте. Я освоился за пару часов более менее
freelancer, guru, upwork, toptal, crossover
Там все деньги, в твоих контактах гроши по сравнению с тем, что там. Но надо инглиш сначала подучить.
>freelancer
>>974248
>freelancer
Ты наверное английскую версию имел, а то зашел на русскую и сразу проиграл в голос
О, спасибо, то что нужно, английский не особая проблема. Разве что если общаться именно голосом, там могут проблемы возникать. А так писать на нем могу свободно документацию, статьи, книги и т.д. Этого достаточно?
читать свободно*
Мы с пацанами в 2008 сидели в кроватке на уроке информатики...
Падажжи ебана.
Можно подробнее, пожалуйста. Вообще не могу въехать в задачу. То есть знаю функцию, но не понимаю как это все правильно записать, что бы работало.
У тебя та же проблема что и у других начинающих: ты пишешь код стеной и не можешь вынести отдельные действия в функции. Ну например конвертирование кодировки в пути надо делать отдельной функцией, а не копипастить многократно по коду. Да и саму отдачу файла наверно тоже.
> $path = '..\\' . $file->link;
Не стоит использовать такие относительные пути, так как они высчитываются относительно текущей директории процесса (не директории в которой php-файл) и могут указывать куда угодно.
> 'attachment; filename=' . $fileName)
Это не будет работать так как в filename по стандарту можно указывать только ASCII (латинницу). Есть способ указать там кодировку, но он работает только в новых браузерах, так что лучше это поле не использовать.
> readfile($path);
> return($newResponse);
Это тоже неправильно. Ты сначала выводишь содержмое файла через readfile, а только потом возвращаешь объект ответа с заголовками, но без тела ответа. Зачем тогда этот объект Response нужен если он не содержит тело ответа?
Конечно Слим перехватывает выводимые данные и добавляет их в ответ, но это неэффективно, так как весь файл будет считан в память. Нужно использовать возможность передать поток файла в Response, и он будет выводе ответа прочтет тело из него.
Если посмотреть на конструктор Response, то там есть возможность передать в конструктор объект, соответствующий StreamInterface.
Ну и наконец, все это подразумевает отдачу файла средствами PHP. Эффективнее было бы переложить эту задачу на веб-сервер, если есть такая возможность. Она есть в Апаче с помощью модуля X-Sendfile и в нгинксе в модуле X-Accel-Redirect. От PHP скрипта только требуется указать имя файла для отдачи. Стоит добавить возможность использовать такой модуль.
>>972123
Имей в виду еще, что на это все может уйти много времени.
>>972289
Тебе надо разобраться с областью видимости переменных. Напрмер, глобальные переменные не видны внутри функций.
У тебя та же проблема что и у других начинающих: ты пишешь код стеной и не можешь вынести отдельные действия в функции. Ну например конвертирование кодировки в пути надо делать отдельной функцией, а не копипастить многократно по коду. Да и саму отдачу файла наверно тоже.
> $path = '..\\' . $file->link;
Не стоит использовать такие относительные пути, так как они высчитываются относительно текущей директории процесса (не директории в которой php-файл) и могут указывать куда угодно.
> 'attachment; filename=' . $fileName)
Это не будет работать так как в filename по стандарту можно указывать только ASCII (латинницу). Есть способ указать там кодировку, но он работает только в новых браузерах, так что лучше это поле не использовать.
> readfile($path);
> return($newResponse);
Это тоже неправильно. Ты сначала выводишь содержмое файла через readfile, а только потом возвращаешь объект ответа с заголовками, но без тела ответа. Зачем тогда этот объект Response нужен если он не содержит тело ответа?
Конечно Слим перехватывает выводимые данные и добавляет их в ответ, но это неэффективно, так как весь файл будет считан в память. Нужно использовать возможность передать поток файла в Response, и он будет выводе ответа прочтет тело из него.
Если посмотреть на конструктор Response, то там есть возможность передать в конструктор объект, соответствующий StreamInterface.
Ну и наконец, все это подразумевает отдачу файла средствами PHP. Эффективнее было бы переложить эту задачу на веб-сервер, если есть такая возможность. Она есть в Апаче с помощью модуля X-Sendfile и в нгинксе в модуле X-Accel-Redirect. От PHP скрипта только требуется указать имя файла для отдачи. Стоит добавить возможность использовать такой модуль.
>>972123
Имей в виду еще, что на это все может уйти много времени.
>>972289
Тебе надо разобраться с областью видимости переменных. Напрмер, глобальные переменные не видны внутри функций.
Синглтон это плохой паттерн в данном случае.
>>972417
> Но если мы хотим получить всю цепочку начиная с B, нужно будет сделать ещё один запрос WHERE reference=B, и так далее, пока мы не найдем всех предков.
Может быть я не так понял условия задачи? Вот в этом примере, когда мы создаем большую таблицу связей:
post | reference | depth
A | B | 1
A | C | 1
A | D | 2
A | E | 2
B | D | 1
B | E | 1
Мы ищем посты не по условию WHERE reference =, а по условию WHERE post = и выборка WHERE pos t = A включает в себя и посты из выборки с post = B (D и E).
То есть если представить посты и связи как дерево, то в этой таблице мы одним запросом выбираем всех потомков узла любой глубины вложенности, а не только непосредственных детей.
>>972692
Проблемы будут не только с регулярками, например mb_lenth() вернет длину в codepoints.
>>972694
В HTML используют отступ в 2 или 4 пробела. Имена тегов пишут в нижнем регистре.
В CSS пишут свойства либо вертикально, либо горизонтально. Имена классов и id пишут маленькими буквами, разделяя слова минусами.
Есть еще БЭМ.
Погуглить стайлгайды можно по словам вроде "html style guide". Вот я например гугловский выгуглил: https://google.github.io/styleguide/htmlcssguide.html
>>972738
Погуглить стайлгайды можно по словам вроде "html style guide". Вот я например гугловский выгуглил: https://google.github.io/styleguide/htmlcssguide.html
Синглтон это плохой паттерн в данном случае.
>>972417
> Но если мы хотим получить всю цепочку начиная с B, нужно будет сделать ещё один запрос WHERE reference=B, и так далее, пока мы не найдем всех предков.
Может быть я не так понял условия задачи? Вот в этом примере, когда мы создаем большую таблицу связей:
post | reference | depth
A | B | 1
A | C | 1
A | D | 2
A | E | 2
B | D | 1
B | E | 1
Мы ищем посты не по условию WHERE reference =, а по условию WHERE post = и выборка WHERE pos t = A включает в себя и посты из выборки с post = B (D и E).
То есть если представить посты и связи как дерево, то в этой таблице мы одним запросом выбираем всех потомков узла любой глубины вложенности, а не только непосредственных детей.
>>972692
Проблемы будут не только с регулярками, например mb_lenth() вернет длину в codepoints.
>>972694
В HTML используют отступ в 2 или 4 пробела. Имена тегов пишут в нижнем регистре.
В CSS пишут свойства либо вертикально, либо горизонтально. Имена классов и id пишут маленькими буквами, разделяя слова минусами.
Есть еще БЭМ.
Погуглить стайлгайды можно по словам вроде "html style guide". Вот я например гугловский выгуглил: https://google.github.io/styleguide/htmlcssguide.html
>>972738
Погуглить стайлгайды можно по словам вроде "html style guide". Вот я например гугловский выгуглил: https://google.github.io/styleguide/htmlcssguide.html
А что-то запрещает тебе его использовать? Он к конкретному языку не привязан.
>>972810
> юникод-класс который обещает быть не быстрым
А у тебя есть более быстрая альтернатива? Также, это надо мерять, может на практике скорости вполе хватает.
> для включения нижних подчёркиваний нужно использовать старый добрый \w (с указанием 'u' после регекса).
Можно писать так [\p{L}_]
> А вот дефисы \w не видит, чтобы проверять слова,интересно, почему так сделали
Не знаю. Это формально не дефис, а математический знак минус.
Объясните плиз, подробно, как решать ? Чето совсем додуматься не могу, как это все правильно записать.
Сделал мобильную верстку для сайта на медиа
@media only screen and (min-width: 400px) and (max-width: 500px),
only screen and (min-device-width: 400px) and (max-device-width: 500px){
в браузере в указанном разрешении все норм, но на реальном телефоне отвратительная хрень - позиции выставляются по минимальному значению (< 400px), а вот размеры шрифта, элементов - все дико мелкое. В итоге как будто телефон выбирает css для 400px, а отрисовывает на свои реальные пиксели. Что не так?
https://github.com/codedokode/pasta/blob/master/html/html.md
8: https://jsfiddle.net/Lpguk5kx/
10: https://jsfiddle.net/18504y5y/3/
11:
https://jsfiddle.net/3qm145b4/2/
https://jsfiddle.net/3qm145b4/2/embedded/result/
Второе - тест клавиатурной навигации. На jsfiddle немного глючит из-за наличия посторонних элементов на странице. Но если сохранить эту https://pastebin.com/YDuMFQSP страницу и открыть браузером, то навигация работает правильно (стрелочки+Tab для радиокнопок, стрелочки+пробел для чекбоксов).
12:
https://jsfiddle.net/qozy8zsL/7/
https://jsfiddle.net/qozy8zsL/7/embedded/result/
>У тебя та же проблема что и у других начинающих: ты пишешь код стеной и не можешь вынести отдельные действия в функции. Ну например конвертирование кодировки в пути надо делать отдельной функцией, а не копипастить многократно по коду. Да и саму отдачу файла наверно тоже.
В целом понял. Я в общем-то так и думал, сделать класс типа FileDownloader и реализвать в нем разные способы отдачи файлов.
>Не стоит использовать такие относительные пути, так как они высчитываются относительно текущей директории процесса (не директории в которой php-файл) и могут указывать куда угодно.
А нормально ли будет сделать пхп-файл в котором константами будут прописаны все эти пути? Или надо как-то хитрее делать?
meta viewport поставил? Без него телефон будет рендерить страницу в вьюпорт шириной 800-900 пикс и всячески имитировать десктопный браузер. При этом твое правило min-device-width срабатывает.
https://developer.mozilla.org/en-US/docs/Mozilla/Mobile/Viewport_meta_tag
http://frontender.com.ua/mobile-web/wtf-viewport/
Я бы также убрал min-device-width, какое оно отношение имеет к верстке? Размер окна браузера не обязан совпадать с размером экрана устройства.
https://jsfiddle.net/rw01ae7v/
vertical-align: top, либо пропиши float.
Vertical-align у тебя по умолчанию baseline, а baseline в данном случае - конец строки первого дива
>> Но если мы хотим получить всю цепочку начиная с B, нужно будет сделать ещё один запрос WHERE reference=B, и так далее, пока мы не найдем всех предков.
>
>Может быть я не так понял условия задачи? Вот в этом примере, когда мы создаем большую таблицу связей:
>
>post | reference | depth
>A | B | 1
>A | C | 1
>A | D | 2
>A | E | 2
>B | D | 1
>B | E | 1
>
>Мы ищем посты не по условию WHERE reference =, а по условию WHERE post = и выборка WHERE pos t = A включает в себя и посты из выборки с post = B (D и E).
>
>То есть если представить посты и связи как дерево, то в этой таблице мы одним запросом выбираем всех потомков узла любой глубины вложенности, а не только непосредственных детей.
>Может быть я не так понял условия задачи?
Проясню на всякий случай условия задачи:
Если мы имеем пост №1, на который ссылается №2, и на номер №2 ссылается №3, то какой бы пост мы не выбрали мы должны получить всю эту цепочку.
Я с самого начала был запутан этой таблицей, я думал что A это самый старший предок, который имеет ответы B, C и т.д, но, тем не менее, это не меняет принципа моего вопроса - Если B имеет ссылки на предков, то он не имеет ссылок на детей и получить всю цепочку только одной выборкой WHERE post=B нельзя, нужно делать
А, понял, о чем речь. Может быть можно тогда допилить таблицу и добавить туда не только "потомков", но и "предков" поста, с depth = -1, -2 и тд?
Тогда будет один запрос. Но на мой взгляд, это только утяжелит таблицу, и приведет к дублированию данных без особой выгоды, действительно, лучше уж тогда 2 запроса делать:
WHERE post = A
UNION
WHERE reference = A
Вообще, я сейчас поймал себя на мысли, что связи между постами образуют не дерево (где у узла ровно один предок, и много потомков), а граф без циклов (где узел может ссылаться на любое число узлов и любое число узлов может ссылаться на него, но циклов нет так как пост может ссылаться только на предыдущие посты): https://ru.wikipedia.org/wiki/Направленный_ациклический_граф
И соответственно мы можем при желании построить таблицу связей в обе стороны, искать как "потомков", так и "предков". Ну и вообще, поняв, какая у нас структура данных, можно понять, что с ней можно делать.
Рекурсия тут нужна в любом случае, просто мы можем делать ее либо при построении таблицы, строя список всех связей, либо ее придется делать при выборке.
> Я с самого начала был запутан этой таблицей,
Тут лучше посмотреть на картинку графа из википедии. Мы можем либо записывать в таблице непосредственные связи (узлы, в которые за 1 шаг можно попасть из текущего), либо записывать все узлы, которые достижимы из текущего, если двигаться по стрелкам.
>Проблема начинается когда сразу отправляются опции которые могут вычитать и добавлять результати(и или).
Приведи пример. Типа (A ^ B) V (C ^ D) V (E)? И как на фронте это выглядит?
Что за анальная регистрация
Ну пример на телефонах: есть чекбоксы hdmi, ips(условие и), ну и чекбоксы моделей с условием или, но не в этом суть. Как вообще правильно организовать передачу параметров и разбирать их в контроллере? Плюс если там будут связующие таблицы с айдишками фичей телефонов то код вообще раздутый выходит. В общем может есть готовые решения, паттерны организации фильтрации контента?
Ну я свой код уже скидывал выше в треде, вот класс-хелпер для фильтрации:
https://github.com/MakeevD/MicroCrm/blob/master/app/Helpers/SearchOrders.php
и форма:
https://github.com/MakeevD/MicroCrm/blob/master/resources/views/orders/search.blade.php
Контроллер передаёт в этот класс массив search[] с формы, и там всё постепенно строится Builder. В классе-хелпере лежит массив с правилами, по какому методу Builder'а искать тот или иной параметр (например, все даты объединены правилом date). Нужен какой-то другой - дописываешь правило и метод.
Это внешне похоже на то, как это реализовано в Yii2. Но я хуй простой, и интересно было бы послушать мнение других.
попробуй почитать документацию, можешь юзать скоупы для моделей и чтоб вернуть json можешь с метода просто массив вернуть.
PS. 6yrs php experience
спасибо тебе, посмотрю
Ну этот проект в процессе буквально пару недель, впереди ещё много доделывать и рефакторить. Ну да, со скоупами более ларавель-вей, но вкратце суть такая:
1. Определяем правила, по которым ищутся параметры. (после того, как напишу валидацию, думаю, привяжу эти правила и к поиску)
2. Перебираем массив параметров с фронтенда, к каждому одноименному полю вызываем соответствующий правилу метод (скоуп)
3. Возвращаем билдер, и в контроллере уже его сортируем-пагинируем-сериализуем
Мой todo: передавать массив ['логический_оператор' => 'массив_параметров']. Каждый массив_параметров фильтруется вышеописанным способом, а затем они связываются между собой логическими параметрами (в качестве ключа) в том порядке, в котором его принял хелпер. Ну и этот массив может быть многоуровневым.
relations
На апворке да, на топталах/кроссоверах нет, там устный проверяют.
Все soap веб-сервисы на нем. Rest тоже часто бывают.
Давно писал свою простенькую тёмную тему для двача через stylish т.к. нормальной не нашёл, а тут решил чего-то модернизировать, и пришла куча идей, но я не специалист в css, поэтому не уверен - можно ли такое вообще сделать. Это к вашему треду?
Это скорее в Верстка-тред, тут я думаю верстальщиков поменьше. Хотя большинство знает CSS на средне-начальном уровне
Я бы мог составить список вопросов и тут написать их, а то 1 я в этом точно не разберусь.
Все вопросы к стайлишу:
1. Можно ли добавить в строку на 1 пике кнопку "Доска", которая бы вела на главную доски треда. Например, если я тут бы её нажал, то перешёл бы на доску /pr ?
2. Можно ли сделать так, что при автообновлении страницы она сама прокручивалась вниз?
Ничего из списка Stylish'ем не сделать, тебе нужен язык JavaScript и аддон, позволяющий вставить свой JavaScript код в страницу (Greasemonkey, Tampermonkey). Для первой задачи нужно вычленить название доски и вставить элемент-ссылку в ДОМ-дерево, для второй задачи нужно изучать JavaScript макабы, чтобы узнать как добавить прокрутку после автообновления. Если не знаком с JS, то будет туго. Вся инфа есть на learn.javascript.ru
А вы не поможете скрипты написать? Я в цсс худо-бедно с гуглом написал говнотему, а с яс я точно не справлюсь.
>> Я реализовал ассоциацию Один-Ко-Многим и теперь, когда я получаю Тред, я получаю его Посты и Файлы, и теперь подсчет количества постов выполняется посредством метода count() класса ArrayCollection.
>
>Ну так это сверхнеэффективно, выбрать кучу постов в память только для того, чтобы получить их количество или получить первые 3.
>
>> Мне следует получать посты через свои запросы?
>Да.
Ха, даже если я использую NativeSQL запросы, то я всё равно получаю ArrayCollection на самом деле PersistentCollection, не знаю почему со всеми постами. У меня не получилось нагуглить как получить сущность без ассоциаций. Значит нужно отказаться от них?
>>974518
>Тогда будет один запрос. Но на мой взгляд, это только утяжелит таблицу, и приведет к дублированию данных без особой выгоды
Это действительно так плохо? Это решение решило бы проблему.
А почему бы тебе не сортировать в реальном времени прямо на странице, а для получения подробной информации отправлять например аяксом только id уже отфильтрованных записей?
public function get(): StringReverseWorker
{
код
}
Интересует именно двоеточие
Это в седьмой пыхе завезли. Strict Mode, все дела
Почему бы тебе не использовать getSingleScalarResult();???
Пример:
public function getTotal()
{
return $this->createQueryBuilder('post')
->select('COUNT(post)')
->getQuery()
->getSingleScalarResult();
}
Зачем вы тут используете Query Builder? Пишите на DQL сразу, будет и проще и читабельнее. Query Builder для сборки запросов из частей, а тут запрос всегда одинаковый.
Алсо тут проще обычный SQL запрос использовать без маппингов, через DBAL.
> Пишите на DQL сразу, будет и проще и читабельнее.
>Алсо тут проще обычный SQL запрос использовать без маппингов, через DBAL.
Иди своей дорогой, сталкер.
1. на идеуан выдает ошибку
Uncaught Error: Call to undefined function mb_strlen() in /home/8DynTa/prog.php:14
2. через терминал все работает на ноуте, но только конкатенирует строки, а не складывает их, не могу понять где ошибка
3. пошпыняйте за сам код
1. Большая картинка, допустим, нарисована коробка с инструментами, в которой лежат молоток, отвёртка, зубило, рубанок, пила и тд.
2. Инструменты при наведении курсора слегка увеличиваются и являются ссылками на соответствующие страницы (о молотках, отвёртках и тд).
3. В зависимости от наличия инструментов, там может быть рядом лежащих три молотка, три отвёртки (рядом, но со смещением).
4. Какая-то форма в админке для заполнения количества: допустим, ставлю три галочки в чекбоксах - появляются на картинке три молотка, а всего может быть пять молотков.
Вообще там нужно было полку с ручными работами, они готовятся медленно, но вот с молотками понятнее, надеюсь.
Сама визитка на Yii2.
Человеку в админке нужно просто как-то указывать количество молотков-отвёрток, жмакать на "сохранить", а потом на странице видеть изменения.
Как к такому подступиться вообще? На jQuery, на чём?
понятно, тоже так подумал, жаль вот ошибку я еще не нашел
css + jquery же, можно бутстрап для упрощения жизни, но не обязательно.
>Как к такому подступиться вообще?
Уроки верстки из шапки делал? Тогда бы знал уже. Бэкграунды, флоаты, абсолютное позиционирование, css эффекты.
Я делал очень давно и не до конца доделал тот макет.
Что CSS - это понятно, бутстрап там уже есть. Что jQuery - я предполагал.
Ну а как подступиться-то? Я хз же вообще.
Нужна ведь вкладка в админке для выставления флажков в чекбоксах. Или лучше не чекбоксы, а ползунки jQuery UI, наверное.
Не могу всё собрать воедино, так как никогда не имел с этим дела.
Позиционируй сначала все при помощи css и эффекты при наведении сделай, а потом уж jquery эвенты вешай и по чекбоксам распределяй.
Ну доки ларавела точно надо почитать. К докам пхп по необходимости будешь обращаться, ничего сложного. Разве что ларавел, конечно, распиаренное говно . Объективно он сейчас самый хуевый для разработки вариант, но уж больно удобный, мимими.
Почему самый хуевый? Вроде как в сравнении с yii говорят, там больше наворотов и функицонала.
Перделок на уровне кода ага, больше. Полезного функционала меньше. Скорость такая, что кина не будет, посаны. Медленнее ларавела только вордпресс.
Есть такое
<div class = words><div class = italic>n: </div>{{noun}}</div>
Фишка в том, что если {{noun}} пустой, то весь класс words не должен отображаться, если же в {{noun}} будет слово или буква, то должно показаться, типа:
n: test
Делаю свои карты в программе Анки, и хочу так сделать, что если я не напишу ничего в поле, то оно не отображалось бы - пик.
"INSERT INTO table(name, secondName, nuTiPonel) VALUES (?, ?, ?);
Ну а далее prepare($sql) и экзекут, ну вы понели. Ну или там можно bindParam(':name', $name). Ну тут проблема в том, что я не знаю заранее сколько и каких у меня будет параметров в класс-таблице для подстановки. Как лучше решить проблемку? А то на ум сплошной говнокод приходит, типа хранить все эти данные в специальной параметре-массиве и прочее.
Кот на месте, я спокоен.
Есть основной сервер с обновляющимися данными, я с него периодически отправляю запросы с этими данными на другой сервер-клиент. И на сервер-клиенте должна обновляться страница.
Так вот, как сделать, чтобы из текста пост-запроса генерировалась страница с этим текстом? (Подозреваю, что это элементарно)
<?php
$bankSum = 10000;
$bankPercent = 1.1;
for ($age=16; $age < 1000; $age++) {
$time = $age - 16;
$bankSum = $bankSum * $bankPercent;
if ($bankSum >= 1000000) {
break;}
}
echo "через $time лет сумма на счёту в банке составит $bankSum, этому некто будет $age";
Помогите понять, почему мне кажется, что это неправильно? И как округлить число там полученное? Через Round не выходит.
round($bankSum)
Попробуй переменные выносить за кавычки. То-есть:
echo "через " . $time . " лет сумма на счёту в банке составит " . round($bankSum) . ", этому некто будет " . $age;
О, спасибо, получилось. Не туда round пихал.
А есть какая-нибудь практическая польза от того, что я выношу переменные за скобки? Пока я понял только, что это для того, чтобы формулы не наёбывались.
Сука, ЗА КАВЫЧКИ.
Вопрос отметается, я понял.
Да, так такие функции как round() будут работать. Пока они в кавычках - считаются текстом и просто выводятся на экран.
Тебе самому потом проще будет, некоторые текстовые редакторы не хотят делать подсветку переменных внутри кавычек.
Я бы на твоём месте ещё поменял этот участок кода:
> for ($age=16; $age < 1000; $age++)
Внутри цикла у тебя используется if как "СИГНАЛ СТОП", но проще будет изменить само условие цикла, тогда не потребуется делать дополнительных проверок.
for ($bankSum = 10000, $age = 16, $time = 0, $bankPercent = 1.1;
$bankSum <= 1000000; $bankSum *= $bankPercent)
{
$time++;
$age++;
}
То-есть все переменные обозначили в условии, затем цикл повторяется столько раз, пока сумма не будет равна миллиону
А, ну я просто перед этим прочитал в уроке, что, мол, код становится запутанным, если несколько переменных вставлять в цикл и поэтому так танцевал. Так что спасибо за информацию.
Только обобщать не надо на всех сразу. Я и джавистов/шарпистов видел таких, которые любую вордпресную пхпмакаку заставят себя почувствовать богом программирования, и никакой порог вхождения повыше им не помог.
Работаю с Йи2 на винде и локальном сервере Апачи. Возникла необходимость из скрипта (модели) создавать папку и в ней же создавать файл. Вот только файл не создается (создаю с помощью мкдир) и происходит фатальная ошибка. Что интересно, я из модели могу создать и папку и файл везде, кроме папки локального сервера. То есть в корневой директории Йи2 - уже не могу. За пределами - пожалуйста. Помогите решить.
Нет, один объект создается. Просто методы и свойства наследуются от какого-либо класса.
Уточню: в ходе проверок выяснилось, что могу создать подпапку из модели бекэнда (я использую адвансед шаблон) в любом каталоге, кроме каталога фронтэнд и, соответственно, его подкаталогов. В чём проблема?
Смотри:
<?php
class Base
{
private $test = 0;
function setPrivate($n)
{
$this->test = $n;
}
function getPrivate()
{
echo $this->test;
}
}
class Derived extends Base
{
}
$d = new Derived();
$d->setPrivate(4);
$d->getPrivate();
Смотри:
<?php
class Base
{
private $test = 0;
function setPrivate($n)
{
$this->test = $n;
}
function getPrivate()
{
echo $this->test;
}
}
class Derived extends Base
{
}
$d = new Derived();
$d->setPrivate(4);
$d->getPrivate();
>>976070
Уточню ещё раз: если модель переместить в common я всё так же могу создавать папки в бекэнде и не могу создавать во фронтэнде.
При наследовании создается новый класс на основе старого (условно говоря, берутся методы и поля из предка и к ним добавляются поля и методы наследника) Объект всегда создается один.
Это примерно то же, как если бы ты вручную скопипастил старый класс, переименовал его и дописал новые поля и методы. Только разница в том, что при наследовании сохраняется информация о том, какой класс от какого унаследован (а в случае копипасты связи между классами нет).
Ты не путаешь понятия класса и объекта? Класс - это описание, какие поля и методы будут в созданных объектах. Наследуются именно классы, а не сами объекты.
А текст и подробности ошибки? Что в логах написано?
>>975768
Ты вредный совет даешь. Какая выгода ставить кучу точек и кавычек, если можно без них?
Писать стоит либо так:
echo "Прошло $time секунд\n";
либо так, если нужны выражения:
printf("Прошло %d секунд\n", $time + 100 - $start);
Подробности про printf в мануале.
Писать в шапке много переменных плохо, код становится хуже читаем. Вот это стоит вынести наружу:
$bankSum = 10000;
$age = 16;
$bankPercent = 1.1;
Да и менять значения удобнее, когда они в начале, а не в середине программы.
из Derived
А ты задачу про таблицу умножения решил? Тебе надо лучше разобраться с циклами. Вот тебе задача в помощь:
- выведи таблицу умножения для чисел от 1 до 5:
1 x 1 = 1
1 x 2 = 2
1 x 3 = 3
...
5 x 5 = 25
- выведи в конце сумму всех получившихся чисел (1 + 2 + 3 ... + 25 = ?)
>>975725
зайди на fl.ru и посмотри задачи
>>975719
Ты что-то путаешь. "Я отправляю данные на сервер-клиент" - на сервер или на клиент? Ты вообще понимаешь ,что значит сервер и что значит клиент?
Клиент - это тот, кто запрашивает какие-то данные
Сервер - тот, кто обслуживает клиентов (serve - обслуживать) и выполняет их запросы, дает им ответы
Скрин ошибки.
Последние логи и, кажется, они не регистрируют эту ошибку.
AH00112: Warning: DocumentRoot [C:/Apache24/docs/dummy-host2.example.com] does not exist
[Wed Apr 19 00:48:10.490833 2017] [mpm_winnt:notice] [pid 1860:tid 424] AH00455: Apache/2.4.25 (Win64) PHP/7.1.2 configured -- resuming normal operations
[Wed Apr 19 00:48:10.490833 2017] [mpm_winnt:notice] [pid 1860:tid 424] AH00456: Apache Lounge VC14 Server built: Dec 17 2016 11:15:57
[Wed Apr 19 00:48:10.506459 2017] [core:notice] [pid 1860:tid 424] AH00094: Command line: 'D:\\user\\apache\\bin\\httpd.exe -d D:/user/apache'
[Wed Apr 19 00:48:10.506459 2017] [mpm_winnt:notice] [pid 1860:tid 424] AH00418: Parent: Created child process 6296
AH00112: Warning: DocumentRoot [C:/Apache24/docs/dummy-host.example.com] does not exist
AH00112: Warning: DocumentRoot [C:/Apache24/docs/dummy-host2.example.com] does not exist
AH00112: Warning: DocumentRoot [C:/Apache24/docs/dummy-host.example.com] does not exist
AH00112: Warning: DocumentRoot [C:/Apache24/docs/dummy-host2.example.com] does not exist
[Wed Apr 19 00:48:11.378009 2017] [mpm_winnt:notice] [pid 6296:tid 396] AH00354: Child: Starting 64 worker threads.
[Wed Apr 19 00:48:12.378949 2017] [mpm_winnt:notice] [pid 7036:tid 400] AH00364: Child: All worker threads have exited.
В CSS есть псевдокласс :empty - https://developer.mozilla.org/ru/docs/Web/CSS/:empty - может можно его задействовать.
Только наверно HTML придется переделать, например добавлять префикс n: через псевдоэлемент ::before.
>>975668
В твоем случае проще всего написать функцию, которая получает на вход массив с данными и выдает на выходе либо кусок SQL кода с экранированными данными через $pdo->quote(), либо кусок SQL кода с плейсхолдерами и массив значений плейсхолдеров.
Попробуй посмотреть как в Doctrine DBAL сделано:
док-я: http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/data-retrieval-and-manipulation.html#insert
код: https://github.com/doctrine/dbal/blob/master/lib/Doctrine/DBAL/Connection.php#L680
Важно написать код так, чтобы SQL-инъекция (подмена запроса) была невозможна, чтобы при любых входных данных вид запроса соответствовал задуманному.
А в общем, для построения произвольных запросов из кусков есть паттерн Query Builder: http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/query-builder.html
>>975591
Может какое-нибудь кеширование не включено?
>>975525
Тесты с вопросами на знание той или иной технологии.
>>975278
Как ты собрался писать на PHP без знания PHP?
>>975196
Я им писал пару месяцев назад, недавно ответили, что проверят, в чем проблема.
>>975191
mb-функций нет на ideone, есть на 3v4l.org
В CSS есть псевдокласс :empty - https://developer.mozilla.org/ru/docs/Web/CSS/:empty - может можно его задействовать.
Только наверно HTML придется переделать, например добавлять префикс n: через псевдоэлемент ::before.
>>975668
В твоем случае проще всего написать функцию, которая получает на вход массив с данными и выдает на выходе либо кусок SQL кода с экранированными данными через $pdo->quote(), либо кусок SQL кода с плейсхолдерами и массив значений плейсхолдеров.
Попробуй посмотреть как в Doctrine DBAL сделано:
док-я: http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/data-retrieval-and-manipulation.html#insert
код: https://github.com/doctrine/dbal/blob/master/lib/Doctrine/DBAL/Connection.php#L680
Важно написать код так, чтобы SQL-инъекция (подмена запроса) была невозможна, чтобы при любых входных данных вид запроса соответствовал задуманному.
А в общем, для построения произвольных запросов из кусков есть паттерн Query Builder: http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/query-builder.html
>>975591
Может какое-нибудь кеширование не включено?
>>975525
Тесты с вопросами на знание той или иной технологии.
>>975278
Как ты собрался писать на PHP без знания PHP?
>>975196
Я им писал пару месяцев назад, недавно ответили, что проверят, в чем проблема.
>>975191
mb-функций нет на ideone, есть на 3v4l.org
Так понять сложно, попробуй натыкать echo которое будет выводить значения переменных, и посмотреть, где значения отличаются от ожидаемых.
Также у тебя там 2 свитча для математических действий, попробуй объединить в один.
>>975183
Сам ты сталкер. Query Builder используется для сборки запроса из кусков с условиями, если запрос всегда одинаковый, то смысла его использовать нет.
То же касается и DQL, смысл тут его использовать если можно без него обойтись.
Ты вместо аккуратного запроса нагородил кучу скобок и стрелок и наверно думаешь что Query Builder придумали как замену SQL.
>>975159
Очень полезная фича. Раньше тип указывали через phpdoc вроде @return SomeClass, а теперь можно нормально на уровне языка указать.
>>975117
Во-первых, я не советую исплоьзоваь NativeSQL с маппингом. Если тебе нужен маппинг - используй DQL или Query Builder , если тебе нужно посчитать количество то можно выполнить обычный SQL запрос без маппинга, напрямую через DBAL.
Во-вторых, ассоциации в доктрине загружаются лениво. То есть они не загружаются из БД пока к ним не обратишься (если только ты не указал для них жадную загрузку).
Соответственно запрос вида
$em->find('Thread', $threadId);
выберет только одну запись из БД, и не будет выбирать посты, авторов, картинки и что там еще может быть связано с этой записью.
Для подсчета числа постов ты можешь использовать
SELECT COUNT(*) FROM posts WHERE thread_id = ?
Но еще эффективнее будет просто в треде сделать поле "число постов" и брать данные из него. Это назвается денормализация - добавление избыточных данных в базу ради повышения производительности.
Далее, тебе надо для треда получить 3 последних поста. Тут есть много вариантов:
1) через DQL делаем запрос вида
SELECT p FROM posts WHERE IDENTITY(posts.thread) = ? ORDER BY postedTime DESC
с опцией setMaxResults(3)
Это будет преобразовано в SQL запрос вида SELECT .. ORDER BY postedTime DESC LIMIT 3
Разумеется, нужен индекс по (thread_id, postedTime) для оптимальной выборки.
Этот метод позволяет выбрать 3 последних поста оптимально, но только для 1 треда. Нужно для 10 тредов - нужно 10 запросов.
2) потому можно при желании применить денормализацию и хранить в БД ссылки на 3 последних поста каждого треда. Либо в самой таблице тредов в виде id, либо в виде таблицы связи многие-ко-многим треды <-> посты. В Доктрине она оформляется как ассоциация hasMany по моему.
Это позволяет одним запросом выбрать 3 последних поста для N тредов сразу.
Тебе важно разобраться, как именно работает Доктрина. Какие она может генерировать запросы в разных случаях.
Ну например в такой ситуации:
1: $thread = $em->find('Thread', $threadId);
2: $posts = $thread->getPosts();
3: foreach ($posts as $post)
делается 2 SQL запроса:
В строчке 1 - SELECT FROM threads WHERE id = ?
В строчке 3 (да, в 3, а не в 2, так как у нас ленивая коллекция) - SELECT FROM posts WHERE thread_id = ?
Если понимать, как работает Доктрина,то станет видно что любые обращения к коллекции $posts вызовут загрузку всех постов треда в память. даже если они все нам не нужны.
>>975117
>>Тогда будет один запрос. Но на мой взгляд, это только утяжелит таблицу, и приведет к дублированию данных без особой выгоды
> Это действительно так плохо? Это решение решило бы проблему.
Ну давай взвесим:
1) если не дублировать данные. таблица будет раза в 2 меньше, но надо сделать 2 запроса которые можно объединить в 1 с помощью UNION
2) если дублировать данные, таблица будет больше, при добавлении поста надо делать больше вставок, зато мы делаем 1 запрос вместо 2.
По моему пункт 1 выгоднее. У нас ведь была цель избавиться от потенциально большого числа запросов (если цепочка постов длинная), а два запроса или один - разницы особой нет.
Так понять сложно, попробуй натыкать echo которое будет выводить значения переменных, и посмотреть, где значения отличаются от ожидаемых.
Также у тебя там 2 свитча для математических действий, попробуй объединить в один.
>>975183
Сам ты сталкер. Query Builder используется для сборки запроса из кусков с условиями, если запрос всегда одинаковый, то смысла его использовать нет.
То же касается и DQL, смысл тут его использовать если можно без него обойтись.
Ты вместо аккуратного запроса нагородил кучу скобок и стрелок и наверно думаешь что Query Builder придумали как замену SQL.
>>975159
Очень полезная фича. Раньше тип указывали через phpdoc вроде @return SomeClass, а теперь можно нормально на уровне языка указать.
>>975117
Во-первых, я не советую исплоьзоваь NativeSQL с маппингом. Если тебе нужен маппинг - используй DQL или Query Builder , если тебе нужно посчитать количество то можно выполнить обычный SQL запрос без маппинга, напрямую через DBAL.
Во-вторых, ассоциации в доктрине загружаются лениво. То есть они не загружаются из БД пока к ним не обратишься (если только ты не указал для них жадную загрузку).
Соответственно запрос вида
$em->find('Thread', $threadId);
выберет только одну запись из БД, и не будет выбирать посты, авторов, картинки и что там еще может быть связано с этой записью.
Для подсчета числа постов ты можешь использовать
SELECT COUNT(*) FROM posts WHERE thread_id = ?
Но еще эффективнее будет просто в треде сделать поле "число постов" и брать данные из него. Это назвается денормализация - добавление избыточных данных в базу ради повышения производительности.
Далее, тебе надо для треда получить 3 последних поста. Тут есть много вариантов:
1) через DQL делаем запрос вида
SELECT p FROM posts WHERE IDENTITY(posts.thread) = ? ORDER BY postedTime DESC
с опцией setMaxResults(3)
Это будет преобразовано в SQL запрос вида SELECT .. ORDER BY postedTime DESC LIMIT 3
Разумеется, нужен индекс по (thread_id, postedTime) для оптимальной выборки.
Этот метод позволяет выбрать 3 последних поста оптимально, но только для 1 треда. Нужно для 10 тредов - нужно 10 запросов.
2) потому можно при желании применить денормализацию и хранить в БД ссылки на 3 последних поста каждого треда. Либо в самой таблице тредов в виде id, либо в виде таблицы связи многие-ко-многим треды <-> посты. В Доктрине она оформляется как ассоциация hasMany по моему.
Это позволяет одним запросом выбрать 3 последних поста для N тредов сразу.
Тебе важно разобраться, как именно работает Доктрина. Какие она может генерировать запросы в разных случаях.
Ну например в такой ситуации:
1: $thread = $em->find('Thread', $threadId);
2: $posts = $thread->getPosts();
3: foreach ($posts as $post)
делается 2 SQL запроса:
В строчке 1 - SELECT FROM threads WHERE id = ?
В строчке 3 (да, в 3, а не в 2, так как у нас ленивая коллекция) - SELECT FROM posts WHERE thread_id = ?
Если понимать, как работает Доктрина,то станет видно что любые обращения к коллекции $posts вызовут загрузку всех постов треда в память. даже если они все нам не нужны.
>>975117
>>Тогда будет один запрос. Но на мой взгляд, это только утяжелит таблицу, и приведет к дублированию данных без особой выгоды
> Это действительно так плохо? Это решение решило бы проблему.
Ну давай взвесим:
1) если не дублировать данные. таблица будет раза в 2 меньше, но надо сделать 2 запроса которые можно объединить в 1 с помощью UNION
2) если дублировать данные, таблица будет больше, при добавлении поста надо делать больше вставок, зато мы делаем 1 запрос вместо 2.
По моему пункт 1 выгоднее. У нас ведь была цель избавиться от потенциально большого числа запросов (если цепочка постов длинная), а два запроса или один - разницы особой нет.
Ссылка "назад" ведет на доску.
Для прокрутки нужен яваскрипт, причем его надо будет переделывать, если в скриптах борды что-то поменяется.
>>974639
Удобный формат же. Например данные для Яндекс-Маркета в нем предоставляются.
>>974624
В Доктрине один объект = 1 строка таблицы. Если таблиц несколько, то нужно несколько объектов со связями между ними.
flush() сбрасывает в базу все изменения во всех объектах. То есть тут тебе делать ничего не надо, доктрина сама все найдет и сохранит.
>>974620
Вообще для фильтров удобно сделать объект, представляющий состояние фильтра, а не гонять туда-сюда многомерные массивы непонятной структуры.
Для произвольных выражений, может быть, придется строить дерево выражения из узлов. Стоит подумать, прежде чем за это браться. Но на массивах это будет в разы запутаннее. Это вообще как-то неправильно, использовать массив там, где лучше подходит объект.
>>974607
Полезно представить настройки фильтра в виде объекта. И передавать уже этот объект куда надо:
- в модель для поиска записей
- в шаблон для вывода формы с подставленными значениями
А городить многомерные массивы - это запутывать код.
Ссылка "назад" ведет на доску.
Для прокрутки нужен яваскрипт, причем его надо будет переделывать, если в скриптах борды что-то поменяется.
>>974639
Удобный формат же. Например данные для Яндекс-Маркета в нем предоставляются.
>>974624
В Доктрине один объект = 1 строка таблицы. Если таблиц несколько, то нужно несколько объектов со связями между ними.
flush() сбрасывает в базу все изменения во всех объектах. То есть тут тебе делать ничего не надо, доктрина сама все найдет и сохранит.
>>974620
Вообще для фильтров удобно сделать объект, представляющий состояние фильтра, а не гонять туда-сюда многомерные массивы непонятной структуры.
Для произвольных выражений, может быть, придется строить дерево выражения из узлов. Стоит подумать, прежде чем за это браться. Но на массивах это будет в разы запутаннее. Это вообще как-то неправильно, использовать массив там, где лучше подходит объект.
>>974607
Полезно представить настройки фильтра в виде объекта. И передавать уже этот объект куда надо:
- в модель для поиска записей
- в шаблон для вывода формы с подставленными значениями
А городить многомерные массивы - это запутывать код.
> [(Дд|Dd)]
Ты не понял, как работают квадратные скобки. В твоем случае это читается как "любой один из символов: скобка, буква Д, вертикальная черта". То есть в квадратных скобках ( или | это обычные символы.
> \\s\\S
Это позволяет между буквами "д" и "у" вставить любые другие буквы, например твоя регуялрка среагирует на фразу
аД кУ пиР мирА коК
Пример: https://ideone.com/QJ7KLx
Также ты забыл флаг u, без которого корректная работа с русскими буквами вообще не гарантируется.
>>974585
Можно состояние фильтра представить в виде объекта. И передавать везде этот объект. Или при желании усложнить - в виде коллекции объектов.
class PhoneFilter
{
private $isHdmi = false;
private $hasIps;
...
}
>>974463
Можно работать на винде. Можно поставить вируталку с дебианом.
Линукс изучить полезно в любом случае.
>>974448
Неправильная конструкция. Ведь getcwd получает текущий каталог процесса (не каталог где расположен файл), он может быть любым.
Надо использовать например __DIR__ или заданный в конфиге путь. Желательно все, что связано с путями, вынести куда-нибудь в класс, чтобы это было собрано в одном месте и можно было менять, не трогая остальной код.
> [(Дд|Dd)]
Ты не понял, как работают квадратные скобки. В твоем случае это читается как "любой один из символов: скобка, буква Д, вертикальная черта". То есть в квадратных скобках ( или | это обычные символы.
> \\s\\S
Это позволяет между буквами "д" и "у" вставить любые другие буквы, например твоя регуялрка среагирует на фразу
аД кУ пиР мирА коК
Пример: https://ideone.com/QJ7KLx
Также ты забыл флаг u, без которого корректная работа с русскими буквами вообще не гарантируется.
>>974585
Можно состояние фильтра представить в виде объекта. И передавать везде этот объект. Или при желании усложнить - в виде коллекции объектов.
class PhoneFilter
{
private $isHdmi = false;
private $hasIps;
...
}
>>974463
Можно работать на винде. Можно поставить вируталку с дебианом.
Линукс изучить полезно в любом случае.
>>974448
Неправильная конструкция. Ведь getcwd получает текущий каталог процесса (не каталог где расположен файл), он может быть любым.
Надо использовать например __DIR__ или заданный в конфиге путь. Желательно все, что связано с путями, вынести куда-нибудь в класс, чтобы это было собрано в одном месте и можно было менять, не трогая остальной код.
Почитай теорию, что такое "текущий каталог процесса":
http://heap.altlinux.org/issues/textbooks/linux_intro/Filesystem_use.html
https://ru.wikipedia.org/wiki/Рабочий_каталог
http://php.net/manual/ru/function.chdir.php
У каждого процесса есть "текущий каталог", он предназначен в первую очередь для того, чтобы при вызове команды не надо было указывать полный путь к файлам, с которыми она работает. Соответственно внутри твоей программы этот каталог может быть любым (он зависит от того, какой каталог был текущим когда программа была запущена). Полагаться на него нельзя.
Вот еще теория:
https://ru.wikibooks.org/wiki/UNIX#.D0.A4.D0.B0.D0.B9.D0.BB.D0.BE.D0.B2.D0.B0.D1.8F_.D1.81.D0.B8.D1.81.D1.82.D0.B5.D0.BC.D0.B0
Можно отдельный класс для отдачи файлов. Но не все можно в него помещать.
Вот допустим функция для определения полного пути к файлу. Если она нужна не только при скачивании, а где-то еще то не логично ее помещать в класс для отдачи файлов, а логично положить в какой-то вспомогательный класс, которым все могут пользоваться.
> А нормально ли будет сделать пхп-файл в котором константами будут прописаны все эти пути? Или надо как-то хитрее делать?
Лучше класс с методами, возвращающими нужные пути. Так гибче.
Потому что приватное свойство доступно только внутри одного класса. То есть в куске кода между class Base и завершающей скобкой. Если ты хочешь чтобы оно было доступно в потомках, надо было использовать protected.
Идея в том, что мы можем специально запретить доступ к нему напрямую и предоставлять доступ только через методы. Представь, если Base и Derived пишут 2 разных человека и тот кто пишет Base не хочет чтобы в поле записали что-то неправильное. Он делает поле приватным разрешает доступ только через методы. Или например этот человек, который пишет Base, не хочет заставлять второго изучать его класс целиком, а просто предоставляет готовый метод, который надо вызвать. Соответственно он помечает с помощью private то, что второму можно не смотреть.
Это называется инкапсуляция, почитай http://learn.javascript.ru/internal-external-interface
Инкапсуляция позволяет разделять код на слабосвязанные части, классы, что упрощает его понимание, когда объем кода большой.
> Вот если класс derived унаследовал от base свойство тест (приватное для родительского класса),
Свойство он унаследовал, а право доступа к нему - нет. Доступ к нему имеют только методы, унаследованные из Base.
Ограничение доступа идет именно на уровне исходного кода, то есть доступ к private возможен только из кода, находящегося внутри определения класса. Соответственно автор класса получает гарантию что никто не может обойти это ограничение снаружи. Это позволяет ему давать гарантии насчет своего класса, что он работает так, как описано в документации. То есть автор класса, если он не позволяет никому править его код, имеет полный контроль над тем, как будет работать класс, и наследование не поможет обойти заданные им правила.
Вообще, "гарантии" - это важное условие для написания надежных программ.
Кстати есть еще интересный случай, когда у нас 2 приватных поля с одинаковым именем:
class Base
{
private $a;
}
class Derived extends Base
{
private $a;
}
Изучи, как это работает. Подвох тут в том, что это не одно поле, которое переопределено, а именно 2 разных поля - Base#$a и Derived#$a. методы, описанные в Base видят первое, а методы в Derived - второе.
И опять же, это значит что класс-наследник не может обойти ограничения доступа к приватному полю.
>>976092
Это общий лог Апача. Наверно у Юи есть свой лог и он перехватывает и пишет ошибки туда. Поищи.
А вообще, причина видна, хоть твой скриншот ее не показывает, но можно там увидеть "No such file or directory" то есть ты пытаешься создать папку внутри несуществующей папки.
Я знаю что такое клиент. Ну ок, отправляю с одного сервера на другой сервер, где хостится сайт.
> кеширование не включено?
Включено, включено. Я же понимаю все. Но вообще он реально тяжелый, та же юи в 3 раза быстрее летает (а у юйки весьма средняя скорость по больнице я бы сказал). Люмен пашет шустрее юи уже, но это ж не сам ларавел. Под скоростью, конечно, имеется ввиду не только скорость обработки запроса, но и потребляемые ресурсы. И конечно все это будет не критично, если нет проблем с расширением серваков, но я как-то такой подход не одобряю. Да и не осуждаю сам ларавел, нишевая тема, удобная в некоторых местах, востребованная сейчас (юи только на легаси уже, нового почти ничего нет) просто вот не взял бы я его на свой проект, на мой взгляд есть масса решений гораздо лучше и эффективнее.
>аД кУ пиР мирА коК
>
>Пример: https://ideone.com/QJ7KLx
Переделал https://3v4l.org/7SKVK
И вот граммар нази еще https://3v4l.org/0G8MP
>Если понимать, как работает Доктрина,то станет видно что любые обращения к коллекции $posts вызовут загрузку всех постов треда в память. даже если они все нам не нужны.
Такое поведение будет и при getRepository()?
>По моему пункт 1 выгоднее. У нас ведь была цель избавиться от потенциально большого числа запросов (если цепочка постов длинная), а два запроса или один - разницы особой нет.
Но нужно сделать не два запроса, а ещё столько же сколько детей. Получается мы делаем эти запросы либо при вставке либо при получении. Только есть разница, что мы вставляем только один раз при добавлении поста, а получаем каждый раз когда пользователь получает цепочку. С такой перспективы кажется лучше 2-ой вариант.
Нагуглил регулярку: ([а-я])([А-Я]) -проверил по regex101.com - находит такое совпадение.
Пишу скрипт:
<?php
$str = 'текст васяПетя текст';
$result = preg_match_all('/([а-я])([А-Я])/', $str, $found);
echo "Matches: $result<br>";
print_r($found);
?>
Нихера не находит. Как его расклеить-то? Помогите, анончики.
Твоя регулярка найдет только по одному символу в подмаске. Тебе нужно указать что может встретиться от 1 и более символов, с помощью метасимвола +.
'/([а-я]+)([А-Я]+)/'
https://secure.php.net/manual/ru/regexp.reference.meta.php
>+ квантификатор, означающий 1 или более вхождений
> Тебе нужно указать что может встретиться от 1 и более символов, с помощью метасимвола +.
Спасибо за отклик, это уже лучше! Но почему пикрелейтед не вытаскивает второе слово?
getRepository возвращает объект репозитория и ничего не загружает из базы вообще.
> Но нужно сделать не два запроса, а ещё столько же сколько детей.
Нет, я говорил про вариант, где для построения цепочки нужно ровно 2 запроса:
1) для постов, до которых можно дойти по стрелкам в графе WHERE post = A (на которые ссылается A)
2) для постов, до которых можно дойти, идя против направления стрелок в графе WHERE reference = A (которые ссылаются на A)
Посмотри на граф со стрелками и может быть станет понятнее.
Я предлагаю сделать таблицу, где мы для каждого поста (узла в графе) указываем все посты, в которые можно дойти по стрелкам из него.
А-Я найдет ведь только буквы в верхнем регистре. По сути чтобы "раслеить" этого достаточно. Но раз уж хочешь чтобы находило целиком, то ([А-Я][а-я]плюсик) во второй части. Наверно. Не проверял.
А по хорошему тебе достаточно было бы найти из твоего склеенного говна позицию вхождения "яП", а не все сразу, что твоя первая регулярка и делает, притом там даже скобочки не нужны. С этим уже можно будет работать.
>2) для постов, до которых можно дойти, идя против направления стрелок в графе WHERE reference = A (которые ссылаются на A)
Но если пост A ссылается на пост B то нужно будет сделать запрос WHERE reference = B, и так далее.
При условии что структура такая:
>post | reference | depth
>A | B | 1
>A | C | 1
>A | D | 2
>A | E | 2
>B | D | 1
>B | E | 1
Переменные в кавычках должны парсится, вне кавычек нет. Парсинг занимает время у php. Если у тебя большие тексты, в которых переменные, то быстрее скрипт будет работать, если ты их вынесешь из кавычек.
Алсо сами кавычки на одинарные надо заменить, в них парсинга не происходит.
Если ты пишешь "быстрее", пиши насколько. Иначе ты ничем не отличаешься от маркетологов которые берут цифры с потолка в рекламе.
Анонам советую не слушать таких пустословов. ставьте такие кавычки, которые нравятся.
По твоей логике и комментарии к коду писать не стоит, ведь из парсинг занимает время у PHP? И переменные наверно не стоит называть длиннее, чем одной буквой?
Твоя программа реагирует на любую латиницу, а надо реагировать только на латинские буквы в русских словах, и на русские в латинских. То есть на слова со смешанным алфавитом. Одно из решений - написать регулярку, которая будет искать такие слова, другое - разбить текст на слова и обрабатывать их по очереди.
>>976403
А зачем ты вообще присылаешь ссылку на почту? Попробуй начать рассуждать с этого.
>>976391
Можно, она для этого и придумана, но неудобно. Прямой слеш поддерживается и в Линуксе, и в винде, проще использовать его.
Вообще, иногда полезно иметь класс с вспомогательными функциями для работы с путями, вроде склеивания путей.
Вот примеры таких библиотек (нашел на packagist.org по слову path):
- https://github.com/donutclub/php-path
- https://github.com/vweevers/php-path
- https://github.com/webmozart/path-util
>>976361
Кажется, я понял, что ты имел в виду.
Тебе надо получить все узлы в графе, которые достижимы из заданного, если идти по стрелкам в любом направлении? Тогда да, для ускорения выборки надо заранее строить их списки для каждого поста, и списки могут быть огромные. Там у тебя легко могут сотни постов набраться (нужно конечно делать тесты чтобы узнать).
> Получается мы делаем эти запросы либо при вставке либо при получении. Только есть разница, что мы вставляем только один раз при добавлении поста, а получаем каждый раз когда пользователь получает цепочку.
Ну да, либо мы строим полный список заранее, либо делаем много запросов.
Твоя программа реагирует на любую латиницу, а надо реагировать только на латинские буквы в русских словах, и на русские в латинских. То есть на слова со смешанным алфавитом. Одно из решений - написать регулярку, которая будет искать такие слова, другое - разбить текст на слова и обрабатывать их по очереди.
>>976403
А зачем ты вообще присылаешь ссылку на почту? Попробуй начать рассуждать с этого.
>>976391
Можно, она для этого и придумана, но неудобно. Прямой слеш поддерживается и в Линуксе, и в винде, проще использовать его.
Вообще, иногда полезно иметь класс с вспомогательными функциями для работы с путями, вроде склеивания путей.
Вот примеры таких библиотек (нашел на packagist.org по слову path):
- https://github.com/donutclub/php-path
- https://github.com/vweevers/php-path
- https://github.com/webmozart/path-util
>>976361
Кажется, я понял, что ты имел в виду.
Тебе надо получить все узлы в графе, которые достижимы из заданного, если идти по стрелкам в любом направлении? Тогда да, для ускорения выборки надо заранее строить их списки для каждого поста, и списки могут быть огромные. Там у тебя легко могут сотни постов набраться (нужно конечно делать тесты чтобы узнать).
> Получается мы делаем эти запросы либо при вставке либо при получении. Только есть разница, что мы вставляем только один раз при добавлении поста, а получаем каждый раз когда пользователь получает цепочку.
Ну да, либо мы строим полный список заранее, либо делаем много запросов.
> \\W*\_*
Это лучше записать как [\\W_]*
А так, верно.
Правописание
удобнее записать пары регулярка - замена так:
[
'/xxx/' => 'yyy',
'/xxx/' => 'yyy'
]
Сразу видно, что чему соответствует.
"Зделаем" не найдется.
В остальном все хорошо.
>>976155
Тебе нужно какое-то хранилище, так как ты отправляешь данные с первого сервера на второй, и второму их надо где-то сохранить, чтобы позже отдавать своим клиентам. Обычно базу данных используют для этого, хотя возможны и другие варианты.
>>976132
Возможно ты пытаешься создать папку, которая уже существует. Или возможно все-таки родительская папка не существует. Почему бы не проверить с помощью is_dir() ?
Если линукс, могут быть проблемы с правами на одну из папок в пути.
> \\W*\_*
Это лучше записать как [\\W_]*
А так, верно.
Правописание
удобнее записать пары регулярка - замена так:
[
'/xxx/' => 'yyy',
'/xxx/' => 'yyy'
]
Сразу видно, что чему соответствует.
"Зделаем" не найдется.
В остальном все хорошо.
>>976155
Тебе нужно какое-то хранилище, так как ты отправляешь данные с первого сервера на второй, и второму их надо где-то сохранить, чтобы позже отдавать своим клиентам. Обычно базу данных используют для этого, хотя возможны и другие варианты.
>>976132
Возможно ты пытаешься создать папку, которая уже существует. Или возможно все-таки родительская папка не существует. Почему бы не проверить с помощью is_dir() ?
Если линукс, могут быть проблемы с правами на одну из папок в пути.
8: https://jsfiddle.net/Lpguk5kx/
Ок, верно.
10: https://jsfiddle.net/18504y5y/3/
> text-decoration-color: #f0c000;
Это что-то новое из CSS3, я-то в общем не против, только надо смотреть уровень поддержки в браузерах: https://caniuse.com/#search=text-decoration
Пока очень мало, потому советую сделать по-старому, бордером. Ну и сайт запомни, пригодится.
Так, в общем верно.
Вообще, для задания размера картинки используется запутанная (но работающая) схема. Я бы для надежности добавил max-width 100% на figure. Оно и без него работает, но с ним как-то определенности больше становится.
Ну и отступ слева наверно стоит убрать у figure, его же вроде нет на исходной картинке.
11: https://jsfiddle.net/3qm145b4/2/
> top: -100px;
Этого на реальном сайте ведь маловато, если только там нет overflow hidden.
Вообще, хорошо сделано.
> На jsfiddle немного глючит из-за наличия посторонних элементов на странице.
Да, я знаю, но если выделить мышкой на слово "Radio" и нажать Tab, то все работает.
12: https://jsfiddle.net/qozy8zsL/7/
> .tabs-wrapper input + label
Вот это нехорошо, оно ведь подействует не только на заголовок вкладки, но и на любую пару input + label в теле вкладки. Нужно делать селектор более точечным. Например использовать класс .tab-head тут
Лучше сразу писать селекторы без побочных эффектов, чем потом искать косяки в верстке.
Так, в общем, верно.
8: https://jsfiddle.net/Lpguk5kx/
Ок, верно.
10: https://jsfiddle.net/18504y5y/3/
> text-decoration-color: #f0c000;
Это что-то новое из CSS3, я-то в общем не против, только надо смотреть уровень поддержки в браузерах: https://caniuse.com/#search=text-decoration
Пока очень мало, потому советую сделать по-старому, бордером. Ну и сайт запомни, пригодится.
Так, в общем верно.
Вообще, для задания размера картинки используется запутанная (но работающая) схема. Я бы для надежности добавил max-width 100% на figure. Оно и без него работает, но с ним как-то определенности больше становится.
Ну и отступ слева наверно стоит убрать у figure, его же вроде нет на исходной картинке.
11: https://jsfiddle.net/3qm145b4/2/
> top: -100px;
Этого на реальном сайте ведь маловато, если только там нет overflow hidden.
Вообще, хорошо сделано.
> На jsfiddle немного глючит из-за наличия посторонних элементов на странице.
Да, я знаю, но если выделить мышкой на слово "Radio" и нажать Tab, то все работает.
12: https://jsfiddle.net/qozy8zsL/7/
> .tabs-wrapper input + label
Вот это нехорошо, оно ведь подействует не только на заголовок вкладки, но и на любую пару input + label в теле вкладки. Нужно делать селектор более точечным. Например использовать класс .tab-head тут
Лучше сразу писать селекторы без побочных эффектов, чем потом искать косяки в верстке.
Так, в общем, верно.
В задаче есть массив, и он задает правило, какие буквы на какие заменяются. Проблема в том, что заменяются не все буквы, а только от а до й. Нужно шифровать и другие буквы. Также, надо дописать код для расшифровки (можно использовать array_flip).
Также в помощь тебе мануал по strtr: http://php.net/manual/ru/function.strtr.php
Для расшифровки нам надо сделать обратную замену (например менять 1 на "а"). Для этого можно перевернуть массив кодов с помощью array_flip. Попробуй это сделать и вывести получившийся массив через var_dump.
>>974246
Не работает с utf-8 и нелатинскими буквами.
>>974071
mb_strtolower
mb_strtoupper
>>974075
Квадратные скобки не требуются.
>>973866
Если ты включил режим исключений (PDO::ERRMODE_EXCEPTION, погугли) то проверять ничего не требуется. Если произойдет ошибка (например база недоступна или неверно написан запрос) то выбросится исключение и программа прервется.
В этом и плюс исключений, что тебе делать ничего не надо для их обработки. Урок https://github.com/codedokode/pasta/blob/master/php/exceptions.md
Это в mysqli надо каждый вызов проверять, а тут не надо.
Если же ты хочешь проверить, что запрос что-то нашел, хотя бы 1 запись, то это стандартно - if (count(...) > 0)
>>973871
Ничего не надо возвращать, при ошибке выбросится исключение
В задаче есть массив, и он задает правило, какие буквы на какие заменяются. Проблема в том, что заменяются не все буквы, а только от а до й. Нужно шифровать и другие буквы. Также, надо дописать код для расшифровки (можно использовать array_flip).
Также в помощь тебе мануал по strtr: http://php.net/manual/ru/function.strtr.php
Для расшифровки нам надо сделать обратную замену (например менять 1 на "а"). Для этого можно перевернуть массив кодов с помощью array_flip. Попробуй это сделать и вывести получившийся массив через var_dump.
>>974246
Не работает с utf-8 и нелатинскими буквами.
>>974071
mb_strtolower
mb_strtoupper
>>974075
Квадратные скобки не требуются.
>>973866
Если ты включил режим исключений (PDO::ERRMODE_EXCEPTION, погугли) то проверять ничего не требуется. Если произойдет ошибка (например база недоступна или неверно написан запрос) то выбросится исключение и программа прервется.
В этом и плюс исключений, что тебе делать ничего не надо для их обработки. Урок https://github.com/codedokode/pasta/blob/master/php/exceptions.md
Это в mysqli надо каждый вызов проверять, а тут не надо.
Если же ты хочешь проверить, что запрос что-то нашел, хотя бы 1 запись, то это стандартно - if (count(...) > 0)
>>973871
Ничего не надо возвращать, при ошибке выбросится исключение
Полный путь от корня диска хранить не надо, так как тогда проект не перенести в другую папку. лучше хранить путь относительно папки с файлами. Чтобы при переносе ничего не надо было менять.
В коде сделать функции которые из этого относительного пути генерируют URL и полный путь.
При скачивании в URL в конце должно стоять исходное имя файла: /download/13/файл%20файл.txt
> Также неизбежно ли отказываться от конструктора класса-модели
Удобнее конструктор без аргументов.
> и создавать отдельный метод setProperties
Можно и его, а можно свойства напрямую или через сеттеры менять.
>>973774
Названия у тебя очень неудачные и трудно понимать код. ЧТо такое TempHandler например? Непонятно. Что такое TempInterface? Комментариев тоже нет.
> $object->tempChanges()
наверно tempChanges надо в интерфейсе описать? Так как сейчас у тебя там ни одного метода не описано и значит вызывать ты тоже ничего не можешь.
> if (!empty($order->getDirty)) {
Скобки забыл
> $temp->name = 'change';
тут наверно константа нужна
> $temp->value = json_encode($tempArray);
Если можно, лучше бы в памяти хранить сам массив, а преобразовывать в JSON только в момент сохранения в БД.
https://github.com/MakeevD/MicroCrm/blob/master/app/Helpers/SearchOrders.php
тут тоже много странного, например почему фильтр записей наследуется от модели, почему куча статических методов которые явно должны быть нестатическими?
Фильтр можно было сделать в виде объекта с полями, соответствующими отдельным критериям поиска.
>>973748
Если в тайпхинте стоит интерфейс, то тебе не надо знать, какой именно класс тебе передали. Ты и не можешь это сделать, так как новые классы (реализующие интерфейс) могут быть написаны уже после написания твоего кода.
Ты должен просто вызывать методы, которые описаны в интерфейсе, а не гадать, какой именно там класс.
Подход вида if ($x instanceof Class1) не работает, так как позже могут допсать новые классы, реализующие интерфейс.
Полный путь от корня диска хранить не надо, так как тогда проект не перенести в другую папку. лучше хранить путь относительно папки с файлами. Чтобы при переносе ничего не надо было менять.
В коде сделать функции которые из этого относительного пути генерируют URL и полный путь.
При скачивании в URL в конце должно стоять исходное имя файла: /download/13/файл%20файл.txt
> Также неизбежно ли отказываться от конструктора класса-модели
Удобнее конструктор без аргументов.
> и создавать отдельный метод setProperties
Можно и его, а можно свойства напрямую или через сеттеры менять.
>>973774
Названия у тебя очень неудачные и трудно понимать код. ЧТо такое TempHandler например? Непонятно. Что такое TempInterface? Комментариев тоже нет.
> $object->tempChanges()
наверно tempChanges надо в интерфейсе описать? Так как сейчас у тебя там ни одного метода не описано и значит вызывать ты тоже ничего не можешь.
> if (!empty($order->getDirty)) {
Скобки забыл
> $temp->name = 'change';
тут наверно константа нужна
> $temp->value = json_encode($tempArray);
Если можно, лучше бы в памяти хранить сам массив, а преобразовывать в JSON только в момент сохранения в БД.
https://github.com/MakeevD/MicroCrm/blob/master/app/Helpers/SearchOrders.php
тут тоже много странного, например почему фильтр записей наследуется от модели, почему куча статических методов которые явно должны быть нестатическими?
Фильтр можно было сделать в виде объекта с полями, соответствующими отдельным критериям поиска.
>>973748
Если в тайпхинте стоит интерфейс, то тебе не надо знать, какой именно класс тебе передали. Ты и не можешь это сделать, так как новые классы (реализующие интерфейс) могут быть написаны уже после написания твоего кода.
Ты должен просто вызывать методы, которые описаны в интерфейсе, а не гадать, какой именно там класс.
Подход вида if ($x instanceof Class1) не работает, так как позже могут допсать новые классы, реализующие интерфейс.
зависит от ситуации, что это за данные, что в них может быть, что мы хотим с ними делать.
>>973465
>>973345
> [8]
Тут скобки не нужны
> \\)\\(\\-\\s
Тут ты задаешь определенный порядок, в котором идут символы. Но они могут ведь идти в любом порядке. надо написать "один из указанных символов", с помощью квадратных скобок, и добавить после этого звездочку.
> '/(\\-|\\s|\\(|\\)|)/';
Зачем тут последняя вертикальная черта? Лишняя ведь.
> /(\\+\\s7)/'
Тут стоит добавить еще что это должно быть в начале
>>973548
Я бы тут использовал IN, а недостающие пустые записи вставил на стороне PHP, если так можно делать.
>>973383
> select from A where id > (select min(id) from B)
> Сколько раз выполнится вложенный запрос? Столько, сколько строк в A? Если да, то можно ли как-то это оптимизировать?
Зависит от используемой базы данных. Некоторые умны, чтобы выполнить вложенный запрос 1 раз, некоторые нет. Проверить в MySQL план выполнения можно через EXPLAIN : https://www.google.ru/search?q=habr+explain+sql&newwindow=1&gbv=1
Оптимизировать можно с помощью переменной в PHP, выбрав первым запросом число, положив в переменную и поставив во второй запрос. В языке SQL тоже есть переменные (@x), но возможности работы сохранения данных из запроса в переменную разные в разных базах данных.
В MySQL ( https://dev.mysql.com/doc/refman/5.7/en/select-into.html ) синтаксис такой:
SELECT MIN(id) FROM table INTO @minValue;
SELECT FROM A WHERE is > @minValue;
В Postgres есть что-то такое: https://www.postgresql.org/docs/9.2/static/plpgsql-statements.html#PLPGSQL-STATEMENTS-SQL-ONEROW
зависит от ситуации, что это за данные, что в них может быть, что мы хотим с ними делать.
>>973465
>>973345
> [8]
Тут скобки не нужны
> \\)\\(\\-\\s
Тут ты задаешь определенный порядок, в котором идут символы. Но они могут ведь идти в любом порядке. надо написать "один из указанных символов", с помощью квадратных скобок, и добавить после этого звездочку.
> '/(\\-|\\s|\\(|\\)|)/';
Зачем тут последняя вертикальная черта? Лишняя ведь.
> /(\\+\\s7)/'
Тут стоит добавить еще что это должно быть в начале
>>973548
Я бы тут использовал IN, а недостающие пустые записи вставил на стороне PHP, если так можно делать.
>>973383
> select from A where id > (select min(id) from B)
> Сколько раз выполнится вложенный запрос? Столько, сколько строк в A? Если да, то можно ли как-то это оптимизировать?
Зависит от используемой базы данных. Некоторые умны, чтобы выполнить вложенный запрос 1 раз, некоторые нет. Проверить в MySQL план выполнения можно через EXPLAIN : https://www.google.ru/search?q=habr+explain+sql&newwindow=1&gbv=1
Оптимизировать можно с помощью переменной в PHP, выбрав первым запросом число, положив в переменную и поставив во второй запрос. В языке SQL тоже есть переменные (@x), но возможности работы сохранения данных из запроса в переменную разные в разных базах данных.
В MySQL ( https://dev.mysql.com/doc/refman/5.7/en/select-into.html ) синтаксис такой:
SELECT MIN(id) FROM table INTO @minValue;
SELECT FROM A WHERE is > @minValue;
В Postgres есть что-то такое: https://www.postgresql.org/docs/9.2/static/plpgsql-statements.html#PLPGSQL-STATEMENTS-SQL-ONEROW
Для подсветки текста у нажатой кнопки.
>>973135
Эти кнопки делаются на основе input radio или checkbox. Мы делаем кнопку в виде тега label, который передает клик на input, и в зависимости от состояния инпута мы подсвечиваем текст кнопки.
Пример:
<input type="checkbox" class="btn-checkbox" id="checkbox1"><label for="checkbox1" class="btn-label">Текст</label>
.btn-checkbox:checked + .btn-label { background: yellow; }
Но тут есть недостаток - надо указывать атрибуты id, for. Избавиться от них, можно положив инпут внутрь label.
Изучи селекторы + и ~.
На хабре есть статьи, гугли. Например
- https://habrahabr.ru/post/144104/
- https://habrahabr.ru/post/154719/
- https://habrahabr.ru/company/imagecms/blog/204030/
- http://dimox.name/custom-checkboxes-and-radio-buttons-using-css-only/
>>973151
тут нет связи между label и input - их надо либо вложить друг в друга либо связать через id.
Для подсветки текста у нажатой кнопки.
>>973135
Эти кнопки делаются на основе input radio или checkbox. Мы делаем кнопку в виде тега label, который передает клик на input, и в зависимости от состояния инпута мы подсвечиваем текст кнопки.
Пример:
<input type="checkbox" class="btn-checkbox" id="checkbox1"><label for="checkbox1" class="btn-label">Текст</label>
.btn-checkbox:checked + .btn-label { background: yellow; }
Но тут есть недостаток - надо указывать атрибуты id, for. Избавиться от них, можно положив инпут внутрь label.
Изучи селекторы + и ~.
На хабре есть статьи, гугли. Например
- https://habrahabr.ru/post/144104/
- https://habrahabr.ru/post/154719/
- https://habrahabr.ru/company/imagecms/blog/204030/
- http://dimox.name/custom-checkboxes-and-radio-buttons-using-css-only/
>>973151
тут нет связи между label и input - их надо либо вложить друг в друга либо связать через id.
>Тебе нужно какое-то хранилище
Ну да, можно и через базу, но это не главное.
Возможно, вы не совсем поняли мой вопрос, пожалуй упрощу его:
Как записать в файл данные из POST-запроса? Просто напишите пример кода, пожалуйста.
Поясните, зачем нужны фигурные скобки на пикрилейтед? И без них же зоебись работает
>А зачем ты вообще присылаешь ссылку на почту? Попробуй начать рассуждать с этого.
Чтобы удостовериться что почта существует, конечно же. В таком ключе становиться очевидно, что не так важно что должно содержаться в ссылке. Просто я часто видел в таких ссылках содержится какой-то хэш-код.
как заставить ничью работать нормально?
Относительно папки с файлами это значит включая ее в этом пути? /downloads/2010/10/10 или /2010/10/10
>PHP Notice: Undefined variable: playedDice2 in /home/UwjuzN/prog.php on line 13
>Молодой человек, это не для вас написано
<3
Анончики как в регулярках в утверждениях указать чтобы проверялась наличие не только одной точки/знак вопроса/восклицательный знака, но и все возможные варианты, вот такие например .../??/!!!!
> preg_split('/((?<=[.?!]))/iu', $text, 0, PREG_SPLIT_NO_EMPTY)
$newPow = function($b, $e) use (&$newPow){
if($e){
return $b * $newPow($b, $e);
} else {
return ;
}
};
echo $newPow(4, 4);
Ближайшее время (год) я буду поддерживать оба. Кодобаза будет почти одна, только я хинтинг из PHP 5.6 уберу. Какой best practice по проворачиванию такого (две параллельные ветки в пакаджисте), при условии что я не хочу версии 1.0 & 2.0, я хочу чтобы версия была одна между двумя бранчами?
То есть есть ли у меня возможность каким-то образом называть теги так, чтобы packagist вел именно параллельные версии? Вроде есть только постфикс RC для релиз кандидатов. Само собой в обоих бранчах будет свой композер.json (отличается только require для php) и настройки для CI.
Браузер он вряд ли может подвесить, скорее сервер. Попробуй поставить там echo внутри функции и выводить, с какими аргументами она вызвана.
Возможно что у тебя тут получается бесконечная рекурсия. Тогда PHP будет выполнять скрипт, пока не закончится память. Но в современных ОС используется swap, и прежде чем PHP умрет, он загоняет остальные программы в своп, что и создает ощущение что все тормозит.
https://ru.wikipedia.org/wiki/Подкачка_страниц
Как с этим бороться? Проверь такие настройки с помощью phpinfo():
- max_execution_time - ограничение на время выполнения
- memory_limit - ограничение на потребление памяти
Если у тебя установлен xdebug то доступна настройка xdebug.max_nesting_level ограничивающая глубину рекурсии. https://xdebug.org/docs/basic
Также можно открыть диспетчер задач от администратора и прибить процесс php (или apache), который потребляет много памяти и ест процессор.
>>977421
Ты изучал описание как композер работает с версиями? https://getcomposer.org/doc/articles/versions.md
Ты можешь попробовать сделать одну версию основной, а другую под тегом вроде php7 и ставить ее явным указанием ветки
"mnylibrary": "dev-php7"
Но вообще я бы советовал тебе отказаться от этой идеи. Много труда потратишь. Проще подождать пока php7 наберет долю. А проверять тип аргумента можно костылем вроде
TypeHints::assertIsString($x);
Увы, кроме ссылки на документацию, подсказать наверно ничего не могу. Ну еще есть вариант сделать 2 репозитория конечно.
> при условии что я не хочу версии 1.0 & 2.0, я хочу чтобы версия была одна между двумя бранчами?
Вот это кстати хорошая идея, сделать 2 версии. Можно для второй указать требование php7, а для первой php5, и в таком случае композер сам выберет нужную версию в зависимости от версии PHP (если указать в зависимости "mylbrary": ">= 1.0").
Я бы конечно не советовал ставить зависимости на последние версии PHP, это сужает область применения твоей библиотеки.
<?php
error_reporting(-1);
$text = "МУУ ГООУО ОПП по Удмуртинской Области объявляет конкурс на поставку кaнцелярских тoваров на сумму 100500р.";
$regexp = "/([а-яё])([a-z])([а-яё\s.])([a-z])([а-яё]*)/ui";
$match = [];
if (preg_match($regexp,$text,$match)){
echo "Опечатка с слове: {$match[1]}{$match[2]}{$match[3]}: к[а]нцелярских";
}
скажите,что надо исправить, что бы работало правильно(лол). Сформулировал, конечно, еще как,но думаю, все поняли, о чем я прошу:3
Если данных так много, то возможно их лучше поместить в отдельный csv файл. Его в том числе можно редактировать в excel/openoffice.
> Можно ли как-то указать PHPUnit считать 20 наборов входных данных за одну точку?
Тогда надо группировать данные и подавать на вход теста массив из 20 элементов.
>>977512
Можно. Но лучше наверно передать в шаблон самого пользователя, чем сервис, проверяющий залогиненность. Часто бывает такое, что какая-то переменная выводится в шапке и нужна почти на всех страницах, и тебе надо обеспечить передачу таких переменных.
Использую в форме такое описание
->add('categories', 'collection', [
'type' => 'app_executor_category',
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
])
app_executor_type:
$builder
->add('categoryCode', 'text', [
'property_path' => 'category',
]);
$builder->get('categoryCode')->addViewTransformer(
// трансформер поиска категории по коду
);
Схема app_executor_category - id, ex_id, category_id.
Суть проблемы. При передачи в форму меньшего кол-ва элементов categories чем было в предыдущем сохранении - получал записи в БД c null. Добавил 'allow_delete' => true, эта проблема ушла.
Осталась следующая: если в следующем сохранении в массиве элементы поменяются местами
categories[0][categoryCode]=sports&categories[1][categoryCode]=food
в
categories[0][categoryCode]=food&categories[1][categoryCode]=sports
получаю ошибку duplicate entry из sql, потому что в categories пападают записи под существующими id, но в первой лежит id второй категории, а во второй - первой, и когда они сохраняются - при любом раскладе будет дублированная запись в бд.
Использую в форме такое описание
->add('categories', 'collection', [
'type' => 'app_executor_category',
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
])
app_executor_type:
$builder
->add('categoryCode', 'text', [
'property_path' => 'category',
]);
$builder->get('categoryCode')->addViewTransformer(
// трансформер поиска категории по коду
);
Схема app_executor_category - id, ex_id, category_id.
Суть проблемы. При передачи в форму меньшего кол-ва элементов categories чем было в предыдущем сохранении - получал записи в БД c null. Добавил 'allow_delete' => true, эта проблема ушла.
Осталась следующая: если в следующем сохранении в массиве элементы поменяются местами
categories[0][categoryCode]=sports&categories[1][categoryCode]=food
в
categories[0][categoryCode]=food&categories[1][categoryCode]=sports
получаю ошибку duplicate entry из sql, потому что в categories пападают записи под существующими id, но в первой лежит id второй категории, а во второй - первой, и когда они сохраняются - при любом раскладе будет дублированная запись в бд.
обязательно ли усложнять задачу, добавляя купюры 200 и 2000 и добиваясь минимума выдаваемых купюр или можно дальше продолжать решать задачки. просто перешел по ссылке по решению рюкзаков и монет и испугался словосочетания "реккурентная формула"
Сайт работал в кодировке UTF-8. Конфигурация сервера не соответствует требованиям.
Для продолжения установите настройки PHP: mbstring.func_overload=2 и mbstring.internal_encoding=UTF-8.
Что значит "не сохраняется"? Ты отредактировал файл, открыл заново и там нет твоих изменений? У тебя может прав нужных нет?
После редактирования php.ini надо перезапустить apache или php-fpm, в зависимости от того, что используется.
Проверить конфигурацию можно с помощью phpinfo()
Ну и конечно func_overload - это максимальный быдлокодинг (проблема в том, что с ним часть функций начинают поддерживать utf-8, а часть - нет, и очень легко запутаться). К тому же в документации написано, что эта опция устарела (ну наконец-то): http://php.net/manual/ru/mbstring.overload.php
>>977810
Не знаю, я же не психолог. Но могу сказать, что если ты не можешь освоить регулярки, то ты в более сложных темах дальше вряд ли разберешься.
А что именно тебе кажется сложным? Регулярка это ведь всего лишь шаблон для поиска текста, где можно использовать специальные символы вроде "любая буква".
Если ты читаешь наш учебник, попробуй погуглить и почитать другие статьи. Ключевые слова - "регулярные выражения pcre", "регулярные выражения в php"
>>mb-функций нет на ideone, есть на 3v4l.org
не понимаю и туда запилил Лиличку https://3v4l.org/h3E9h, тоже только знаки вопроса вылазят. Допоможить!
https://github.com/codedokode/pasta/blob/master/php/strings-utf8.md
ты почему-то решил что $string[0] вернет первую букву строки. Но это не так, $string[0] это только первый байт из строки, а буква состоит из нескольких байт и при попытке его отобразить получается вопросик.
Используй mb_substr.
спасибо, понял промах
Тут надо искать слова, содержащие буквы из разных алфавитов. То есть слова, где рядом есть буквы из 2 разных алфавитов. Получается такое выражение:
(любые буквы, 1 русская буква, 1 латинская буква, любые буквы)
или
(любые буквы, 1 латинская буква, 1 русская буква, любые буквы)
У тебя примерно то же по сути, но добавлено лишнее и не рассматривается вариант, когда слово состоит из латинских букв и содержит одну русскую.
спасибо :3
Если у тебя 6 тыс наборов данных, то ты что-то делаешь не так. Обычно все граничные случаи покрываются максимум 10 наборами.
Invalid request (Unexpected EOF). Как это фиксить и чем чревато?
там пермутации же. Мне нужно покрыть все варианты входных данных.
Допустим, первый параметр может быть в четырёх состояниях, второй — тоже, это уже 16, и так далее. Какой конкретно сбойнёт никто не скажет. Тесты для этого и нужны, чтобы все случаи покрыть. Если тесты пишутся под конкретную ошибку имлементации, возникшую в прошлый раз, это плохие тесты. Потому что после рефакторинга они пропустят новую ошибку
Синтаксис в целом знаю, учебник опа проходил несколько лет назад, недавно освежил свои знания на кодакадемии.
Писать гостевуху и борду достаточно глупые вещи. Делай задачи из ОП поста, сначала список студентов, потом файлообменник.
Что есть: Я одминю юнкисы лет пять, не вылажу из консоли, хорошо умею в баш, умею в питон, понимаю как работает лапм, могу поднять и сконфижить мускуль с апачем. Фронтенд тоже в целом представляю как работает.
Чего нет: Я совершенно не работал с ПХП. Я только в теории понимаю ООП и СКЛ, опыт работы с ними эпизодический.
Чего надо: Поддерживать и в идеале отрефакторить местную самописную систему учёта. Поднять уровень пхп, рассмотреть сценарии применения.
Я пролистал по диагонали Трахтенберга, но без практики всё вылетает из головы. Хочу пробежаться по кодакадеми, или аналогу, чтобы руки набить, прежде чем к реальному коду прикасаться. Или сразу за студентов приниматься?
Чтоб и не нудное чтиво на полгода, но и знания базовые получить
В ОП-посте есть ссылка, нужно было его читать перед тем как задавать вопрос.
https://github.com/codedokode/pasta/blob/master/soft/web-server.md
CREATE TABLE student
( name VARCHAR(30),
surname VARCHAR(30),
gender VARCHAR(30),
group VARCHAR(5),
mail VARCHAR(20),
score SMALLINT UNSIGHNED,
yearofbirth YEAR,
placeofbirth VARCHAR(10),
password VARCHAR(40));
и вылезает вот это:
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near 'group
VARCHAR(5),
mail VARCHAR(20),
score SMALLINT UNSIGHNED,
yearofbirth' at line 5
Как фиксить?
Ну так почитай, что в ошибке. Слово 'group' зарезервировано MySQL. Я знаю 2 способа обойти:
- назвать столбец как-то по-другому, например student_group
- поменять group на `group`
1. Уроки по 20-50 минут в среднем, многое затянуто, по самому ларавелю смотрю первую часть, но пока ее досмотришь, дипломный проект сделаешь к пенсии. Думаю начать сразу с практической части.
2. В некоторых моментах особенно ларавел коверкается произношение заморского. Ретурн, фолсе и много еще замечательного. Не граммарнацик, но все же.
гений торрент преступлений
var data1 = new FormData();
$.each( files, function( key, value ){
data1.append( key, value );
});
И отправляю с параметрами:
data: data1,
dataType: 'json',
А принимаю с
if( isset( $_GET['uploadfiles'] ) ){
и так далее. Так вот, нифига не догоняю, как послать две переменных: файл и строку. Обычно я использую на php-стороне такой код для разбора:
$value = array ();
$i = 0;
while(list ($key, $val) = each ($_POST)){
$value[$i] = $val;
$i = $i + 1;
}
$date1 = $value[0];
но тут он не прокатывает.
Как это можно разрулить?
class Student{
public $data = new StudentTableGateway;
}
Ошибка такая:
Parse error: syntax error, unexpected 'new' (T_NEW)
Так нельзя. Вообще, зависимости нужно не хардкодить, а передевать сверху, в качестве аргумента конструктора: https://github.com/codedokode/pasta/blob/master/arch/di.md
IDE умеют генерировать поля на основе переданных аргументов, если тебя не устраивает многословность PHP.
Алсо зачем в сущности объект TableGateway, это ты ActiveRecord и TableGateway смешать в кучу пытаешься?
>>978248
На реддите о нём почти никто ничего не пишет, на апворке тоже мало предложений по Yii.
$name = trim(htmlspecialchars($_POST["name"]));
какие нужно ещё использовать функции?
>Алсо зачем в сущности объект TableGateway
Я хотел реализовать паттерн TDG, но как использовать его с самой моделью я не понял, видимо мне Dependency Injection нужно курить
То, что ты написал, вообще никакого отношения к SQL-инъекциям не имеет. Тебе надо сначала разобраться, что это такое и почему возникает уязвимость. Сейчас же ты просто поставил какие-то функции наугад, не думая, что они делают. Так не годится, начни с урока: https://github.com/codedokode/pasta/blob/master/security/sql-injection.md а потом еще почитай мануал по использованным тобой функциям.
>>979418
Не стоит. У каждой формы скорее всего свои правила обработки данных и общий код для них написать не получится. Алсо почитай про MVC и про работу с формами
https://github.com/codedokode/pasta/blob/master/forms.md
https://github.com/codedokode/pasta/blob/master/arch/mvc.md
>>979414
Это за рубежом, а в русскоязычных странах он довольно популярен.
>>979382
В PHP в качестве значения поля по умолчанию нельзя указывать что угодно, а только константные значения (числа, строки, массивы, другие константы и тд).
>>979230
А ты понимаешь, что делает каждая строчка в твоем коде? Тебе надо не искать готовое решение, а изучить то, что ты используешь. То есть для начала прочти мануал по:
- FormData
- jquery.ajax()
- мануал PHP про загрузку файлов http://php.net/manual/ru/features.file-upload.php
А так, если ты не представляешь, как этот код работает, как ты его дальше развивать будешь?
>>979133
это значит eval
То, что ты написал, вообще никакого отношения к SQL-инъекциям не имеет. Тебе надо сначала разобраться, что это такое и почему возникает уязвимость. Сейчас же ты просто поставил какие-то функции наугад, не думая, что они делают. Так не годится, начни с урока: https://github.com/codedokode/pasta/blob/master/security/sql-injection.md а потом еще почитай мануал по использованным тобой функциям.
>>979418
Не стоит. У каждой формы скорее всего свои правила обработки данных и общий код для них написать не получится. Алсо почитай про MVC и про работу с формами
https://github.com/codedokode/pasta/blob/master/forms.md
https://github.com/codedokode/pasta/blob/master/arch/mvc.md
>>979414
Это за рубежом, а в русскоязычных странах он довольно популярен.
>>979382
В PHP в качестве значения поля по умолчанию нельзя указывать что угодно, а только константные значения (числа, строки, массивы, другие константы и тд).
>>979230
А ты понимаешь, что делает каждая строчка в твоем коде? Тебе надо не искать готовое решение, а изучить то, что ты используешь. То есть для начала прочти мануал по:
- FormData
- jquery.ajax()
- мануал PHP про загрузку файлов http://php.net/manual/ru/features.file-upload.php
А так, если ты не представляешь, как этот код работает, как ты его дальше развивать будешь?
>>979133
это значит eval
В ОП посте есть учебник, полистай его, и найди те задачи, которые ты с ходу не можешь решить, и решай их. Там же есть глава по ООП.
Также, желательно прочесть мануал https://secure.php.net/manual/ru/langref.php
Далее, решай студентов из ОП поста, к ним много подробных комментариев.
Кодеакадеми - там очень базовый, ознакомительный уровень, его хватит для написания скрипта на 20 строк, но не для большой системы. И это же относится ко многим книгам "для начинающих".
>>978237
Примерно того же уровня что и студенты. Тоже простая система с парой таблиц в БД и формами.
>>978207
Не, на практике покрыть все случаи обычно нереально. Потому тестируют отдельные кейсы, вроде "если пользователь ввел неправильный email, форма должна отобразитоь ошибку".
Тесты обычно пишут по требованиям, про ТЗ. Если там написано "пользователь должен заполнить имя, email и придумать пароль для регистрации", то мы из этого делаем позитивные/негативные сценарии (заполнил, не заполнил, заполнил неправильно) и тестируем.
Полностью покрыть все комбинации входных данных обычно нереально, или неоправданно долго/дорого. Тесты не гарантируют что все 100% корректно, их задача - отлавливать случайные ошибки в добросовестно написанном коде.
>>978084
В веб-сервере для командной строки? Скорее всего никак не надо, это просто браузер отменил запрос и разорвал соединение.
> $biggest=mb_strlen(max($text_arr));
Неправильно. max() выстраивает строки по возрастанию байт, которыми они кодируются, и берет ту, в которой первый байт максимален. Соответственно для строк: ['abram', 'z'], max() вернет 'z' потому что в utf-8 код для 'z' больше чем для 'a'.
Если интересно, вот правильное сравнение строк по алфавиту, но тут оно не нужно: https://github.com/codedokode/pasta/blob/master/php/collation.md
> $text_arr
Плохое название, не надо в переменной писать ее тип, и не надо использовать подчеркивание. Правильнее назвать $lines (строки).
В остальном верно.
>>977748
Не то чтобы обязательно, но на этой задаче можно научиться реализовывать алгоритмы на языке программирования. Советовал бы выделить время и помучаться.
"рекуррентная" - значит что это последовательность, где следующий член последовательности выражается через предыдущий (или предыдущие). https://ru.wikipedia.org/wiki/Рекуррентная_формула
Ну например рекуррентная формула для последовательности натуральных чисел 1, 2, 3...:
x[1] = 1; // последовательность начинается с единицы
x[n] = x[n - 1] + 1; // следующий член на 1 больше предыдущего
В программе у тебя есть проблема: слишком большие блоки в if и к тому же они еще и сильно вложены. Лучше сделать так:
if ($total_sum < $amount){
echo "Выдача невозможна: недостаточно средств в терминале\n";
exit();
}
....
> $quantity_5000=
> $quantity_1000=
> $quantity_500
Это копипаста, так не пойдет, надо обойтись без нее. Нельзя просто бездумно копировать код, надо подумать, как избавиться от повторов. Хотелось бы чтобы номиналы купюр задавались в массиве в начале программы и их можно было бы менять, не трогая код. А то если у нас будет 10 номиналов купюр, ты 10 блоков кода что ли будешь копипастить?
> $biggest=mb_strlen(max($text_arr));
Неправильно. max() выстраивает строки по возрастанию байт, которыми они кодируются, и берет ту, в которой первый байт максимален. Соответственно для строк: ['abram', 'z'], max() вернет 'z' потому что в utf-8 код для 'z' больше чем для 'a'.
Если интересно, вот правильное сравнение строк по алфавиту, но тут оно не нужно: https://github.com/codedokode/pasta/blob/master/php/collation.md
> $text_arr
Плохое название, не надо в переменной писать ее тип, и не надо использовать подчеркивание. Правильнее назвать $lines (строки).
В остальном верно.
>>977748
Не то чтобы обязательно, но на этой задаче можно научиться реализовывать алгоритмы на языке программирования. Советовал бы выделить время и помучаться.
"рекуррентная" - значит что это последовательность, где следующий член последовательности выражается через предыдущий (или предыдущие). https://ru.wikipedia.org/wiki/Рекуррентная_формула
Ну например рекуррентная формула для последовательности натуральных чисел 1, 2, 3...:
x[1] = 1; // последовательность начинается с единицы
x[n] = x[n - 1] + 1; // следующий член на 1 больше предыдущего
В программе у тебя есть проблема: слишком большие блоки в if и к тому же они еще и сильно вложены. Лучше сделать так:
if ($total_sum < $amount){
echo "Выдача невозможна: недостаточно средств в терминале\n";
exit();
}
....
> $quantity_5000=
> $quantity_1000=
> $quantity_500
Это копипаста, так не пойдет, надо обойтись без нее. Нельзя просто бездумно копировать код, надо подумать, как избавиться от повторов. Хотелось бы чтобы номиналы купюр задавались в массиве в начале программы и их можно было бы менять, не трогая код. А то если у нас будет 10 номиналов купюр, ты 10 блоков кода что ли будешь копипастить?
ок, верно.
>>977633
А что у тебя там за связи? Многие-ко-многим между categories и executor? Ты не пробовал сделать как тут описано ( http://symfony.com/doc/2.7/form/form_collections.html )? В частности, посмотри пункт "Doctrine: Ensuring the database persistence" в конце.
Также, в Доктрине прописаны связи между category и executor как многие-ко-многим?
>>977180
> Анончики как в регулярках в утверждениях указать чтобы проверялась наличие не только одной точки/знак вопроса/восклицательный знака, но и все возможные варианты, вот такие например .../??/!!!!
Использовать второе утверждение, проверяющее что дальше идет не знак препинания:
(?<=[.,])(?![.,]) - соответствует позиции после точкой или запятой, за которой нет другой точки или запятой.
Решено верно.
>>977068
Можно включать, можно не включать.
>>977026
А зачем нужен хеш? Чтобы доказать, что пользователь действительно получил ссылку, а не пытается подтвердить несуществующий ящик, мы генерируем сложный случайный код (не хеш, с чего ты решил, что это результат хеш-функции?), и просим пользователя его предъявить как подтверждение владения почтовым ящиком. Злоумышленник не может угадать код.
ок, верно.
>>977633
А что у тебя там за связи? Многие-ко-многим между categories и executor? Ты не пробовал сделать как тут описано ( http://symfony.com/doc/2.7/form/form_collections.html )? В частности, посмотри пункт "Doctrine: Ensuring the database persistence" в конце.
Также, в Доктрине прописаны связи между category и executor как многие-ко-многим?
>>977180
> Анончики как в регулярках в утверждениях указать чтобы проверялась наличие не только одной точки/знак вопроса/восклицательный знака, но и все возможные варианты, вот такие например .../??/!!!!
Использовать второе утверждение, проверяющее что дальше идет не знак препинания:
(?<=[.,])(?![.,]) - соответствует позиции после точкой или запятой, за которой нет другой точки или запятой.
Решено верно.
>>977068
Можно включать, можно не включать.
>>977026
А зачем нужен хеш? Чтобы доказать, что пользователь действительно получил ссылку, а не пытается подтвердить несуществующий ящик, мы генерируем сложный случайный код (не хеш, с чего ты решил, что это результат хеш-функции?), и просим пользователя его предъявить как подтверждение владения почтовым ящиком. Злоумышленник не может угадать код.
Вряд ли, хотя может быть для какой-то части сайтов получится написать алгоритм.
>>976826
Чтобы отделить выражение от остальной части строки: http://php.net/manual/ru/language.types.string.php#language.types.string.parsing
Они не обязательны.
>>976751
Нет, я пример кода писать за тебя не хочу.
>>974013
Не делай кеширование, если у тебя товары обновляются часто. Посылай новый запрос при каждой введенной букве (с небольшой задержкой, если быстро печатают).
> Т.е., допустим, по фокусу на инпут идёт один запрос на сервер
На фокус ничего делать не требуется, только при нажатии клавиш.
> откуда в потоке приходят записи и колбэком заносятся в общий селект.
Не надо изобретать велосипед, уже есть селекты на JS которые работают с аякс-запросами: select2, chosen.
>>973867
Если это объект из DOM или SimpleXmlElement, то там есть методы, поищи в мануале.
>>973811
В базе ты хранишь путь вместе с датой. А расположение папки download задаешь в конфиге или в коде.
>>973499
В CSS есть анимация и transition (переходы).
Вряд ли, хотя может быть для какой-то части сайтов получится написать алгоритм.
>>976826
Чтобы отделить выражение от остальной части строки: http://php.net/manual/ru/language.types.string.php#language.types.string.parsing
Они не обязательны.
>>976751
Нет, я пример кода писать за тебя не хочу.
>>974013
Не делай кеширование, если у тебя товары обновляются часто. Посылай новый запрос при каждой введенной букве (с небольшой задержкой, если быстро печатают).
> Т.е., допустим, по фокусу на инпут идёт один запрос на сервер
На фокус ничего делать не требуется, только при нажатии клавиш.
> откуда в потоке приходят записи и колбэком заносятся в общий селект.
Не надо изобретать велосипед, уже есть селекты на JS которые работают с аякс-запросами: select2, chosen.
>>973867
Если это объект из DOM или SimpleXmlElement, то там есть методы, поищи в мануале.
>>973811
В базе ты хранишь путь вместе с датой. А расположение папки download задаешь в конфиге или в коде.
>>973499
В CSS есть анимация и transition (переходы).
Хороший вопрос про https://www.owasp.org/index.php/AJAX_Security_Cheat_Sheet#Always_return_JSON_with_an_Object_on_the_outside
Сории, что сразу не ответил. Здесь речь об уязвимости которая позволяет обойти ограничения на получение данных с другого домена. Допустим есть домен good.example.com, на котором залогинен пользователь, и на нем есть URL, который отдает важную информацию о пользователе в формате JSON: good.example.com/userinfo
Получить информацию можно только из браузера пользователя, так как для доступа к ней нужна авторизация через куки.
Злоумышленник владеет сайтом на домене example.evil и хотел бы при заходе пользователя получить эту информацию с good.example.com. Просто так отправить аякс-запрос со страницы он не может, так как браузер не позволяет получить ответ с другого домена. Отправить запрос он может (как GET, так и POST - через подключение картинки или отправку формы), а прочесть ответ - нет.
Однако, злоумышленник может подключить JS скрипт с другого домена на своем сайте, при этом браузер отправит запрос и выполнит содержимое ответа как JS-код. То есть злоумышленник пишет у себя на сайте
<script src="//good.example.com/userinfo"></script>
При этом браузер отправит запрос, получит JSON-ответ такого вида:
['secret_info', 'secret_info2', ...]
и попытается его выполнить как JS-код. Так как JSON почти является подмножеством JS, то JSON почти всегда является валидным JS-кодом. И не вызовет ошибки. Но и данные злоумышленник, казалось бы, не получит.
Однако, тут есть лазейка. В JS массив - это объект с конструктором window.Array. Когда ты пишешь var x = [1, 2];, в реальности происходит вызов конструктора как new Array(1, 2). Злоумышленник может перед подключением скрипта заменить конструктор на свою функцию, которая перехватит данные:
window.Array = function(data) { ... };
И браузер при выполнени JSON-кода, содержащего массив, вызовет функцию злоумышленника и передаст в нее содержимое массива. Таким образом, злоумышленник обойдет ограничения на доступ к данным с другого домена и похитит данные пользователя. Там вполне могут быть например какие-то персональные данные, или данные, нужные для входа на сайт. Ну или, злоумышленник может деанонимизировать пользователя по его логину на другом сайте.
В качестве меры защиты раньше предлагалось вставлять в начало ответа синтаксически некорретный кусок кода, чтобы он вызвал ошибку при попытке выполнить его как яваскрипт. Но тогда ответ конечно перестанет быть JSON-ом.
Вот пример, когда эта уязвимость была в gmail: http://blog.jeremiahgrossman.com/2006/01/advanced-web-attack-techniques-using.html и позволяла узнать имя и email пользователя.
Вот еще по теме:
- http://stackoverflow.com/questions/3146798/why-do-people-put-code-like-throw-1-dont-be-evil-and-for-in-front-of
- http://stackoverflow.com/questions/3503102/what-are-top-level-json-arrays-and-why-are-they-a-security-risk
- http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx/
- http://www.ninoishere.com/json-hijacking/
- http://ejohn.org/blog/re-securing-json/
- https://bugzilla.mozilla.org/show_bug.cgi?id=376957
Использование объекта вместо массива { ... } делает JSON не валидным JS кодом.
В Хроме сейчас создание массива через литерал [1, 2] не приводит к вызову подмененного конструктора, если его переопределить.
Стандарт ES5: http://es5.javascript.ru/x11.html#x11.1.4
> 1. Пусть array("массив") будет результатом создания нового объекта, как если бы этот объект был создан выражением new Array(), где Array является стандартным встроенным конструктором с этим именем.
То же самое там написано и про литерал объекта - вызывается встроенный конструктор Object.
Вообще, первопричина такой уязвимости - это возможность обходить кросс-доменные ограничения через подключение скриптов. Если тебе интересно, есть еще такие лазейки, существующие с давних времен:
- подключение iframe с другого домена (тут по идее разграничение должно работать, но кто знает что там можно найти)
- подключение картинок, стилей, скриптов с другого домена
- отправка форм и XHR на другой домен
Для других типов, веб-шрифтов, например, выдается ошибка при попытке подключить шрифты с другого домена.
Хороший вопрос про https://www.owasp.org/index.php/AJAX_Security_Cheat_Sheet#Always_return_JSON_with_an_Object_on_the_outside
Сории, что сразу не ответил. Здесь речь об уязвимости которая позволяет обойти ограничения на получение данных с другого домена. Допустим есть домен good.example.com, на котором залогинен пользователь, и на нем есть URL, который отдает важную информацию о пользователе в формате JSON: good.example.com/userinfo
Получить информацию можно только из браузера пользователя, так как для доступа к ней нужна авторизация через куки.
Злоумышленник владеет сайтом на домене example.evil и хотел бы при заходе пользователя получить эту информацию с good.example.com. Просто так отправить аякс-запрос со страницы он не может, так как браузер не позволяет получить ответ с другого домена. Отправить запрос он может (как GET, так и POST - через подключение картинки или отправку формы), а прочесть ответ - нет.
Однако, злоумышленник может подключить JS скрипт с другого домена на своем сайте, при этом браузер отправит запрос и выполнит содержимое ответа как JS-код. То есть злоумышленник пишет у себя на сайте
<script src="//good.example.com/userinfo"></script>
При этом браузер отправит запрос, получит JSON-ответ такого вида:
['secret_info', 'secret_info2', ...]
и попытается его выполнить как JS-код. Так как JSON почти является подмножеством JS, то JSON почти всегда является валидным JS-кодом. И не вызовет ошибки. Но и данные злоумышленник, казалось бы, не получит.
Однако, тут есть лазейка. В JS массив - это объект с конструктором window.Array. Когда ты пишешь var x = [1, 2];, в реальности происходит вызов конструктора как new Array(1, 2). Злоумышленник может перед подключением скрипта заменить конструктор на свою функцию, которая перехватит данные:
window.Array = function(data) { ... };
И браузер при выполнени JSON-кода, содержащего массив, вызовет функцию злоумышленника и передаст в нее содержимое массива. Таким образом, злоумышленник обойдет ограничения на доступ к данным с другого домена и похитит данные пользователя. Там вполне могут быть например какие-то персональные данные, или данные, нужные для входа на сайт. Ну или, злоумышленник может деанонимизировать пользователя по его логину на другом сайте.
В качестве меры защиты раньше предлагалось вставлять в начало ответа синтаксически некорретный кусок кода, чтобы он вызвал ошибку при попытке выполнить его как яваскрипт. Но тогда ответ конечно перестанет быть JSON-ом.
Вот пример, когда эта уязвимость была в gmail: http://blog.jeremiahgrossman.com/2006/01/advanced-web-attack-techniques-using.html и позволяла узнать имя и email пользователя.
Вот еще по теме:
- http://stackoverflow.com/questions/3146798/why-do-people-put-code-like-throw-1-dont-be-evil-and-for-in-front-of
- http://stackoverflow.com/questions/3503102/what-are-top-level-json-arrays-and-why-are-they-a-security-risk
- http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx/
- http://www.ninoishere.com/json-hijacking/
- http://ejohn.org/blog/re-securing-json/
- https://bugzilla.mozilla.org/show_bug.cgi?id=376957
Использование объекта вместо массива { ... } делает JSON не валидным JS кодом.
В Хроме сейчас создание массива через литерал [1, 2] не приводит к вызову подмененного конструктора, если его переопределить.
Стандарт ES5: http://es5.javascript.ru/x11.html#x11.1.4
> 1. Пусть array("массив") будет результатом создания нового объекта, как если бы этот объект был создан выражением new Array(), где Array является стандартным встроенным конструктором с этим именем.
То же самое там написано и про литерал объекта - вызывается встроенный конструктор Object.
Вообще, первопричина такой уязвимости - это возможность обходить кросс-доменные ограничения через подключение скриптов. Если тебе интересно, есть еще такие лазейки, существующие с давних времен:
- подключение iframe с другого домена (тут по идее разграничение должно работать, но кто знает что там можно найти)
- подключение картинок, стилей, скриптов с другого домена
- отправка форм и XHR на другой домен
Для других типов, веб-шрифтов, например, выдается ошибка при попытке подключить шрифты с другого домена.
Не знаю, может и не подойдут если рассчитаны на конкретную версию API.
>>967048
>>967050
> function inclineWord($number, $type) {
Тут идея с массивом не очень удачная, так как у тебя получилась фукнция, умеющая склонять только 3 слова, лучше было просто передавать в функцию возможные формы слов, а она выберет нужную. А так ты зачем-то туда еще и точку засунул. Какое отношение точка имеет к выбору формы слова? Это не задача этой функции, ставить точки.
Также, у тебя переменная $type привязана по смыслу к функции numberToText, что тоже плохо, лучше если функции независимы друг от друга, а не спутаны вместе.
> $words[0] =
Вместо явного указания индекса лучше использовать $words[] = ...
> $numbers = array();
> $numbers[0] = floor($number / 1000000);
> $numbers[1] = floor(($number % 1000000)/1000);
> $numbers[2] = $number % 1000;
Можно еще так писать:
$numbers = [
floor($number / 1000000),
floor(($number % 1000000)/1000),
...
];
> function numberToText($number) {
> if ($number <> 0){
Тут if слишком огромный и занимает почти всю функцию, надо поменять в нем условие на противоположное.
> $finalArray[$i]
Тут лучше просто [] вместо [$i]
> function getFinalWord
Название плохое, лучше getWordFormNumber
> function checking($number){
Название неправильное, непонятно что значит.
> function spellSmallNumber($number){
название не соответствует содержимому
>>966920
Слишком много кода для простой задачи. Например это повторяется 2 раза: $credit*$percent+$service
> $total=$total+$pay;
используй тут +=
> if($credit+$service<$pay) {
Тут не учтен процент от долга.
Не знаю, может и не подойдут если рассчитаны на конкретную версию API.
>>967048
>>967050
> function inclineWord($number, $type) {
Тут идея с массивом не очень удачная, так как у тебя получилась фукнция, умеющая склонять только 3 слова, лучше было просто передавать в функцию возможные формы слов, а она выберет нужную. А так ты зачем-то туда еще и точку засунул. Какое отношение точка имеет к выбору формы слова? Это не задача этой функции, ставить точки.
Также, у тебя переменная $type привязана по смыслу к функции numberToText, что тоже плохо, лучше если функции независимы друг от друга, а не спутаны вместе.
> $words[0] =
Вместо явного указания индекса лучше использовать $words[] = ...
> $numbers = array();
> $numbers[0] = floor($number / 1000000);
> $numbers[1] = floor(($number % 1000000)/1000);
> $numbers[2] = $number % 1000;
Можно еще так писать:
$numbers = [
floor($number / 1000000),
floor(($number % 1000000)/1000),
...
];
> function numberToText($number) {
> if ($number <> 0){
Тут if слишком огромный и занимает почти всю функцию, надо поменять в нем условие на противоположное.
> $finalArray[$i]
Тут лучше просто [] вместо [$i]
> function getFinalWord
Название плохое, лучше getWordFormNumber
> function checking($number){
Название неправильное, непонятно что значит.
> function spellSmallNumber($number){
название не соответствует содержимому
>>966920
Слишком много кода для простой задачи. Например это повторяется 2 раза: $credit*$percent+$service
> $total=$total+$pay;
используй тут +=
> if($credit+$service<$pay) {
Тут не учтен процент от долга.
При использовании TDG класс Student не знает о TDG, а вот TDG знает про Student и создает его при надобности.
Ты не путаешь модель студента и класс StudentTDG? Это 2 разных класса, первый представляет информацию об одном студенте, второй - умеет работать с базой данных.
>>979491
Ты тестируешь регулярку на regex101, и когда она будет работать верно, переносишь ее в скрипт и тестируешь все еще раз.
Ты не обязан использовать regex101, но по моему на нем отлаживать регулярку быстрее, чем каждый раз править и запускать код.
>>979501
Ограничители там уже стоят и их писать не надо.
Вот пример выражения: https://regex101.com/r/jmRKQL/1/
Вверху пишешь регулярку, внизу текст и он подсвечивает все фрагменты текста, соответствующие регулярке.
Добавь флаг m если хочешь, чтобы ^ соответствовал началу каждой строки, а не только началу текста.
>>979510
Есть синтаксис INSERT в MySQL (нестандартный) для вставки нескольких строк, погугли.
>а вот TDG знает про Student и создает его при надобности
То есть модель передаёт только нужные свойства и в ней хранятся только они? А если я захочу написать какой нибудь метод не связанный с работой в бд, мне его в TDG делать? Ведь я думал что TDG на то и нужен чтобы не мешать работу бд с другими методами, которые будут в модели.
Запутался я вобщем
Для чего по твоему нужен TDG?
Что такое по твоему модель? Для чего она нужна?
Мне кажется ты что-то перепутал из-за непонимания этих терминов.
>Пробел в регулярных выражениях как будет? Пробелом и будет
Да, но ещё есть \s, который найдет любой пробельный символ (пробел, табуляцию, перенос на новую строку и т.д.).
> [0-9 ]
Это найдет либо цифры, либо пробел.
>А зачем нужен хеш? Чтобы доказать, что пользователь действительно получил ссылку, а не пытается подтвердить несуществующий ящик, мы генерируем сложный случайный код (не хеш, с чего ты решил, что это результат хеш-функции?), и просим пользователя его предъявить как подтверждение владения почтовым ящиком. Злоумышленник не может угадать код.
Было бы удобно не создавать новых полей или таблиц которые содержат этот код, а просто отправить хеш тот самый который получаем из пароля.
>А так, если ты не представляешь, как этот код работает, как ты его дальше развивать будешь?
Методом велосипедов и костылей!
Окей, почитаю. Правда, я туповатый и мало что понимаю в прочитанном.
Я не догоняю.
На js стороне мы создаём форму и добавляем в неё данные из файла. Можно заодно добавить что-нибудь вроде data1.append("key", "652");
>Объекты FormData позволяют вам легко конструировать наборы пар ключ-значение, представляющие поля формы и их значения
Окей, отправляем. Но php-скрипт же ведёт себя так, будто просто получил файл. И я не понимаю, как в нём получить отправленную информацию, кроме той, которая в $_FILES.
То есть, по отдельности всё клёво: вот мы создаём объект из ключей-значений и отправляем его. Дальше магия - и вот мы получаем файл, как если бы отправили его тупо кнопкой, а не аяксом. И вот вам пять переменных, типа $_FILES['userfile']['name'], с ними и работайте.
В отладчике в браузере Ctrl + Shift + I на вкладке Network посмотри какой POST запрос отправляется и что в нем передается , передается ли параметр, какие заголовки Conent-Type/Content-Length?
}?
Request Payload
------WebKitFormBoundaryN6lXi0VCJBkSobQb
Content-Disposition: form-data; name="0"; filename="del_object_v1.png"
Content-Type: image/png
------WebKitFormBoundaryN6lXi0VCJBkSobQb
Content-Disposition: form-data; name="key"
652
------WebKitFormBoundaryN6lXi0VCJBkSobQb--
Это? Вижу, что параметр key передаётся. Но как его принять на стороне php-скрипта? Я пробовал пару вариантов, но они не сработали.
Можешь еще скинуть кусочек кода, HTML, JS, чтобы я мог у себя запустить и проверить?
Просто пока мне кажется, что тут все в порядке и данные должны приходить в массив $_POST.
"use strict";
var sequense = function (start, step) {
var n = start;
return function(){
return n = n + step;
}
}
var generator = sequense(4, 1);
console.log(generator());
console.log(generator());
Работает вроде как надо. Только вот я все равно не понял, почему значение n сохраняется раз и навсегда, а не перезаписывается каждый раз при обращению к generator.
Алсо ОП, поправь все таки условия в задачнике, т.к. в твоей тестирующей проге добавлены еще условия. Алсо2, на мой код пишет такое:
Функция sequence(startingValue, step)
encountered a declaration exception
Что бы это значило? Сам код:
function sequense(start = 0, step = 1) {
var flag = false;
return function () {
if (flag) {
return start = start + step;
} else {
flag = true;
return start;
}
};
}
var generator = sequense();
console.log(generator());
console.log(generator());
console.log(generator());
Прочувствуй разницу:
>return n = n + step;
и
>return n + step;
n сохраняется для функции sequence, а не для generator, но увеличивается, так как на него есть ссылка. Получается, ты передаешь start и step при вызове generator, но используется только step (и n берется из функции).
Всё он видит. У тебя какое условие? 8 и десять цифр от 0 до 9. А скармливаешь "8-495-1-234-567", оно не подходит под условие!
В общем, если человеческим языком перевести:
покажи "+7" или "8 и десять цифр в промежутке от 0 до 9"
Все равно туплю. По моей логике, в generator() у меня лежит ф-я sequence. И значит при вызове фи генератор я по ссылке вызываю фю секвенс с параметрами. Так вот, почему сохраняется состояние переменной n от прошлого вызова, а не каждый раз по новой устанавливаются?
Подумай, как включить туда ещё пробелы, скобки и дефисы
>>980230
Тут-то и есть эта тонкая грань. Когда ты пишешь так
>var generator = sequense();
ты запускаешь функцию sequense,
но когда ты пишешь дальше
>generator();
это равносильно вот такому:
>var n = 4; --> сохранилась внутри sequence
>generator(); --> n = 4 + 1 = 5;
>generator(); --> n = 5 + 1 = 6;
>...
>function generator(n, step) {
>return n = n + step;
>}
То есть n передается из функции sequence в функцию, которая вернулась в generator, как будто ты еще находишься внутри sequence. Блджад, это реально трудно объяснить... Captain OP, to the rescue!
Ошибся:
>function generator(start, step) {
>return n = n + step;
>}
n конечно же передается сверху сверху, а step из аргументов.
Это называется замыкание (closure) - когда к функции в момент ее создания привязываются переменные снаружи ее. И она может позже обращаться к этим переменным.
https://learn.javascript.ru/functions-closures
https://learn.javascript.ru/closures
Когда ты вызываешь функцию, то создаются объявленные внутри нее через var переменные. Когда ты выходишь из этой функции, они уничтожаются (так как к ним больше никто не может обратиться и незачем их хранить в памяти).
При этом, если функцию вызвать несколько раз, то каждый раз при входе в функцию создается новая копия переменной:
function test() { var n = 1; }
test(); // входим в функцию, создаем переменную n, выходим, переменная уничтожается
test(); // то же самое, создается новая копия n и уничтожается
test(); // еще раз то же самое
Но когда тело функции обращается к переменным, созданным снаружи функции, получается более интересная штука - замыкание. В момент создания функция сохраняет ссылку на переменную и может потом к ней обращаться:
function createFn() {
var n = 1;
var fn = function () { n++; return n; }
return fn;
}
var f1 = createFn();
// входим в функцию createFn, создаем переменную n (назовем ее n_1)
// создаем новую функцию, сохраняем ее в переменную fn и в момент создания функция привязывается (запоминает ссылку на копию переменной) к этой копии переменной n_1
// выходим из функции, переменная n_1 не уничтожается, так как ссылка на нее сохранена в fn и к ней могут быть обращения
// новая созданная функция сохраняется в f1
var f2 = createFn();
// входим в функцию createFn, создаем второй экземпляр переменной n (n_2)
// создаем новую функцию, функция привязывается к этому экземпляру переменной n_2
// выходим из функции, переменная n_2 не уничтожается так как ссылка на него есть в функции
// сохраняем созданную функцию в f2
console.log(f1());
// вызываем f1, она увеличивает n_1 на 1 и возвращает ее (получается 2)
console.log(f2());
// вызываем f2, она увеличивает n_2 на 1 и возвращает ее (тоже 2)
console.log(f1()); // выводит 3
console.log(f1()); // выводит 4
console.log(f2()); // выводит 3
Если повторить:
- локальные переменные, созданные внутри функции, доступны только внутри нее (в том числе в создаваемых внутри нее функциях)
- локальные переменные удаляются, как только они становятся недоступными, исчезают все ссылки на них (в обычном случае - при выходе из функции)
- функция при создании сохраняет ссылки на внешние переменные, которые в ней использованы. Эти переменные не удаляются, так как она удерживает ссылки на них. Функция с привязанными к ней внешними переменными называется замыканием.
Вот еще пример кода с замыканием. Попробуй определить, что выведет программа?
function createTwoFunctions() {
var n = 1;
var f1 = function () { n++; return n; }
var f2 = function () { n++; return n; }
return [f1, f2];
}
var fns = createTwoFunctions();
var f1 = fns[0];
var f2 = fns[1];
console.log(f1()); // что выведется?
console.log(f1());
console.log(f2());
console.log(f1());
Это называется замыкание (closure) - когда к функции в момент ее создания привязываются переменные снаружи ее. И она может позже обращаться к этим переменным.
https://learn.javascript.ru/functions-closures
https://learn.javascript.ru/closures
Когда ты вызываешь функцию, то создаются объявленные внутри нее через var переменные. Когда ты выходишь из этой функции, они уничтожаются (так как к ним больше никто не может обратиться и незачем их хранить в памяти).
При этом, если функцию вызвать несколько раз, то каждый раз при входе в функцию создается новая копия переменной:
function test() { var n = 1; }
test(); // входим в функцию, создаем переменную n, выходим, переменная уничтожается
test(); // то же самое, создается новая копия n и уничтожается
test(); // еще раз то же самое
Но когда тело функции обращается к переменным, созданным снаружи функции, получается более интересная штука - замыкание. В момент создания функция сохраняет ссылку на переменную и может потом к ней обращаться:
function createFn() {
var n = 1;
var fn = function () { n++; return n; }
return fn;
}
var f1 = createFn();
// входим в функцию createFn, создаем переменную n (назовем ее n_1)
// создаем новую функцию, сохраняем ее в переменную fn и в момент создания функция привязывается (запоминает ссылку на копию переменной) к этой копии переменной n_1
// выходим из функции, переменная n_1 не уничтожается, так как ссылка на нее сохранена в fn и к ней могут быть обращения
// новая созданная функция сохраняется в f1
var f2 = createFn();
// входим в функцию createFn, создаем второй экземпляр переменной n (n_2)
// создаем новую функцию, функция привязывается к этому экземпляру переменной n_2
// выходим из функции, переменная n_2 не уничтожается так как ссылка на него есть в функции
// сохраняем созданную функцию в f2
console.log(f1());
// вызываем f1, она увеличивает n_1 на 1 и возвращает ее (получается 2)
console.log(f2());
// вызываем f2, она увеличивает n_2 на 1 и возвращает ее (тоже 2)
console.log(f1()); // выводит 3
console.log(f1()); // выводит 4
console.log(f2()); // выводит 3
Если повторить:
- локальные переменные, созданные внутри функции, доступны только внутри нее (в том числе в создаваемых внутри нее функциях)
- локальные переменные удаляются, как только они становятся недоступными, исчезают все ссылки на них (в обычном случае - при выходе из функции)
- функция при создании сохраняет ссылки на внешние переменные, которые в ней использованы. Эти переменные не удаляются, так как она удерживает ссылки на них. Функция с привязанными к ней внешними переменными называется замыканием.
Вот еще пример кода с замыканием. Попробуй определить, что выведет программа?
function createTwoFunctions() {
var n = 1;
var f1 = function () { n++; return n; }
var f2 = function () { n++; return n; }
return [f1, f2];
}
var fns = createTwoFunctions();
var f1 = fns[0];
var f2 = fns[1];
console.log(f1()); // что выведется?
console.log(f1());
console.log(f2());
console.log(f1());
Скорее всего ты используешь синтаксис значений аргументов по умолчанию, который введен в ES6 и который не поддерживает твой браузер.
>>980178
Плюс это спецсимвол и надо писать \+ или [+] чтобы он не имел специального значения.
Попробуй расшифровать свое выражение:
-- первый вариант --
[+] = должен встретиться знак плюс
[[\s]? = затем может быть, а может и не быть (так как знак вопроса), один из символов в квадратных скобках, то есть скобка [ или пробельный символ \s
+ = предыдущее выражение встречается 1 или более раз подряд
[7] = далее должна идти цифра 7
-- или второй вариант --
8[0-9]{10} = должна идти цифра 8, за ней ровно 10 цифр
-- конец --
То есть твое выражение ищет либо кусок вроде +7 либо номер из 11 цифр подряд, где первая = 8
Было бы полезно, если бы ты словами написал что ты имел в виду, и привел бы выражение, а мы бы сказали правильно ты его написал или нет. Попробуй сначала именно словами сформулировать, что в каком порядке должно идти.
Скорее всего ты используешь синтаксис значений аргументов по умолчанию, который введен в ES6 и который не поддерживает твой браузер.
>>980178
Плюс это спецсимвол и надо писать \+ или [+] чтобы он не имел специального значения.
Попробуй расшифровать свое выражение:
-- первый вариант --
[+] = должен встретиться знак плюс
[[\s]? = затем может быть, а может и не быть (так как знак вопроса), один из символов в квадратных скобках, то есть скобка [ или пробельный символ \s
+ = предыдущее выражение встречается 1 или более раз подряд
[7] = далее должна идти цифра 7
-- или второй вариант --
8[0-9]{10} = должна идти цифра 8, за ней ровно 10 цифр
-- конец --
То есть твое выражение ищет либо кусок вроде +7 либо номер из 11 цифр подряд, где первая = 8
Было бы полезно, если бы ты словами написал что ты имел в виду, и привел бы выражение, а мы бы сказали правильно ты его написал или нет. Попробуй сначала именно словами сформулировать, что в каком порядке должно идти.
Регулярное выражение еще называют "шаблоном", совпадение с которым надо найти, или "маской" (которая в данном случае значит "шаблон"). "Подмаска" - это часть регулярки, заключенная в круглые скобки.
>>980230
Ты немного неправильно рассуждаешь.
"в generator() у меня лежит ф-я sequence". Неправильно. В переменную generator ты поместил анонимную (без имени) функцию, которую создала и вернула функция sequence(). sequence() при каждом вызове создает и возвращает новую функцию.
А когда ты пишешь generator() со скобками, то ты делаешь вызов функции, ссылка на которую была сохранена в переменную.
В JS функции - это объекты и ссылки на них можно сохранять в переменные, передавать и возвращать из функций.
Если бы ты написал
var generator = sequence;
То тогда бы ты положил в переменную generator ссылку на функцию sequence. но у тебя написано sequence(), а круглые скобки обозначают вызов функции.
Вот еще пример интересного выражения:
var x = fn(1)(2)(3);
Ну-ка, расшифруй, что это значит? Как это выполняется? Допиши функцию fn так, чтобы в x оказалась сумма значений в скобках (1 + 2 + 3 = 6).
Регулярное выражение еще называют "шаблоном", совпадение с которым надо найти, или "маской" (которая в данном случае значит "шаблон"). "Подмаска" - это часть регулярки, заключенная в круглые скобки.
>>980230
Ты немного неправильно рассуждаешь.
"в generator() у меня лежит ф-я sequence". Неправильно. В переменную generator ты поместил анонимную (без имени) функцию, которую создала и вернула функция sequence(). sequence() при каждом вызове создает и возвращает новую функцию.
А когда ты пишешь generator() со скобками, то ты делаешь вызов функции, ссылка на которую была сохранена в переменную.
В JS функции - это объекты и ссылки на них можно сохранять в переменные, передавать и возвращать из функций.
Если бы ты написал
var generator = sequence;
То тогда бы ты положил в переменную generator ссылку на функцию sequence. но у тебя написано sequence(), а круглые скобки обозначают вызов функции.
Вот еще пример интересного выражения:
var x = fn(1)(2)(3);
Ну-ка, расшифруй, что это значит? Как это выполняется? Допиши функцию fn так, чтобы в x оказалась сумма значений в скобках (1 + 2 + 3 = 6).
Флаг тут не требуется. Проще либо уменьшить start заранее на 1 шаг либо сохранять его перед увеличением.
И еще кое-что. Ты наверно заметил, что я стараюсь писать не "в переменную мы поместили функцию", а "в переменную мы поместили ссылку на функцию". Почему? Потому что функции - это объекты и они не копируются при присваивании, копируется ссылка на тот же самый объект:
var a = {}; // создается новый объект, ссылка помещается в a
var b = a; // не создается вторая копия объекта, просто в b помещается ссылка на тот же объект, на который ссылается a
a.x = 1; // добавляем поле в объект
console.log(b.x); // выведет 1
То же самое с функциями:
var a = function () {};
var b = a;
Здесь создается одна функция (один объект) и обе переменные на этот один объект ссылаются.
Это по моему написано у меня в предисловии к задачам, советую тоже почитать.
https://pastebin.com/Fm1f7srw
Тут глючит: http://sqlfiddle.com/#!9/3935de/9
В 4-й части (где группировка по 09-15, 15-18 и т.д) не додумался, как выводить сам временной промежуток. Есть ещё идея добавлять union на каждый временной промежуток:
select '9-15', count ...
union
seect '15-18', count ...
...
Но нельзя ли одним запросом?
>>976689
Вопросов по замечаниям нет, спасибо за проверку, сажусь за макет.
Подожди. Т.е. по факту, это ф-я внутри ф-и заставляет сохранять значение переменной, так?
Переделал задачу с промежутками и исправил ошибки: https://pastebin.com/1C9451Si
Но есть проблема - если за определённый промежуток (допустим 15-18) не было ни одного сеанса за всё время, то строка '15-18'|0|0 не выведется.
Не сказал бы, что функция заставляет. С каждой функцией связаны LexicalEnvironment - набор её переменных, грубо говоря и Scope - свойство, указывающее не внешнее окружение. Если функция не находит в своём LexicalEnvironment какой-то переменной, то она лезет на уровень выше через свойство Scope и ищёт переменную во внешнем LexicalEnvironment. Вот здесь подробней и правильней описано: https://learn.javascript.ru/closure
>>980278
>>980386
Ещё раз переделал, с учётом сеансов без купленных билетов: https://pastebin.com/Ym8kuDTv
Действительно, через $_POST['key'] сё нормально передаётся. То ли я ступил, то ли что-то было в другом месте неправильно, когда проверял.
Можно.
Ой там в 93 строке написано "0" заместно "Ноль", фикс карочь
Проект написан на PHP и подключится к этой всей байде через PHP нету возможности. Было решено написать программу на C# которая бы отдавала данные, все это отлично работает, если запускать напрямую из консоли. Но когда PHP пытается вытащить данные, запустив консольный скрипт и получив результат, то ничего в ответ не приходит. Ну что за блять гемморой с виндой?Кто знает в чем может быть причина?Под винду вообще не писал ничего и с C# первый раз вообще работаю.
Уже даже не знаю что делать.
А с этими он не работает.
Я вот сделал, но он мне выдаёт месиво. Это так должно быть или я накосячил?
> Просто if-ами, сделать специальный класс с методами, или отдельные функции?
Я в студентах просто сделал класс валидатор с одним методом, а там через метод проверял ифами поля объекта-студента, точнее с помощью регулярок. Ошибки записывал в массив errors, который и возвращал. Хотя логичней было бы возвращать исключения, наверное.
Смотерл по Yii2. Хер его знает, меня удивило что автор закрывает скрипты тегом ?> - это же ужас. Хотя в остальном вроде норм, но не могу сказать насколько его практики в целом полезны.
Ну так этот хеш может сгенерировать и злоумышленник, так как он знает свой пароль.
>>980038
А какое именно условие надо поправить?
>>980278
> join seans s2 on s2.start > s.start
Тут должно быть >=
> список фильмов, для каждого указано общее число посетителей за все время, среднее число зрителей за сеанс и общая сумма сбора по каждому, отсортированные по убыванию прибыли.
А любопытно, для подведения итога тут не подойдет GROUP BY WITH ROLLUP вместо UNION?
> число посетителей и кассовые сборы, сгруппированные по времени начала фильма:
Тут можно сделать так:
SELECT CASE
WHEN HOUR(start) BETWEEN 9 AND 14 THEN '9-15'
WHEN HOUR(start) BETWEEN 15 AND 17 THEN '15-18'
END CASE as group,
...
GROUP BY group
Также, можно заджойниться на созданную на лету таблицу:
SELECT ...
FROM seans
JOIN (
SELECT '9:00' AS start, '15:00' AS end
UNION
SELECT '15:00' AS start, '18:00' AS end
) AS periods ON seans.start >= period.start AND seans.start < period.end
...
GROUP BY periods.start
Так, в общем, верно решено. Только названия стоит получше придумывать и ключевые слова писать большими буквами.
Ну так этот хеш может сгенерировать и злоумышленник, так как он знает свой пароль.
>>980038
А какое именно условие надо поправить?
>>980278
> join seans s2 on s2.start > s.start
Тут должно быть >=
> список фильмов, для каждого указано общее число посетителей за все время, среднее число зрителей за сеанс и общая сумма сбора по каждому, отсортированные по убыванию прибыли.
А любопытно, для подведения итога тут не подойдет GROUP BY WITH ROLLUP вместо UNION?
> число посетителей и кассовые сборы, сгруппированные по времени начала фильма:
Тут можно сделать так:
SELECT CASE
WHEN HOUR(start) BETWEEN 9 AND 14 THEN '9-15'
WHEN HOUR(start) BETWEEN 15 AND 17 THEN '15-18'
END CASE as group,
...
GROUP BY group
Также, можно заджойниться на созданную на лету таблицу:
SELECT ...
FROM seans
JOIN (
SELECT '9:00' AS start, '15:00' AS end
UNION
SELECT '15:00' AS start, '18:00' AS end
) AS periods ON seans.start >= period.start AND seans.start < period.end
...
GROUP BY periods.start
Так, в общем, верно решено. Только названия стоит получше придумывать и ключевые слова писать большими буквами.
Надо понимать, что эти SAPI - это способы организовать взаимодействие между веб-сервером и PHP, который может работать как внутри веб-сервера так и как отдельный процесс. В обоих случаях нужно иметь какой-то протокол для передачи запроса от сервера к PHP и результата его обработки от PHP к серверу. Сам PHP взаимодействует только с веб-сервером по одному из описанных ниже протоколов, а веб-сервер уже взаимодействует с клиентом (браузером) по HTTP.
Эти протоколы позволяют обрабатывать запросы не только с помощью PHP, но и с помощью программы на любом другом языке. При этом программе не надо уметь работать с HTTP - это ответственность веб-сервера.
Первые веб-серверы могли отдавать только статические страницы (то есть файлы с диска), и CGI был простым способом добавить динамические возможности (добавление комментариев, учет числа просмотров страницы).
CGI - самый древний и медленный, но самый простой интерфейс. При поступлении запроса веб-сервер запускает новый процесс PHP, передавая информаицю о запросе (заголовки, URL) в переменных окружения. В PHP она будет доступна в массиве $_SERVER ( http://php.net/manual/ru/reserved.variables.server.php ). PHP выводит ответ (например HTML код) на стандартный вывод (а веб-сервер пересылает его в браузер), ошибки выводятся в стандартный поток ошибок (веб-сервер сохраняет их в свой лог). После обработки одного запроса программа завершается.
В случае поступления POST запроса тело запроса передается программе на стандартный поток ввода.
Он очень простой, так как обработчик легко написать на любом языке, хоть bash-скриптом. Также его поддержка не требует сложного кода в веб-сервере. Но он очень медленный, так как на каждый запрос интерпретатор PHP запускается с нуля, инициализируется.
- про CGI http://students.uni-vologda.ac.ru/pages/pm97/cgi/cgi.html - в статье есть пример программы в 7 строк, показывающей, как просто использовать CGI.
- Про переменные окружения: http://www.linux-ink.ru/static/Docs/Courses/adv-user-guide/adv-user-guide/ch02s02.html
- про потоки ввода/вывода: http://xgu.ru/wiki/Стандартные_потоки_ввода/вывода
Далее, mod_php - это модуль, который позволяет встроить интерпретатор PHP внутрь Апача. Соответственно теперь он запускается вместе с сервером, и работает намного быстрее. Это не универсальный интерфейс, как CGI, который позволяет использовать любой веб-сервер и любой язык программирования.
Из минусов - поддерживается только Апач и PHP (nginx - уже нет), также, если у тебя много сайтов, и хочется чтобы каждый из них работал от отдельного пользователя, с отдельными ограничениями ресурсов, то реализовать это затруднительно. Если PHP вдруг упадет, он утянет за собой процесс веб-сервера, в котором выполняется.
Далее, FastCGI - это специальный протокол для передачи запросов от веб-сервера к программе, например, интерпретатору PHP. При его использовании интепретатор PHP запскается как отдельная программа, открывает порт и принимает запросы от веб-сервера по протоколу FastCGI, обрабатывает их (запуская PHP-программу, которую указал сервер) и постылает ответы обратно. Опять же, перезапускать на каждый запрос PHP не надо, потому работает быстро. Также, можно для каждого сайта запустить свой процесс PHP, от своего пользователя, со своими ограничениями. Благодаря тому, что PHP работает в отдельном процессе, от отдельного пользователя, при проблемах он упадет один, не задевая веб-сервер.
Он быстрый, но потреял простоту, которая была у CGI и с ним скрипт на bash из нескольких строчек использовать не получится.
http://lectureswww.readthedocs.io/5.web.server/fcgi.html
php-fpm - это менеджер процессов PHP, работающих по протоколу FastCGI. Выше я описал протокол, но чтобы его использовать, надо как-то запускать процессы PHP, поддерживать определенное их количество, перезапускать, если они падают, логгировать ошибки. Всем этим и занимается php-fpm. Мануал: http://php.net/manual/ru/install.fpm.php
http://xandeadx.ru/blog/php/866
Также, может тебе будет полезно почитать про архитектуру серверов вообще: https://gist.github.com/codedokode/ffd520440a970c07c1c6
>>980362
Глупый совет. Обсуждать как раз надо, чтобы понимать в каких случаях что лучше подходит. А ты подаешь все так, как будто есть всегда плохой и всегда хороший вариант, непонятно правда почему об этом до 2017 года не знали.
Надо понимать, что эти SAPI - это способы организовать взаимодействие между веб-сервером и PHP, который может работать как внутри веб-сервера так и как отдельный процесс. В обоих случаях нужно иметь какой-то протокол для передачи запроса от сервера к PHP и результата его обработки от PHP к серверу. Сам PHP взаимодействует только с веб-сервером по одному из описанных ниже протоколов, а веб-сервер уже взаимодействует с клиентом (браузером) по HTTP.
Эти протоколы позволяют обрабатывать запросы не только с помощью PHP, но и с помощью программы на любом другом языке. При этом программе не надо уметь работать с HTTP - это ответственность веб-сервера.
Первые веб-серверы могли отдавать только статические страницы (то есть файлы с диска), и CGI был простым способом добавить динамические возможности (добавление комментариев, учет числа просмотров страницы).
CGI - самый древний и медленный, но самый простой интерфейс. При поступлении запроса веб-сервер запускает новый процесс PHP, передавая информаицю о запросе (заголовки, URL) в переменных окружения. В PHP она будет доступна в массиве $_SERVER ( http://php.net/manual/ru/reserved.variables.server.php ). PHP выводит ответ (например HTML код) на стандартный вывод (а веб-сервер пересылает его в браузер), ошибки выводятся в стандартный поток ошибок (веб-сервер сохраняет их в свой лог). После обработки одного запроса программа завершается.
В случае поступления POST запроса тело запроса передается программе на стандартный поток ввода.
Он очень простой, так как обработчик легко написать на любом языке, хоть bash-скриптом. Также его поддержка не требует сложного кода в веб-сервере. Но он очень медленный, так как на каждый запрос интерпретатор PHP запускается с нуля, инициализируется.
- про CGI http://students.uni-vologda.ac.ru/pages/pm97/cgi/cgi.html - в статье есть пример программы в 7 строк, показывающей, как просто использовать CGI.
- Про переменные окружения: http://www.linux-ink.ru/static/Docs/Courses/adv-user-guide/adv-user-guide/ch02s02.html
- про потоки ввода/вывода: http://xgu.ru/wiki/Стандартные_потоки_ввода/вывода
Далее, mod_php - это модуль, который позволяет встроить интерпретатор PHP внутрь Апача. Соответственно теперь он запускается вместе с сервером, и работает намного быстрее. Это не универсальный интерфейс, как CGI, который позволяет использовать любой веб-сервер и любой язык программирования.
Из минусов - поддерживается только Апач и PHP (nginx - уже нет), также, если у тебя много сайтов, и хочется чтобы каждый из них работал от отдельного пользователя, с отдельными ограничениями ресурсов, то реализовать это затруднительно. Если PHP вдруг упадет, он утянет за собой процесс веб-сервера, в котором выполняется.
Далее, FastCGI - это специальный протокол для передачи запросов от веб-сервера к программе, например, интерпретатору PHP. При его использовании интепретатор PHP запскается как отдельная программа, открывает порт и принимает запросы от веб-сервера по протоколу FastCGI, обрабатывает их (запуская PHP-программу, которую указал сервер) и постылает ответы обратно. Опять же, перезапускать на каждый запрос PHP не надо, потому работает быстро. Также, можно для каждого сайта запустить свой процесс PHP, от своего пользователя, со своими ограничениями. Благодаря тому, что PHP работает в отдельном процессе, от отдельного пользователя, при проблемах он упадет один, не задевая веб-сервер.
Он быстрый, но потреял простоту, которая была у CGI и с ним скрипт на bash из нескольких строчек использовать не получится.
http://lectureswww.readthedocs.io/5.web.server/fcgi.html
php-fpm - это менеджер процессов PHP, работающих по протоколу FastCGI. Выше я описал протокол, но чтобы его использовать, надо как-то запускать процессы PHP, поддерживать определенное их количество, перезапускать, если они падают, логгировать ошибки. Всем этим и занимается php-fpm. Мануал: http://php.net/manual/ru/install.fpm.php
http://xandeadx.ru/blog/php/866
Также, может тебе будет полезно почитать про архитектуру серверов вообще: https://gist.github.com/codedokode/ffd520440a970c07c1c6
>>980362
Глупый совет. Обсуждать как раз надо, чтобы понимать в каких случаях что лучше подходит. А ты подаешь все так, как будто есть всегда плохой и всегда хороший вариант, непонятно правда почему об этом до 2017 года не знали.
Тогда джойнить надо на созданную из SELECT/UNION таблицу.
>>980423
Да, правильно.
>>980535
> if (($isFemale == 1) || ($isFemale == 2)) {
Тут странно, я думал что $isFemale может быть только 0 или 1. Нелогично как-то.
> inclineWord($millions % 10,
Непонятно, почему так. Это же неправильно наверно.
В остальном верно.
>>980629
Урок по формам https://github.com/codedokode/pasta/blob/master/forms.md
Валидация делается функцией, подумай, что подается ей на вход и что она вернет на выходе.
> Просто if-ами, сделать специальный класс с методами, или отдельные функции?
как удобнее. Главное, чтобы была функция/метод, которую можно вызвать.
> Что делать, если данные не верны (empty, другого типа чем ожидалось, слишком длинное/короткое, не входит в требуемый диапазон и т.п.)
Вернуть сообщение об ошибке
> или пытаться исправить/привести к должному виду
Можно и так, но тогда надо предусмотреть возврат исправленных значений и информирование о произведенных исправлениях.
> Стоит ли использовать assertion?
Нет, assert() используется чтобы сказать "это утверждение всегда верно, иначе в программе ошибка и надо ее завершить"
> Нужно подходить к каждому конкретному случаю индивидуально в текущем контексте, или стараться унифицировать это все?
В фреймворках это унифицируют, вот Symfony Validation, если не боишься:
http://symfony.com/doc/current/components/validator.html
>>980787
Нет, ты не понимаешь смысл квадратных скобок. Они значат "ровно один любой из перечисленных символов". Соответственно круглые скобки внутри будут восприниматься просто как символы скобок. Также как и звездочка, вопрос или плюс. Мануал http://php.net/manual/ru/regexp.reference.character-classes.php
>>980830
Выделяется потому, что регулярка выделяет не только номер, но и символ перевода строки перед ним. Добавление ^$ и флага m должно помочь.
> Можно ли сделать, дабы он считал исключительно цифры?
да, напиши "1 цифра, за ней любые символы", возьми это в скобки и повтори 10 раз.
[0-9(\W)+] - тут скобки и плюс обозначают соотв. символы, и не имеют специального значения. Мануал http://php.net/manual/ru/regexp.reference.character-classes.php
>>980846
тут слишком длинное выражение
Вместо +? надо писать звездочку.
Также, у тебя ^ относится только к первой альтернативе, и $ ко второй.
^ab|cd$ читается как (^ab)|(cd$) а не ^(ab|cd)$
>>980856
Регулярка слишком длинная, вывод программы невозможно читать. Надо его привести в понятный человеку вид.
>>980866
В loadHTML указывается не доменное имя, а строка с HTML кодом. Открой мануал по loadHtml.
Тогда джойнить надо на созданную из SELECT/UNION таблицу.
>>980423
Да, правильно.
>>980535
> if (($isFemale == 1) || ($isFemale == 2)) {
Тут странно, я думал что $isFemale может быть только 0 или 1. Нелогично как-то.
> inclineWord($millions % 10,
Непонятно, почему так. Это же неправильно наверно.
В остальном верно.
>>980629
Урок по формам https://github.com/codedokode/pasta/blob/master/forms.md
Валидация делается функцией, подумай, что подается ей на вход и что она вернет на выходе.
> Просто if-ами, сделать специальный класс с методами, или отдельные функции?
как удобнее. Главное, чтобы была функция/метод, которую можно вызвать.
> Что делать, если данные не верны (empty, другого типа чем ожидалось, слишком длинное/короткое, не входит в требуемый диапазон и т.п.)
Вернуть сообщение об ошибке
> или пытаться исправить/привести к должному виду
Можно и так, но тогда надо предусмотреть возврат исправленных значений и информирование о произведенных исправлениях.
> Стоит ли использовать assertion?
Нет, assert() используется чтобы сказать "это утверждение всегда верно, иначе в программе ошибка и надо ее завершить"
> Нужно подходить к каждому конкретному случаю индивидуально в текущем контексте, или стараться унифицировать это все?
В фреймворках это унифицируют, вот Symfony Validation, если не боишься:
http://symfony.com/doc/current/components/validator.html
>>980787
Нет, ты не понимаешь смысл квадратных скобок. Они значат "ровно один любой из перечисленных символов". Соответственно круглые скобки внутри будут восприниматься просто как символы скобок. Также как и звездочка, вопрос или плюс. Мануал http://php.net/manual/ru/regexp.reference.character-classes.php
>>980830
Выделяется потому, что регулярка выделяет не только номер, но и символ перевода строки перед ним. Добавление ^$ и флага m должно помочь.
> Можно ли сделать, дабы он считал исключительно цифры?
да, напиши "1 цифра, за ней любые символы", возьми это в скобки и повтори 10 раз.
[0-9(\W)+] - тут скобки и плюс обозначают соотв. символы, и не имеют специального значения. Мануал http://php.net/manual/ru/regexp.reference.character-classes.php
>>980846
тут слишком длинное выражение
Вместо +? надо писать звездочку.
Также, у тебя ^ относится только к первой альтернативе, и $ ко второй.
^ab|cd$ читается как (^ab)|(cd$) а не ^(ab|cd)$
>>980856
Регулярка слишком длинная, вывод программы невозможно читать. Надо его привести в понятный человеку вид.
>>980866
В loadHTML указывается не доменное имя, а строка с HTML кодом. Открой мануал по loadHtml.
Тот, кто не напомнит, умрет через 3 дня.
>В loadHTML
Там изначально был loadHTMLfile, просто на скрине проебался. Все равно не работает.
Ну зачем ты лечишь, я взял пример отсюда http://stackoverflow.com/questions/13718500/using-xpath-with-php-to-parse-html/13718745#13718745
Ты сам все подал так, как оно и есть. Кроме php-fpm сейчас нет нормальных решений. Можно, конечно, работать в ивент лупах, много подобного есть, но это уже другое архитектурное решение вообще. Никто уже не работает ни с cgi, ни с mod_php, потому что апач дружит с php-fpm. Поговорить о них можно, конечно, и узнать всякое интересное, но выбора уже не стоит, ибо во всех случаях лучше всего фпм и подходит. Может только есть свои реализации php-fpm у кого, суть однако той же остается.
>Там указан URL, а не доменное имя
О чем ты вообще, он должен брать содержимое любой ссылки. Кроме того, и там, и там URL.
Тащемта речь про задел на хайлоад. В отрыве от этого и mod_php и php_fpm однохуйственны практически.
Так в целом хорошо сконфигурированный апач с модпхп и так же хорошо сконфигурированный энжинкс с пхпфпм покажут сопоставимые результаты, разница будет в копейках.
Жопа приходит в следующих случаях:
Абсолютно нормальная ситуация для почти всех веб сервисов - отдача статики. Апач в этом месте начинает срать под себя. Это изи обходится подключением энжинкса для конкретно этой цели. Но уже тут возникает вопрос, если нет разницы нахуя мутить переусложненную схему?
Это еще не все. Апач при попытке масштабирования начинает уже просто водить тебе хуем по губам со словами "php мой, мая прелесть, саси". В итоге модпхпшный боярин снова идет на поклон к энжинксу, чтобы тот хоть как-то развел по углам ебанутых апачей. Но вот это уже оказывается попросту существенно медленее простого энжинкса и кучки фпм, так еще и переусложнено на кой то хуй. Снова.
Выбиратьть апач с модпхп в дейтсвительности нужно только в том случае, если позарез нужны его расширения, в иных случаях он ничем не выигрывает.
Напомнило это все отзывы от рубимакак, которые базарят за скорсть RoR.
Руби на Рельсах обычно стоят со своим интерпретатором, там все свое, интерпретатор и фреймворк, тогда как РНР стоит обычно на кучу сайтов да еще в связке с апачем.
Да, WITH ROLLUP подошёл и помог избавиться от лишнего запроса с джойном:
http://sqlfiddle.com/#!9/3935de
https://pastebin.com/BFvfR3U8
Правда в мануале написано, что ORDER BY и WITH ROLLUP взаимно исключающие: https://dev.mysql.com/doc/refman/5.7/en/group-by-modifiers.html
Поэтому для сортировки нужно оборачивать запрос с ROLLUP в ещё один запрос вида SELECT * FROM (...) ORDER BY column
Однако такой подход будет при сортировке также учитывать строку 'Итого'.
Никак. Лучше скачай PHP на комп.
>Ну так этот хеш может сгенерировать и злоумышленник, так как он знает свой пароль.
Не может, так как он не знает соль. Но если мы позволяем не активированному пользователю логиниться и сохраняем хэш в куки, тогда злоумышленник может получить его от туда. Значит остается только вариант с созданием дополнительных таблиц/колонок?
Нет, не любой. Ты все путаешь.
Во-первых, 2ch.hk - это не URL. Прочти мой урок про URL, это будет полезно: https://github.com/codedokode/pasta/blob/master/network/urls.md
Во-вторых, PHP не поддерживает любые URL, а поддерживает "потоки", за счет чего в некоторых функциях можно вместо имени файла указать похожий на URL идентификатор:
http://php.net/manual/ru/intro.stream.php
http://php.net/manual/ru/wrappers.php
То, что ты указал, для PHP - это просто имя файла.
>>981024
Локально у себя может быть проще поставить Апач вместо того, чтобы возиться с настройкой нгинксов. Также, у Апача больше настроек и опций конфигурации, чем у нгинкса. Есть вещи, которые нгинкс в принципе сделать не может. Хотя я не думаю, что это плохо - это все же в первую очередь веб-сервер для быстрой раздачи контента.
>>981063
На ideone не включили почему-то нужное расширение. Используй альтернативы, например 3v4l.org
>>981086
Ага, значит тут он не очень подходит. Но зато ты теперь знаешь про эту возможность.
Конечно можно было извернуться как-то так
ORDER BY IF(id = 'Итого', 1, 0) ASC, ...
но наверно это уже лишнее усложнение.
>>981348
Нужна программа на PHP, которая будет брать данные из базы и генерировать на их основе HTML код, а также обрабатывать запросы на изменение данных.
>>981349
Лучше сделать отдельное случайное число, чтобы не создавать потенциальных уязвимостей. Если тебе жалко места, можно сделать отдельную таблицу кодов подтверждений и чистить в ней старые записи.
Нет, не любой. Ты все путаешь.
Во-первых, 2ch.hk - это не URL. Прочти мой урок про URL, это будет полезно: https://github.com/codedokode/pasta/blob/master/network/urls.md
Во-вторых, PHP не поддерживает любые URL, а поддерживает "потоки", за счет чего в некоторых функциях можно вместо имени файла указать похожий на URL идентификатор:
http://php.net/manual/ru/intro.stream.php
http://php.net/manual/ru/wrappers.php
То, что ты указал, для PHP - это просто имя файла.
>>981024
Локально у себя может быть проще поставить Апач вместо того, чтобы возиться с настройкой нгинксов. Также, у Апача больше настроек и опций конфигурации, чем у нгинкса. Есть вещи, которые нгинкс в принципе сделать не может. Хотя я не думаю, что это плохо - это все же в первую очередь веб-сервер для быстрой раздачи контента.
>>981063
На ideone не включили почему-то нужное расширение. Используй альтернативы, например 3v4l.org
>>981086
Ага, значит тут он не очень подходит. Но зато ты теперь знаешь про эту возможность.
Конечно можно было извернуться как-то так
ORDER BY IF(id = 'Итого', 1, 0) ASC, ...
но наверно это уже лишнее усложнение.
>>981348
Нужна программа на PHP, которая будет брать данные из базы и генерировать на их основе HTML код, а также обрабатывать запросы на изменение данных.
>>981349
Лучше сделать отдельное случайное число, чтобы не создавать потенциальных уязвимостей. Если тебе жалко места, можно сделать отдельную таблицу кодов подтверждений и чистить в ней старые записи.
>Локально у себя может быть проще поставить Апач вместо того, чтобы возиться с настройкой нгинксов.
Зачем ты об этом говоришь, если изначальный вопрос только про быстродействие сайта был?
Можно передавать со страницы на страницу в скрытом поле формы id определённой записи в базе данных? Это не нарушение безопасности?
А другие варианты? Ничего кроме учёта поведенческого фактора (сколько пробыл на странице с голосованием и т.д.) в голову не приходит.
http://www.tema.ru/travel/mexico/
http://www.tema.ru/travel/usa.1990-1991/
http://www.tema.ru/travel/belarus.2015-2/
Добавляю в форму
->add('radius', 'app_map_radius', [
'required' => false,
])
В кастомном типе 'app_map_radius' описываю содержимое этого поля как
$builder
->add('dist', 'text', [
'constraints' => [
new NotBlank('from'),
],
])
->add('from', 'app_latlon', [
'constraints' => [
new NotBlank('radius'),
],
]);
Все преобразуется и выдает как мне нужно, но проблема в том, что теперь он требует "from" когда radius не передаю.
Как сделать 'app_map_radius' необязательным? empty_data => null не помогает.
Чувствую, что ход моих мыслей нужно объяснить.
Первым делом я заметил, что для каждого месяца нужно ровно 7 столбцов и до 6-и строк включительно: http://calendar.yuretz.ru/
На основании этого можно сгенерировать таблицу, содержащую числа от 1 до 42-х (так как 6 * 7 = 42): https://pastebin.com/uwHjYikh
Теперь осталось добавить пару условий и ещё одну переменную-счётчик - для ячеек. Этот счётчик начинает увеличиваться сразу же, а счётчик дней в месяце - только тогда, когда значение счётчика ячеек превысит @firstDayNumber. В этой переменной находится номер 1-го числа в неделе (пик). И ещё, если значение счётчика дней превысит количество дней в месяце - то добиваем оставшиеся ячейки таблицы нулями. Ну а потом оборачиваем это в ещё один SELECT, чтобы отобрать только нужные столбцы и избавиться от строки, состоящей из нулей (она может быть, а может не быть).
Помогите, пожалуйста.
Суть проблемы: у меня есть два скрипта, один из них выполняется 95-120 секунд, а второй выполняется 0.1 секунду.
Почему-то, когда я запускаю первый скрипт, и следом второй. Второй скрипт не отвечает до тех пор, пока не исполнится первый. Как это пофиксить? Чую, что где-то в конфиге апача, но повторяюсь, всю голову выебал и перегуглил, но нихуя не могу понять даже, куда копать. Халп, помогите, господа.
жаваскрипт изначально был как дополнение для "лица" сайта. То есть он работал на стороне клиента - подвигать там формы, снежок посыпать, то есть анимация и прочее и прочее.
ПХП работал на стороне сервера.
Сейчас жаваскрипт может работать и на стороне сервера и на стороне клиента.
Все зависит от того, что хочешь делать, у каждого языка своя задача.
вот у меня есть структура сайта где начиная с index передаются параметры по нажатию ссылки а там уже инклюдится кусок кода в зависимости от нужды но в итоге это всё выглядит как index.php?id=1&sydi=to&vot_tydi=eto
как бы я подозреваю что я даун
и хотелось бы узнать как должно это работать не у макаки
даже не могу нагуглить нормально это. где искать то хотя бы?
Да иди нахуй, жс это вообще худшее что есть в вебдеве.
$id = $_GET["id"];
if(!is_numeric($id)) {
exit("Не существующая страница");
}
if($id<=0 || $id>=$max){
exit("Не существующая страница");
}
//$max = максимальный id в базе данных
Нi.
Можно просто $id = intval($_GET['id']);
> И нужно ли как-то чистить $_GET["id"] если я использую подготовленные запросы в PDO?
Нет, если ты все значения поставляешь через плейсхолдеры.
>>982236
Число проголосовавших считается через аггрегатные функции COUNT DISTINCT/GROUP BY. Ответы можно получить через GROUP_CONCAT, но там конечно свои подвохи.
Вообще, я не уверен, что тут есть смысл все делать одним запросом.
>>982201
Если это страницы сайта, то обычно используют так называемые seo friendly URL. Урок https://gist.github.com/codedokode/772a4ccc03e41d6b7cba
>>982170
Может быть много вариантов. Например, если ты используешь сессии, то там есть блокировка сессии на время использования, которая вызывает такой эффект.
Ты тут полагаешься на использование увеличивающейся переменной, но ведь можно сделать проще и надежнее. Сгенерировать таблицу с числами от 1 до N с помощью формулы SELECT id * 7 + column:
1 2 3 4 5 6 7
8 9 10 11 ...
И затем из чисел в ней вычесть смещение, соответствующее номеру первого дня.
Тогда может быть даже не понадобится внешний запрос, достаточно будет условия WHERE firstColumn <= @daysInMonth
Все-таки эта штука со счетчиком - она полагается на строго определенный порядок увеличения счетчика, обхода строк.
>>982041
required по моему влияет только на установку атрибута html5 required на инпуте, и все (если я не путаю).
Есть такая вещь: http://symfony.com/doc/2.7/form/data_based_validation.html
И такая: http://symfony.com/doc/2.7/form/use_empty_data.html
Они не годятся?
>>981825
Там просто надо выбрать страны, сгруппированные по месяцам. И взять текущий месяц +/- 2 месяца вперед/назад.
>>981754
Никак, если приз ценнее, чем затраты на накрутку голосования, то его будут накручивать.
Разве что как-то подтвержать личность. Потому что даже номера телефонов можно скупить в большом количестве, если это стоит меньше, чем приз.
>>981752
Скорее всего нет.
>>981572
Возможно программа phpMyADmin просто не поддерживает JSON колонки? Может на их форуме или в интернете поискать эту ошибку?
Ты тут полагаешься на использование увеличивающейся переменной, но ведь можно сделать проще и надежнее. Сгенерировать таблицу с числами от 1 до N с помощью формулы SELECT id * 7 + column:
1 2 3 4 5 6 7
8 9 10 11 ...
И затем из чисел в ней вычесть смещение, соответствующее номеру первого дня.
Тогда может быть даже не понадобится внешний запрос, достаточно будет условия WHERE firstColumn <= @daysInMonth
Все-таки эта штука со счетчиком - она полагается на строго определенный порядок увеличения счетчика, обхода строк.
>>982041
required по моему влияет только на установку атрибута html5 required на инпуте, и все (если я не путаю).
Есть такая вещь: http://symfony.com/doc/2.7/form/data_based_validation.html
И такая: http://symfony.com/doc/2.7/form/use_empty_data.html
Они не годятся?
>>981825
Там просто надо выбрать страны, сгруппированные по месяцам. И взять текущий месяц +/- 2 месяца вперед/назад.
>>981754
Никак, если приз ценнее, чем затраты на накрутку голосования, то его будут накручивать.
Разве что как-то подтвержать личность. Потому что даже номера телефонов можно скупить в большом количестве, если это стоит меньше, чем приз.
>>981752
Скорее всего нет.
>>981572
Возможно программа phpMyADmin просто не поддерживает JSON колонки? Может на их форуме или в интернете поискать эту ошибку?
Я это понимаю, что там сортировка по дате, но как убрать лишнее и чтобы расположение было такое?
1 страница
1 новость
2 новость
3 новость
4 новость
5 новость
2 страница
1 новость
2 новость
3 новость
4 новость
5 новость
3 страница
1 новость
2 новость
3 новость
4 новость
5 новость
4 страница
2 новость
3 новость
4 новость
5 новость
6 новость
5 страница
3 новость
4 новость
5 новость
6 новость
7 новость
http://ideone.com/xDwbbM
Я это понимаю, что там сортировка по дате, но как убрать лишнее и чтобы расположение было такое?
1 страница
1 новость
2 новость
3 новость
4 новость
5 новость
2 страница
1 новость
2 новость
3 новость
4 новость
5 новость
3 страница
1 новость
2 новость
3 новость
4 новость
5 новость
4 страница
2 новость
3 новость
4 новость
5 новость
6 новость
5 страница
3 новость
4 новость
5 новость
6 новость
7 новость
http://ideone.com/xDwbbM
https://pastebin.com/exhuPHzp
Да, вычитание смещения это хитро, я бы не додумался до такого.
> Тогда может быть даже не понадобится внешний запрос, достаточно будет условия WHERE firstColumn <= @daysInMonth
Тут ведь firstColumn это alias? У меня в MySQL WHERE не заработал, только HAVING: http://stackoverflow.com/a/942592
И вроде WHERE firstColumn <= @daysInMonth не будет отсеивать полностью пустые строки (как на пике). Поэтому я отсеиваю через NOT (Пн = 0 AND Вск = 0)
И теперь вместо реквестов
require_once (__DIR__. Students\models\Auth.php');
require_once (__DIR__. Students\models\Helper.php'); Пишутся эти ЮЗИ
use FrontController\Helper;
use FrontController\Auth;
В чем сокральный смысл? Хуярить слешами НазванияПространтв/НазванияКласса тоже не круто.
Вместо Auth::login();
Писать Students/Auth::login();
Либо require, либо use, либо Students/
Разве это всё не одно и тоже? Ну за исключением того, что можно использовать одинаковые названия методов, классов(что блядь приведёт к неминуемой путанице ИМХО).
> Либо require, либо use
Как раз таки use необязательно писать если ты запрашиваешь класс из того же неймспейса. К примеру, у тебя такая структура проекта:
src/
-- класс Foo c namespace App,
-- класс Bar c namespace App,
То теперь в файле Bar тебе не нужно писать use App\Foo, так как и Foo и Bar в одном и том же неймспейсе. А require'ы ты обязан писать всегда. Ещё в IDE или редакторах с плагинами за тебя use будет генерировать сам редактор, а require за тебе никто генерировать не будет.
Вроде:
for($i=0;$i<=2;$i++){
$var{$i} = $i;
}
, только с foreach
Может просто засунуть весь проект в один namespace? Ну тогда правда всем php файлам нужно будет написать в шапке namespace ИмяПространстваИмен; И с подгрузкой файлов не придётся трахаться, всё верно? Только с левыми библиотеками придётся дёргать обратный слэш.
Или если каталог файлов такой
Project/controllers/MainController
Project/models/MainModel
И объвить неймспейс Project....то будет ли работать без USE и дроча с папками и слэшами - MainModel в MinController?
могет, если ты скомпилируешь код в исполняемый файл и заставишь пользователя его открыть.
Рабочей средой жаваскрипта был браузер и веб-страничка. У пхп - интерпретатор, веб-сервер, куда заходят.
Сейчас Жаваскрипт можно также запускать на веб-сервере, чтобы он выполнял логику,
> Ну тогда правда всем php файлам нужно будет написать в шапке namespace
Даже это необязательно. Попробуй положить все классы в папку src, а в composer.json пропиши автозагрузку так: https://pastebin.com/2WxRxWXB
И нет, если ты раскидаешь классы по разным папкам, но оставишь их с одним неймспейсом, то композер этого не поймёт.
Подскажите,а можно ли в цикле foreach, указывать уникальные номера переменным,как это можно с помощью обычного for?
Вроде:
for($i=0;$i<=2;$i++){
$var{$i} = $i;
}
, только с foreach
Забыл добавить свой вариант проверки, вот он:
$check = true;
if(isset($_POST['sort_by_id']))
{
if ($check) {
$query1 = "SELECT FROM films ORDER BY Film_id ASC";
}
else {
$query1 = "SELECT FROM films ORDER BY Film_id DESC";
}
Траханные вы в жопу программисты косноязычные твари, ненавижу вас, пидарасов.
Какой вы браузер юзаете для разработки хром или лису?
Нене, ты давай сперва объясни мне схуяли по твоему cli конфиг у пхп именно на винде богомерзкой отличается от серверного? Не можешь? Вот и нахуй иди. Это нормальная практика, а ты дебил блядь очередной.
>Даже это необязательно. Попробуй положить все классы в папку src, а в composer.json пропиши автозагрузку так: https://pastebin.com/2WxRxWXB
ЭМММ, создать папку scr и засунуть туда model/config/components во всех папках есть файлы с классами...
Ето так
В том, что винда говно, он прав однозначно. На ней танцев с бубнами гораздо больше, касаемо создания среды разработки для веба как минимум.
this. На рабочем компе что-то настраивается и конфигурируется с полпинка, а на шинде: тут в path добавь, сюда скачай, здесь в конфиг пропиши, аазазазаза, порт заблокирован, сладенький. Я ебал это говно. На сахарной убунточке за 20 минут настраиваю ламп и приблуды к нему, здесь заебался бубном трясти.
Бамп вопросу.
Нет РНР, ебать лохи.....
Apache_MySQL+PHP устанавливается минут за 5-10 не из консоли. А чтобы из консоли - надо её знать, тогда ещё меньше времени на установку.
>>982714
В данном случае говно его руки и невежество. Он не из-за винды ебался два дня, а из-за того, что нихуя не знает про настрйоку пхп. Касается это не только апача. В итоге у него лыжи не едут и он во всем винит систему, так и не поняв в чем суть за два то дня, как удобно, ебал я таких дурачков.
https://github.com/grigoryMovchan/sandbox_php/blob/master/fizzbuzz.php
Выдает FizzBuzz для 0 и ничего для 100 (т.е. не решено, плохо даже если пишешь ради смехохуечков)
Падает с fatal error при $firstWordTrigger = 0 (не проверяет входные параметры)
Вью не подготовлен для вызова скрипта через консоль.
Ну и $index вместо $i для итератора тоже будет вызывать бугурты.
Я так и не понял. Ты хотел максимально плохо или максимально переусложненно сделать.
> https://github.com/grigoryMovchan/sandbox_php/blob/master/fizzbuzz.php#L55+L63
Не понимаю, почему так много условий используется, можно же проще: https://ideone.com/prz7YP
>>983245
Двачну насчёт консоли, тоже это смутило. Классы есть, а гибкости и удобства нет.
Тут неправильно используются классы. К примеру, объект FizzBuzz - что он представляет? Какую сущность он моделирует?
Если ты пытался показать, что ООП для тебя выглядит сложными и запутанным, то ты недостаточно старался - есть более солидные работы, например https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition
Хочу также добавить, что люди считают ООП "переусложненным" только потому, что не понимают, что это и как правльно его использовать. Точно так же как начинающий, не осиливший функции, может удивляться, зачем разделять код на отдельные файлы и функции, когда можно просто написать все стеной вперемешку с HTML в одном файле.
>require_once (__DIR__. Students\models\Auth.php');
> Auth::login();
и
> Students/Auth::login();
Неужели разницы не видно? Просто берешь и пишешь "Папка"/класс вместо богомерзких реквайрев.
Алсо, у тебя уже ошибка там, кавычку пропустил. Так что неймспейсы это круто, мечтаю о нормальной реализации в js.
Читал ли ты мой урок? https://github.com/codedokode/pasta/blob/master/php/autoload.md
Неймспейсы не были придуманы ради автозагрузки. Они нужны для защиты от конфликта имен (появления 2 классов с одинаковыми названиями). Один из вариантов борьбы - делать длиннющие имена классов, другой - добавить неймспейсы, которые позволяют эти длиннющие названия записывать короче.
А потом уже оказалось, что эту особенность можно использовать для автозагрузки, поставив соответствие между неймспейсами и папками. Но такая возможность была и раньше, раньше просто подчеркивания в имени класса заменяли на слеши.
Я его джаст фор фан для треда в бэ сделал. Но раз оно тут вызвало такой ажиотаж, то постараюсь допилить в меру ваших замечаний.
Новый репозиторий https://github.com/grigoryMovchan/FuzzBuzz
>>983245
>Выдает FizzBuzz для 0 и ничего для 100
Падает с fatal error при $firstWordTrigger = 0 (не проверяет входные параметры)
Исправил
>Вью не подготовлен для вызова скрипта через консоль.
Никогда не запускал скрипты через консоль. Попытался запилить. Работает. Реализация хромает, но уже хочется.
>>983260
>Не понимаю, почему так много условий используется, можно же проще
ИНКАПСУЛЯЦИЯ @ ПОЛИМОРФИЗМ troll.jpg
>>983268
>Какую сущность он моделирует?
Отделил логику от представления
переписать на шаблоны, чтобы хотя бы шапка и подвал отдельно подключались и не дублировался код из них
<input type="radio" class="variant" value="1">
<input type="radio" class="variant" value="2">
<input type="radio" class="variant" value="3">
Надо сделать определённое действие при выборе любой из них, как описать это на jQuery? Не могу понять как описать именно выбранную радиокнопку.
Лол, имбецил дурной, ты думаешь разработка ведется из под маков/линухов просто так? Спермораб за свою винду топит.
Когда в следующий раз будешь уже на линухе пытаться выполнить консольный скрипт с конфигом от сервера на него тоже лопату говна вкинь, дебич. А вообще пиздуй из профессии. Раз уж ты не можешь понять где ты обосрался тебе любая ось и окружение мешать будет.
Я не тот человек, просто макнул тебя лицом в говно, еблан. Если ты привык жрать сперму - не хвались этим.
БАМП.
Винда говно, сути дела не меняет, такое поведение норма для пхп на любой системе, стажер ебаный.
И там и там.
Просто добавь айди
Сумимасе, семпаи!
>Match a single character present in the list [a-zA-z0-9_+.-]+ between one and unlimited times
Вообще охуели не читать сперва хоть что-нибудь по теме?? Мусор ебаный.
Найдёт и то, и то, но если только ты доменную зону допишешь: U:+SSANUSeSdimailPUNCTUMcosDIm и US%Tb1ANUSEMAIL[#4PUNCTUMCv(4OM, например. Иначе не найдёт ни того, ни другого - там стоит же точка, она обязательна.
Помоему ты не прав, точка там в качестве символа только. Эта регулярка должна найти и два изначальных варианта, и два тобою предложенных и даже ".@.". Что в целом делает ее некорректной для работы с мылом.
us1@email - найдет
us1@EMAIL - нет так как после @ там в регулярке стоят только маленькие буквы, и нет флага i, указывающего что регистр букв игнорируется при сравнении.
> Квадратные скобки в регулярных выражениях обозначают либо то, либо другое.
Они обозначают "один любой из указанных в квадратных скобках символов".
Ну и да, апперкейз в домене не найдет конечно же, проглядел. Так что эти варианты не заедут.
Как сделать:
>>https://github.com/enotocode/minesweeper.mvc/blob/master/app/BrowserView.js
>>Тут у тебя жестко прописаны id и селекторы элементов, и мы не можем поместить на 1 странице несколько BrowserView (привязанные к одной или разным моделям), жаль. Ну и ссылка на document жестко прописана.
Мне видятся два варианта. Как сделать лучше, есть ли другие решения?
1. генерировать уникальный случайный айди при создании экземпляра класса BrowserView, он будет добавляться к id всех сгенерированных dom-объектов, чтобы иметь доступ к ним через getElementById.
2. хранить сгенерированные элементы внутри экземпляра класса и изменять их свойство innerHTML.
Сап, аноны. Я полный ноль в php, знаю только css, html и немного ruby on rails. Нужно сделать мини-приложение (есть бд в postgresql, нужно редактировать и выводить данные на страницу) с ГУИ. Подскажите самый простой и быстрый способ.
Можно сделать так:
- убрать id из кода. Ну например, передавать в конструктор View просто нужный DOM элемент:
var div1 = ...
var view1 = new BrowserView(div1);
А если он сам его создает, то не присваивать ему id, а только сохранять ссылку на него.
Элементы внутри можно искать не по id, а например по названиям классов или дата-атрибутам. У тебя id используется для поиска ячеек, но ячейку в таблице можно искать по номеру столбца и строки как table.rows.cells[j]
Второй вариант - это из старых времен когда не было функций вроде querySelector, использовать иерархические id. То есть мы делаем у элементов id вида
<div id="view1/someElement/somePart">
<div id="view2/someElement/somePart">
который содержит в себе id родительского элемента + слеш + название подэлемента. Если слеш использовать в id нельзя, можно взять другой символ. В твоем случае можно было бы присваивать ячейкам id вроде view1/10/20.
Сейчас так не делают, проще искать элементы внутри view по имени класса или атриутам. А в твоем случае - по номеру строки/столбца.
Привет ребятки, помогите настроить пхп шторм. Как пофиксить отступы между строками и нумерацией строк? Что это за хуита? (выделил желтым) Как убрать бары которые выделил красным и серым?
Алсо реквест годных тем для оформления, а то смотрится эта штука как-то совсем не очень.
вбросьте свои оформления
С отступами тоже чек, осталось правый бар с этой полосочкой всратой убрать. И ГЛАВНОЕ ТЕМУ ТЕМУ, ЧТОБЫ БЫЛО КРАСИВО КАК В АТОМЕ ИЛИ СУБЛИМЕ!11111111
СУБЛИМЕ монокай тема, гугли. По дефолту в шторме вообще даркула доступна, хорошая тема, откуда ты этот вырвиглаз достал чет хз.
А вообще он и так доступен должен быть.
У тебя хуйня какая-то. вот дефолтный из шторма. Правда выглядит он все равно как говно.
Если речь о MySQL, то в 2 запроса: первым выбираешь текущую и N предыдущих записей, вторым - N следующих. Объединить их можно при желании через UNION, а можно на стороне PHP.
Если у тебя дан массив в PHP, то аналогичным образом, с помощью отсеивания и сортировок. Ну то есть оставляешь только элементы с текщей или меньшщей датой, сортируешь, берешь N, и так далее.
>>982369
> IF(id + 1 < 1 OR id + 1 > @daysInMonth
Еще можно использовать использовать (id + 1) BETWEEN 1 AND @daysInMonth
> Тут ведь firstColumn это alias? У меня в MySQL WHERE не заработал,
Тогда можно использовать id, WHERE id + 1 <= @daysInMonth или как-то так.
> И вроде WHERE firstColumn <= @daysInMonth не будет отсеивать полностью пустые строки
Мне кажется, будет, если понедельник больше, чем число дней в месяце то вторник и далее можно не проверять. Или ты про первую строку, которая может оказаться пустой? Для нее можно поставить условие вроде id + 7 >= 1 или как-то так.
Ну в любом случае, твое решение верное, думаю ты теперь хорошо разбираешься в написании сложных SQL запросов.
Дальше можешь изучать индексы, оптимизации и денормализацию. Так как на практике часто скорость выполнения "правильных" запросов недостаточная и требуется их ускорить.
>>982413
>>982442
Не надо писать $var{$i}, и вообще не надо использовать "переменные переменные", надо использовать массив в таких случаях.
>>982416
Если у тебя мало классов то можно, но когда их станет много, будет неудобно что они все в одной папке.
Про то как что работает лучше всего прочесть в офиц. мануале.
Ну и прочти мой урок про PSR-4, название controllers - не соответствует PSR-4.
>>982444
Если (сортировка не задана или равна ASC) {
сортировать по возрастанию, а в ссылке с этой колонкой выводить DESC
} иначе {
сортировать по убыванию, а в ссылке писать ASC
}
Почему для сортировки используется POST? Изучи, когда применяется POST и когда GET. передавать лучше не параметр вида sort_by_id, а 2 параметра с именем поля и направлением, или объединить их в одно поле вида +date, -date.
Если речь о MySQL, то в 2 запроса: первым выбираешь текущую и N предыдущих записей, вторым - N следующих. Объединить их можно при желании через UNION, а можно на стороне PHP.
Если у тебя дан массив в PHP, то аналогичным образом, с помощью отсеивания и сортировок. Ну то есть оставляешь только элементы с текщей или меньшщей датой, сортируешь, берешь N, и так далее.
>>982369
> IF(id + 1 < 1 OR id + 1 > @daysInMonth
Еще можно использовать использовать (id + 1) BETWEEN 1 AND @daysInMonth
> Тут ведь firstColumn это alias? У меня в MySQL WHERE не заработал,
Тогда можно использовать id, WHERE id + 1 <= @daysInMonth или как-то так.
> И вроде WHERE firstColumn <= @daysInMonth не будет отсеивать полностью пустые строки
Мне кажется, будет, если понедельник больше, чем число дней в месяце то вторник и далее можно не проверять. Или ты про первую строку, которая может оказаться пустой? Для нее можно поставить условие вроде id + 7 >= 1 или как-то так.
Ну в любом случае, твое решение верное, думаю ты теперь хорошо разбираешься в написании сложных SQL запросов.
Дальше можешь изучать индексы, оптимизации и денормализацию. Так как на практике часто скорость выполнения "правильных" запросов недостаточная и требуется их ускорить.
>>982413
>>982442
Не надо писать $var{$i}, и вообще не надо использовать "переменные переменные", надо использовать массив в таких случаях.
>>982416
Если у тебя мало классов то можно, но когда их станет много, будет неудобно что они все в одной папке.
Про то как что работает лучше всего прочесть в офиц. мануале.
Ну и прочти мой урок про PSR-4, название controllers - не соответствует PSR-4.
>>982444
Если (сортировка не задана или равна ASC) {
сортировать по возрастанию, а в ссылке с этой колонкой выводить DESC
} иначе {
сортировать по убыванию, а в ссылке писать ASC
}
Почему для сортировки используется POST? Изучи, когда применяется POST и когда GET. передавать лучше не параметр вида sort_by_id, а 2 параметра с именем поля и направлением, или объединить их в одно поле вида +date, -date.
Мне кажется, ты не понял что такое модель. Потому что это не то, что ты описал. Читал мой урок про MVC? https://github.com/codedokode/pasta/blob/master/arch/mvc.md
>>982643
В Дебиане например 2 комплекта php.ini файлов (отдельно для cli и для Апача) - а в винде один. Так что спорный вопрос.
>>982724
^ это привязка к началу строки и естественно она может стоять только в начале регулярки.
>>983047
Создаешь на сервере временное хранилище файлов. При загрузке файла сохраняешь его туда. При ошибке выводишь форму, а около поля для файла выводишь информацию о сохраненном на сервере файле (можно например сохранить его идентификатор в скрытом поле, главное чтобы злоумышленник его не подобрал, чтобы он не был предсказуемым). Выводишь галочку удаления сохраненного файла, если это возможно. При желании можно сделать кастомный инпут, который будет выглядеть как будто файл уже выбран. Можно пойти дальше, выодить превьюшку для картинок и тд.
При отправке формы надо соответственно проверять:
1) приложен ли к ней файл
2) передан ли идентификатор сохраненного файла
3) выбрана ли опция удаления сохраненного файла
Это конечно все стоит абстрагировать и вынести в отдельный класс, чтобы подключение было максимально простым.
После успешной проверки формы файл перемещается из временного хранилища в постоянное.
Также, надо будет написать сборщик мусора, удаляющий невостребованные файлы после определенного срока.
Другой вариант - отправлять форму через аякс без перезагрузки страницы.
>>983344
В браузере проще ставить Content-Type чем выводить теги. Также, до сих пор нет пояснения, какую сущность моделирует класс FizzBuzz.
>>983367
Выбранное значение можно получить через $('.variant:checked').val() если я не путаю. http://api.jquery.com/val/
Что значит "как описать"? Если ты имел в виду "как повесить обработчик на выбранную кнопку" то у тебя серьезное непонимание того, как работает jQuery. Это не CSS, там нельзя писать селекторы и правила для них.
Надо повесить обработчик на родителя кнопок с фильтром через on() и в нем уже проверять, какая кнопка нажата.
Мне кажется, ты не понял что такое модель. Потому что это не то, что ты описал. Читал мой урок про MVC? https://github.com/codedokode/pasta/blob/master/arch/mvc.md
>>982643
В Дебиане например 2 комплекта php.ini файлов (отдельно для cli и для Апача) - а в винде один. Так что спорный вопрос.
>>982724
^ это привязка к началу строки и естественно она может стоять только в начале регулярки.
>>983047
Создаешь на сервере временное хранилище файлов. При загрузке файла сохраняешь его туда. При ошибке выводишь форму, а около поля для файла выводишь информацию о сохраненном на сервере файле (можно например сохранить его идентификатор в скрытом поле, главное чтобы злоумышленник его не подобрал, чтобы он не был предсказуемым). Выводишь галочку удаления сохраненного файла, если это возможно. При желании можно сделать кастомный инпут, который будет выглядеть как будто файл уже выбран. Можно пойти дальше, выодить превьюшку для картинок и тд.
При отправке формы надо соответственно проверять:
1) приложен ли к ней файл
2) передан ли идентификатор сохраненного файла
3) выбрана ли опция удаления сохраненного файла
Это конечно все стоит абстрагировать и вынести в отдельный класс, чтобы подключение было максимально простым.
После успешной проверки формы файл перемещается из временного хранилища в постоянное.
Также, надо будет написать сборщик мусора, удаляющий невостребованные файлы после определенного срока.
Другой вариант - отправлять форму через аякс без перезагрузки страницы.
>>983344
В браузере проще ставить Content-Type чем выводить теги. Также, до сих пор нет пояснения, какую сущность моделирует класс FizzBuzz.
>>983367
Выбранное значение можно получить через $('.variant:checked').val() если я не путаю. http://api.jquery.com/val/
Что значит "как описать"? Если ты имел в виду "как повесить обработчик на выбранную кнопку" то у тебя серьезное непонимание того, как работает jQuery. Это не CSS, там нельзя писать селекторы и правила для них.
Надо повесить обработчик на родителя кнопок с фильтром через on() и в нем уже проверять, какая кнопка нажата.
Если не проверять на сервере, тебе в базу мусора могут напихать.
>>984508
Можно с точки зрения PHP там почти любой код писать, единственное что конструктор в отличие от обычной функции, не может ничего вернуть через return.
Но с точки зрения архитектуры может оказаться неправильно что ты что-то делаешь в конструкторе. Его задача ведь просто подготовить объект к работе и заполнить поля начальными значениями.
И я не очень понял какое отношение strip_tags или trim имеют к валидации.
Вообще от логики зависит. Если по логике ты принимаешь грязные значения в конструкторе, а работать хочешь уже с чистыми, то в конструкторе их обработка как раз в тему.
>Мне кажется, ты не понял что такое модель. Потому что это не то, что ты описал. Читал мой урок про MVC? https://github.com/codedokode/pasta/blob/master/arch/mvc.md
Блеять, вот не надо снова.
Модель - это всего лишь класс в файле, который лучше назвать по имени этого класса. В нём всё определено - свойства и методы для работы (они могут получать данные из БД или с помощью конструктора).
В контроллере прописан конкретный URL, по которому сработает нужный экшн с созданием экземпляра модели (или с чем-то другим, что связано), получатся какие-то данные из модели и отдадутся в вид.
Вот не надо меня снова путать, ОП!
А типа контроллер это не класс в файле? А типа %сущность нейм% это не класс в файле? И чем они тогда от модели отличаются, мм? У них у всех и поля и методы и все на свете есть или может быть.
Ну это-то да, но не путай меня!!11
Ну просто модель - это самый главный класс в файле, от него надо плясать, в нём всё содержится, а дальше работают контроллер и вид.
Просто когда с нуля идёшь и не нюхал конкретных примеров (а я долго не мог понять так, чтобы не глядя сообразить, как надо), то так проще: модель - класс, который отвечает на саму суть, контроллер - ну тоже класс, который вспомогательный и связывает с URLом конкретным, а дальше всё мы получаем в виде.
Это очевидным становится в какой-то момент, далеко не сразу, потому что многое путает, не понятно, что тут главное.
Да ООП-то збс, на самом деле, там всё удобно.
Если бы ты мог трезвой башкой оценить как ты ебануто пишешь, то не называл бы програмистишек косноязычными. Ну если тебе так проще - хуярь на основе этих выводов.
1 2 3
1 2 3
Как сделать что бы значения то были ?
array_rand возвращает ключ (индекс), а не значение. А что нужно написать что бы обратиться к элементу массива $word1 с индексом str1?
Есть какое-нибудь решение чтобы объединить два сервера и/или хостинга в один? Или обычно просто указывают абсолютный адрес изображения в шаблоне?
Как преобразовать $_GET запрос отправляемой формы из /search.php?q=... в /search/... ? Нужно разбирать ссылку в контроллере и делать ридерект?
Хотелось бы иметь собственное доменное имя. Но мне с этим не очень понятно - Провайдер обращается к корневому доменному серверу, корневой сервер перенаправляет запрос к серверу верхнего уровня, сервер верхнего уровня к авторитетному серверу. Есть какой-нибудь способ создать собственный авторитетный сервер? Я нашел много статей об этом BIND, но действительно ли методы описанные там могут позволить дать доступ к моему домену для всего интернета?
Используй какую-нибудь сетевую файловую систему чтобы с одного сервака обращаться к другому, где хранится говно, как к файлам на машине, а не по сетевому адресу.
Я хз. К тому же в эхо я вписываю $res, а в нем уже 3 массива. Как к ним ко всем то обратиться ?
В $res нету никаких массивов. Там только строка склеенная из трех случайных чисел которые ты получил из array_rand. попробуй вместо $str1 $word1[$str1] в 24 строке.
> контроллер - ну тоже класс, который вспомогательный
Вот поэтому я (не ОП) советую людям в студентах делать контроллер не классом, а обычным скриптом, чтобы лучше понимали MVC. MVC это в первую очередь о разделении ответственностей, это идея, а не строгий набор классов. Идея отвязать данные и представление друг от друга. Проблема в том, что люди не изучают ООП на нормальном уровне (разделение ответственности, связность/связанность, DI) и сразу лезут читать об MVC, бездумно принимая всё новое как догму. А ведь MVC это лишь одна из возможных реализаций принципа разделения отвественности. В React+Redux не MVC, но данные от представления тоже отделены.
Ну и вот цитата из доков Symfony: "When creating a framework, following the MVC pattern is not the right goal. The main goal should be the Separation of Concerns; this is probably the only design pattern that you should really care about."
> а я долго не мог понять так, чтобы не глядя сообразить, как надо
Нужно понимать, а не учить, тогда и подглядывать никуда не нужно будет.
Алсо в PHP-фреймворках контроллер-класс это вообще груда независимых методов, вот тут интересные мысли про ADR: https://habrahabr.ru/post/260769/
Просто для каждого экшна неудобно передавать одни и те же сервисы, вот их и группируют в классы-контроллеры.
> Просто когда с нуля идёшь
Так большинство и учатся, тебе кто-то мешает читать про SOLID, юнит-тесты?
Ну так и вот, как мне определить, какой пункт выбран?
ОП, скинь пожалуйста файлы (картинки, шебм) к тредам 18-59. И сохранился ли HTML 25-го треда не с архивача, а с двача? А то отдельно парсить придётся, так как у него другая разметка. Текущий парсер парсит нормально всю информацию из всех тредов, за исключением 25-го (т.к HTML с архивача) и нескольких постов из 1-го (т.к. ошибки в HTML).
>>984823
Нужно учитывать, что файлов будет где-то на 2 ГБ (треды 1-17+60-80 весят 750 мб). Кстати если не сохранять шебмки, то должно хватить 500 мб на все треды и быть может не понадобится облачное хранилище.
> Как преобразовать $_GET запрос отправляемой формы из /search.php?q=... в /search/... ? Нужно разбирать ссылку в контроллере и делать ридерект?
Это неэффективно. Ты можешь через JS по клику на кнопку перенаправлять браузер на /search/query/, а в случае отключенного JS, отправлять обычный GET запрос вида /serach?q=123.
Тяжело читать, переводить и, при этом ещё, запоминать документацию. Попробую восполнить пробелы спросив что мне не понятно.
Цепь блоков состоит из узлов. Когда мы устанавливаем Bitcoin Core мы создаем новый узел?
Когда мы ставим Bitcoin Core мы всегда должны иметь все блоки которые есть в сети? Сейчас их размер составляет свыше 100Gb - будет довольно дорого арендовать VPS с таким выделенным пространством.
В примерах приведенных в документации есть пример с командой sendtoaddress https://bitcoin.org/en/developer-examples#simple-spending . Там создается новый кошелек на который переводиться сумма, но не создается кошелек с которого это сумма переводиться. При установке клиента Bitcoin Core - это же клиент? даётся какой-то стандартный кошелек с которым работает эта команда?
Наверно, лучше использовать raw transaction.
>Там интересная схема. Там при создании кошелька генерируется набор случайных байт (то есть очень большое число). Это закрытый, секретный ключ, который позволяет делать любые операции с кошельком (им подписываются транзакции). Из этого ключа необратимым преобразованием генерируется открытый ключ (по моему, просто берется хеш от закрытого ключа). Это публичный идентификатор кошелька.
Мне же не обязательно хранить закрытый ключ в БД, если я хочу чтобы у каждого пользователя был собственный кошелек? Ведь его можно получить в любой момент с помощью команды dumpprivkey.
>Соответственно когда ты создаешь новую транзакцию, и подписываешь ее закрытым ключом, участники сети, каждый, проверяют, что подпись соответствует открытому ключу и таким образом удостоверяются что ты именно владелец кошелька.
В примере с simple raw transaction ( https://bitcoin.org/en/developer-examples#simple-raw-transaction ) это делать не обязательно. Получается Bitcoin Core это всего лишь кошелек, который может работать только с его собственными адресами? Или же он может самостоятельно определить закрытый ключ чтобы отличить свои адреса от остальных, если он всё-таки содержит их?
Наверно, должен быть способ чтобы перенести закрытые и открытые ключи на другой носитель. Как они хранятся?
Тяжело читать, переводить и, при этом ещё, запоминать документацию. Попробую восполнить пробелы спросив что мне не понятно.
Цепь блоков состоит из узлов. Когда мы устанавливаем Bitcoin Core мы создаем новый узел?
Когда мы ставим Bitcoin Core мы всегда должны иметь все блоки которые есть в сети? Сейчас их размер составляет свыше 100Gb - будет довольно дорого арендовать VPS с таким выделенным пространством.
В примерах приведенных в документации есть пример с командой sendtoaddress https://bitcoin.org/en/developer-examples#simple-spending . Там создается новый кошелек на который переводиться сумма, но не создается кошелек с которого это сумма переводиться. При установке клиента Bitcoin Core - это же клиент? даётся какой-то стандартный кошелек с которым работает эта команда?
Наверно, лучше использовать raw transaction.
>Там интересная схема. Там при создании кошелька генерируется набор случайных байт (то есть очень большое число). Это закрытый, секретный ключ, который позволяет делать любые операции с кошельком (им подписываются транзакции). Из этого ключа необратимым преобразованием генерируется открытый ключ (по моему, просто берется хеш от закрытого ключа). Это публичный идентификатор кошелька.
Мне же не обязательно хранить закрытый ключ в БД, если я хочу чтобы у каждого пользователя был собственный кошелек? Ведь его можно получить в любой момент с помощью команды dumpprivkey.
>Соответственно когда ты создаешь новую транзакцию, и подписываешь ее закрытым ключом, участники сети, каждый, проверяют, что подпись соответствует открытому ключу и таким образом удостоверяются что ты именно владелец кошелька.
В примере с simple raw transaction ( https://bitcoin.org/en/developer-examples#simple-raw-transaction ) это делать не обязательно. Получается Bitcoin Core это всего лишь кошелек, который может работать только с его собственными адресами? Или же он может самостоятельно определить закрытый ключ чтобы отличить свои адреса от остальных, если он всё-таки содержит их?
Наверно, должен быть способ чтобы перенести закрытые и открытые ключи на другой носитель. Как они хранятся?
>Используй какую-нибудь сетевую файловую систему чтобы с одного сервака обращаться к другому, где хранится говно, как к файлам на машине, а не по сетевому адресу.
>сетевую файловую систему
Можно по конкретней, пожалуйста? Запрос в гугле выдал много разной информации.
>>984851
>Нужно учитывать, что файлов будет где-то на 2 ГБ (треды 1-17+60-80 весят 750 мб). Кстати если не сохранять шебмки, то должно хватить 500 мб на все треды и быть может не понадобится облачное хранилище.
Всё-таки, в тред можно отправить файлы общим размером 40Мб. Если максимализировать, то в каждом треде может быть вряд ли конечно, но, всё же, раз такая возможность не чем не запрещена, значит, это нужно соблюсти до и более 1000 постов с такими файлами.
>>984863
Так всегда делается при роутинге? Должны же фреймворки как-то обходиться без js.
>Также, до сих пор нет пояснения, какую сущность моделирует класс FizzBuzz.
Сори, не понимаю вопрос. Ты бы как сделал? Не стал бы создавать отдельный класс?
$("#form_quest").submit(function(){
//Ну и здесь дальше всякое разное
});
Пробовал делать событие клик по кнопке отправки, тоже самое получается. Как сделать так, чтобы после отправки формы через аякс приходящие с другой страницы данные можно было разметить на странице и они там бы остались. Я так понял вся проблема из-за того что страница перезагружается, как это избежать?
$emails = array(
'Test Example <tes})AtANUSexa1-ymplePUNCTUMcoYz]m>',
'test@localhost',
'tesfXItANUSlocalhos?dQtPUNCTUMcs&xom'
);
foreach ($emails as $email) {
echo (filter_var($email, FILTER_VALIDATE_EMAIL)) ?
"[+] Email '$email' is valid\n" :
"[-] Email '$email' is NOT valid\n";
}
http://php.net/manual/ru/filter.filters.validate.php
Вот определение из Википедии:
https://ru.wikipedia.org/wiki/Модель
> Модель (фр. modèle, от лат. modulus — «мера, аналог, образец») — это система, исследование которой служит средством для получения информации о другой системе; представление некоторого реального процесса, устройства или концепции
Ну например, мы можем на уменьшенной модели самолета изучать, как его обтекает воздух в аэродинамической трубе. Есть также такое понятие, как "математическая модель", то есть система формул, которые описывают какие-то процессы. Например математическая модель, описывающая движение жидкости, может использоваться для расчета того, как будет течь и какое давление будет создавать реальная жидкость в трубах. Модель в программировании близка по сути к математической модели, только она создается с помощью языка программирования.
"модель" в программировании - это абстрактная система (например, набор переменных и функций, или объектов), которая соответствует какой-то реальной системе, которую мы хотим изучить. Ну например, если у тебя задача учитывать товары на складе, то возможно у тебя будет класс Товар, который является "моделью" реального товара.
Отсюда и идет название компонента "model" в MVC.
Спасибо. Кстати, есть возможность это сделать короче ? А то у меня впечатление сложилось, что все можно было проще сделать, вот только хз как.
Я забыл один момент, на стороне ПХП перевожу нужную переменную в число, при помощи всех возможных методов intval, settype но если вывести полученные данные в аяксе то он всёравно пишет что string
Нужно знать в правильном ли я направлении начал писать код
Раздел "повторим" не проходил, так что сильно не обоссывайте
Да правильно, там же код есть в самом уроке.
У тебя ошибка. У тебя $questions передается как аргумент, и сразу же ты эту переменную перезаписываешь, кладя в нее пустой массив, и значит значение, которое хранилось там до этого, теряется.
У тебя там опечатка: correctAnwer и correctAnswer. А PHP, конечно же, "молодец", просто налету создал несуществующее свойство. Это одна из причин, почему к свойствам никогда напрямую не обращаются, а используют геттеры/сеттеры, но ты пока не морочь себе этим голову. Алсо questions1 ужасное название переменной.
>>985137
Он потом исправил на questions1: >>985044
Для того, чтобы понять принцип и просто выывести результат.
Можно сделать эту функцию методом внутри класса, а вывести как Question::createQuestion([все аргументы]);
Ну и там должны быть все echo внутри самого метода тогда, хотя это не вполне будет правильно и будет громоздко.
Вроде как-то так, блё, я хз.
/ Выполнение запроса с передачей ему массива параметров /
$sth = $dbh->prepare('SELECT *
FROM fruit
ORDER BY ? DESC');
$sth->execute(array('red'));
$red = $sth->fetchAll();
Почему не работает данный пример? Всяко пытался, но все равно не сортирует. В чем может быть ошибка?
http://php.net/manual/ru/pdo.prepare.php
>Если у тебя дан массив в PHP, то аналогичным образом, с помощью отсеивания и сортировок. Ну то есть оставляешь только элементы с текщей или меньшщей датой, сортируешь, берешь N, и так далее.
Можешь псевдокодом расписать?
Попробуй выполнить свой код на https://3v4l.org/ и посмотреть что за ошибка, если на айдеон не отображается.
Спасибо, там все норм. С айдеоном не то что то.
>есть
>>985393
>такой себе фреймворк
проясните в щщи, вопрос скорее общий. все время будет так всрато?
вроде все красиво, все раскидываеться по полочкам при желании, одм-орм внятная б.м. и вольт можно послать нахуй, но все равно что-то мешает просто брать и делать (не вхожу в поток в терминах смузисосеров). ну и доки всраты на 7/10 постоянно приходиться лезть в зефирный гит и искать хинты.
с учетом того что это по большей части кроновый пет-проект, a круд и вся ботва будет в общем и целом на фронте, стоит продолжать надрачивать на такуюто скорость с модельной метой и насиловать привычки или перекатиться на laravel пока не поздно?
из бекграунда yii, cake, silex, ci и крапаль зенда со вторым сифоном.
олсо 985393 - анон проясни плз за hr. как часто хайрите людей, быстро ли закрываете позицию и если берете под обучение сколько у среднего кандидата уходит на вкатывание.
Вот это ПРОФЕССИОНАЛЬНЫЙ ЖАРГОН
Проблема в том, что мне нужно получить число в определённом случае именно на стороне ПХП, так как если в аякс приходит число выполняется одно действие, а если строка то другое.
> все время будет так всрато?
Зависит от задач, у нас на фальконе в основном API (рест), для того чтобы грамотно сделать архитектуру приложения под это, пришлось писать дополнительную библиотеку, которая работает поверх фалькона. Но это уже специфика, мне например очень не понравился их PHQL в целом, он ограничен и предназначен только для простых селектов. Но в работе ты привыкаешь его использовать, и потом натыкаешься на подводные камни когда какие-то SQL запросы просто отказываются работать из-за того что нет поддержки определенных команд. И приходится уже использовать Raw SQL, а там своя специфика работы с этим.
> ну и доки всраты на 7/10 постоянно приходиться лезть в зефирный гит и искать хинты
Это да, благо зефир это не си, и в основном у них простой и понятный код там.
> стоит продолжать надрачивать на такуюто скорость с модельной метой и насиловать привычки или перекатиться на laravel пока не поздно?
Про laravel ничего не скажу, с ним не работал. Если кроновый пет-проект я бы не стал надрачивать на скорость, просто бы делал на чем удобнее. С таким бэкграундом я думаю фалькон тебе легко зайдет, главное знать все нюансы, их там достаточно много.
> олсо 985393 - анон проясни плз за hr. как часто хайрите людей, быстро ли закрываете позицию и если берете под обучение сколько у среднего кандидата уходит на вкатывание
У нас на бэке раньше было два разработчика, теперь четыре, все из них с фальконом работают. Двух добрали вот недавно, по месяцу искали каждого (это джунов). Под обучение берем, в среднем у джуна уходит неделя на обучение, но сюда не только фреймворк входит, тут еще стандарты разработки внутри компании, канбан, ознакомление с стеком технологий (у нас хайлоад, используются различные сервера очереди, оперативные хранилища, кафка, кассандра и прочее) ну и с самим проектом на котором будут работать. У нас на собеседованиях довольно хороший отсев мамкиных вкатывальщиков, поэтому все кого взяли это вполне осиливали за неделю и теперь работают. Опять же тут зависит от прошлого опыта работы, если человек работал с симфони или зендом, то освоить фалькон ему не составит труда.
> все время будет так всрато?
Зависит от задач, у нас на фальконе в основном API (рест), для того чтобы грамотно сделать архитектуру приложения под это, пришлось писать дополнительную библиотеку, которая работает поверх фалькона. Но это уже специфика, мне например очень не понравился их PHQL в целом, он ограничен и предназначен только для простых селектов. Но в работе ты привыкаешь его использовать, и потом натыкаешься на подводные камни когда какие-то SQL запросы просто отказываются работать из-за того что нет поддержки определенных команд. И приходится уже использовать Raw SQL, а там своя специфика работы с этим.
> ну и доки всраты на 7/10 постоянно приходиться лезть в зефирный гит и искать хинты
Это да, благо зефир это не си, и в основном у них простой и понятный код там.
> стоит продолжать надрачивать на такуюто скорость с модельной метой и насиловать привычки или перекатиться на laravel пока не поздно?
Про laravel ничего не скажу, с ним не работал. Если кроновый пет-проект я бы не стал надрачивать на скорость, просто бы делал на чем удобнее. С таким бэкграундом я думаю фалькон тебе легко зайдет, главное знать все нюансы, их там достаточно много.
> олсо 985393 - анон проясни плз за hr. как часто хайрите людей, быстро ли закрываете позицию и если берете под обучение сколько у среднего кандидата уходит на вкатывание
У нас на бэке раньше было два разработчика, теперь четыре, все из них с фальконом работают. Двух добрали вот недавно, по месяцу искали каждого (это джунов). Под обучение берем, в среднем у джуна уходит неделя на обучение, но сюда не только фреймворк входит, тут еще стандарты разработки внутри компании, канбан, ознакомление с стеком технологий (у нас хайлоад, используются различные сервера очереди, оперативные хранилища, кафка, кассандра и прочее) ну и с самим проектом на котором будут работать. У нас на собеседованиях довольно хороший отсев мамкиных вкатывальщиков, поэтому все кого взяли это вполне осиливали за неделю и теперь работают. Опять же тут зависит от прошлого опыта работы, если человек работал с симфони или зендом, то освоить фалькон ему не составит труда.
У меня почти получилось! Как ограничить вывод массива?
Ща показывает все новости, типа так.
4 страница
1 новость
2 новость
3 новость
4 новость
5 новость
6 новость
7 новость
8 новость
9 новость
>использовать Raw SQL
ога, уже наткнулся на ту же херню с простейшими джоинами. в целом мне нравится общая система, но сдаеться мне его точили на классик веб, хайлоад и сервисы уже со скрипом. похоже это важный аргумент против, спасибо, прояснил от души, добра.
Джоины там нормально и с PHQL работают, просто нужно использовать ModelsManager, метод executeQuery. Таким образом результат уже будет не сущностью, а экземпляром класса ResultsetSimple или ResultsetComplex.
С одной страницы отдаю данные полученные с формы через Аякс где они обрабатываются. После обработки, функция используемого для этого отдаёт обратно на страницу либо id добавленной записи, либо текст с описанием ошибок ввода данных.
Получается ты отдаешь всегда string (даже если через echo пропускаешь int число), ajax парсит как строку. Отдавай например в формате json или xml. Тогда при парсинге ajax преобразует "42" в int 42. Или сам приводи к int. Пойми, что к числу в js можно привести число или строку, содержащую только число и пробельные символы. Полюбому у тебя получится или id или NaN, ёпте.
>isNaN("12") \\ false, 12 это число
>isNaN("12a") \\ true, строка не имеет математического смысла
>ModelsManager
ну да, я так и делаю, но чота оно так все больше на тупой orm на массивах из первых кейков смахивает. получается больше минусов чем плюсов в итоге. можно канешн впихнуть фабрику этого дерьма в basemodel или впилить behavior под себя но зачем весь этот корч, если есть возможность сменить на что то более подходящее под задачу. не хотеть, слишком уж геморно, дохуя усилий на инфраструктуру вместо логики. горит невероятно от гениального испанского решения пилить сверхпроизводительный и ультракастомизируемый оверхед-движок и не позаботиться о хотя бы вполовину такой же удобной orm для реальных задач а не васянских лендингов.
>Или сам приводи к int
Как это можно сделать на стороне ПХП? На странице куда идёт запрос аякса, работает функция, которая выдаёт либо id добавленной записи, либо текст с описанием ошибок. Если получаю id, то пишу (int)id, в аякс всёравно приходит строка.
Продолжу. Суть в том, что в правильность введения данных проверяется на стороне ПХП, в отдельном классе, но отправляю я туда данные при помощи аякса. Если данные введены не верно, то выводится сообщение с описанием ошибки.Если верно, то просто происходит переадресация при помощи яваскрипт по id добавленной записи. Я вроде бы нашёл выход из положения, сделал так:
if(msg.length<11) {
//делаем переадресацию
} else {
$("#errors").html(msg);
}
Понятно что это очень криво, но другого варианта не смог найти. Суть в том, что описание любой ошибки больше 11 символов, а у id не может иметь больше чем 11 цифр, поэтому если длина строки меньше 11, то значит это в любом случае id и надо делать переадресацию, если нет, то просто вывести описание ошибок. Главный вопрос, это слишком криво? так делать нельзя?
Расскажи пожалуйста, что должен знать/уметь нормальный кандидат в отличии от "мамкиного вкатывальщика"? Что вообще из себя представляет средний соискатель, который пролетает мимо работы?
Удвою вопрос.
ёбаный null, сука
На HH.ru посмотри по своему городу/области. Я даже на свою мухосрань пару вакансий видел
Я тоже с орм там поебался. Фалкон использую для апи. Несколько своих оберток и трейтов впиздюрил в модели, получше стало. Однако все равно иногда приходится ради хитрого джоина руками все делать. А так, конечно, ничего особо критичного, работать с ним можно.
Интересный вопрос, меня тоже интересует. Я пришёл к выводу, что нужно использовать сессии и их глобал массив, но это блядь ведь хуйня ебанная, все высчитанные параметры на одной странице записывать в массив, что бы на второй все эти данные вытащить...и работаиь с ними...потом опять в массив и снова из массива на 3 странице..чето сомневаюсь что это так должно быть.
Типа, там всё одинаковое и просто клонируй свою?
Я нашёл выход, страница перезагружалась потому что форма отправлялась, я убрал тег <form></form> и просто начал работать с отдельными полями <input>, событие поставил при клике на кнопку, всё отправляется нормально и прописывается в нужном диве, ничего не перезагружается. Я вот только не знаю, можно ли по правила оставлять input без <form>
https://github.com/grigoryMovchan/unmarriedLifestyle
https://github.com/grigoryMovchan/AphorismCMS
Код говно, это только прототип. Классы инкапсулированы, легко перекачу на MVC
Это работает, ечли у тебя ожна страница, а мне нужны данные на нескольких..
Ни хрена не подтянул, сучка, вообще не могу сделать миграции. Там проект на РНР5.04 рассчитан, а у меня РНР7.
Какие-то расширения не включены, хотя всё раскомментировано.
Вообще в гугле забанили, какая команда на винде для активизации композера для данного проекта? Я нипони.....
Разобрался: composer install в папке проекта, а затем php yii migrate.
Всё установилось, всё работает.
С одинарным же работает.
Ты где-то пояснял, но я не могу найти где, почини плес навигацию по урокам.
Бля, скрин кривой. А с поиском самого обратного слэша только с экранированием через два таких же.
Открыл две первые ссылки из гугла, в конце инфа из урока ОПа.
И того инфа по поводу \s с трёх разных ресурсов:
>пробел или табуляция
>пробел
>пробел или перевод строки
Это проблема русскоязычных? ВЕДЬ БЛЯДЬ ПРОБЕЛ И ПЕРЕВОД СТРОКИ ЭТО НАХУЙ ДВЕ РАЗНЫЕ ВЕЩИ, ещё и табуляция в придачу. Упоминать об этом совсем не стоит? Пусть ньюфаг сам ебётся потом когда у него из-за перевода строки будут регулярки по пизде бежать)))))
там же написано
Вот небольшая часть листинга:
/ Возвращает соответствующую числу форму слова: 1 рубль, 2 рубля, 5 рублей /
function inclineWord($number,$word1,$word2,$word5) {
$last2Digits = $number % 100;
if (($last2Digits >= 10)&&($last2Digits <= 20)){
return $word5;
}else if($last2Digits % 10 == 1){
return $word1;
}else if(($last2Digits % 10 >= 2)&&($last2Digits % 10 <= 4)){
return $word2;
}else{
return $word5;
}
}
/
Преобразует числа от 0 до 999 в текст. Параметр $isFemale равен нулю,
если мы считаем число для мужского рода (один рубль),
и 1 — для женского (одна тысяча)
/
function smallNumberToText($number, $isFemale) {
$spelling = array(
0 => 'ноль', 10 => 'десять', 100 => 'сто',
1 => 'один', 11 => 'одиннадцать', 20 => 'двадцать', 200 => 'двести',
2 => 'два', 12 => 'двенадцать', 30 => 'тридцать', 300 => 'триста',
3 => 'три', 13 => 'тринадцать', 40 => 'сорок', 400 => 'четыреста',
4 => 'четыре', 14 => 'четырнадцать', 50 => 'пятьдесят', 500 => 'пятьсот',
5 => 'пять', 15 => 'пятнадцать', 60 => 'шестьдесят', 600 => 'шестьсот',
6 => 'шесть', 16 => 'шестнадцать', 70 => 'семьдесят', 700 => 'семьсот',
7 => 'семь', 17 => 'семнадцать', 80 => 'восемьдесят', 800 => 'восемьсот',
8 => 'восемь', 18 => 'восемнадцать', 90 => 'девяносто', 900 => 'девятьсот',
9 => 'девять', 19 => 'девятнадцать'
);
$femaleSpelling = array(
1 => 'одна', 2 => 'две'
);
if($number % 100 !=0){
}
}
Не понимаю,что надо делать с функцией smallNumberToText. Типа, сам процесс. Надеюсь,кто-нибудь да поможет:3
Вот небольшая часть листинга:
/ Возвращает соответствующую числу форму слова: 1 рубль, 2 рубля, 5 рублей /
function inclineWord($number,$word1,$word2,$word5) {
$last2Digits = $number % 100;
if (($last2Digits >= 10)&&($last2Digits <= 20)){
return $word5;
}else if($last2Digits % 10 == 1){
return $word1;
}else if(($last2Digits % 10 >= 2)&&($last2Digits % 10 <= 4)){
return $word2;
}else{
return $word5;
}
}
/
Преобразует числа от 0 до 999 в текст. Параметр $isFemale равен нулю,
если мы считаем число для мужского рода (один рубль),
и 1 — для женского (одна тысяча)
/
function smallNumberToText($number, $isFemale) {
$spelling = array(
0 => 'ноль', 10 => 'десять', 100 => 'сто',
1 => 'один', 11 => 'одиннадцать', 20 => 'двадцать', 200 => 'двести',
2 => 'два', 12 => 'двенадцать', 30 => 'тридцать', 300 => 'триста',
3 => 'три', 13 => 'тринадцать', 40 => 'сорок', 400 => 'четыреста',
4 => 'четыре', 14 => 'четырнадцать', 50 => 'пятьдесят', 500 => 'пятьсот',
5 => 'пять', 15 => 'пятнадцать', 60 => 'шестьдесят', 600 => 'шестьсот',
6 => 'шесть', 16 => 'шестнадцать', 70 => 'семьдесят', 700 => 'семьсот',
7 => 'семь', 17 => 'семнадцать', 80 => 'восемьдесят', 800 => 'восемьсот',
8 => 'восемь', 18 => 'восемнадцать', 90 => 'девяносто', 900 => 'девятьсот',
9 => 'девять', 19 => 'девятнадцать'
);
$femaleSpelling = array(
1 => 'одна', 2 => 'две'
);
if($number % 100 !=0){
}
}
Не понимаю,что надо делать с функцией smallNumberToText. Типа, сам процесс. Надеюсь,кто-нибудь да поможет:3
Хорошо. Цитатник понравился, допиливай что задумал.
Нужно сделать массив и в него добавлять по очереди слова для сотен, десяток, единиц, если они есть в числе:
- если число содержит сотни, добавить слово для сотен
- если число оканчивается на 11-20, добавить соотв. слово
- если число содержит десятки, добавить слово для них
И так далее. В конце из массива собрать строку.
>>986681
Обратимся к мануалу: http://php.net/manual/ru/regexp.reference.escape.php
> \s
> любой пробельный символ
> Следующие символы считаются как "пробельные": HT (9), LF (10), FF (12), CR (13), и пробел (32). Тем не менее, если идет локале-зависимый поиск, и произойдет совпадение с символами в диапазоне 128-255, они также будут восприняты как пробельные, например NBSP (A0).
К "пробельным" относятся символы пробела, перевод строки \n, табуляция \t (она добавляет отступ), и более экзотичные спецсимволы \r (используется вместе с \n под Windows) и \f.
Также, при отстутсвии флага u к ним могут добавиться другие пробельные символы вроде символа с кодом 160 (неразрывный пробел), если он есть в кодировке, которая выбрана в текущей локали. Но это нас не должно касаться, так как мы используем юникод, а не однобайтовые кодировки.
А что происходит в юникодном режиме? Обратимся к документации по библиотеке pcre, которую используют preg-функции: http://www.pcre.org/original/doc/html/pcrepattern.html (англ) и ищем там выражение \s
> ....
> If PCRE is compiled with Unicode property support, and the PCRE_UCP option is set, the behaviour is changed so that Unicode properties are used to determine character types, as follows:
> \s any character that matches \p{Z} or \h or \v
Что такое "\p{Z}"? Это описано тут http://php.net/manual/en/regexp.reference.unicode.php и тут https://en.wikipedia.org/wiki/Unicode_character_property . В Юникоде у каждого символа есть категория: является ли он буквой, цифрой, разделителем или чем-то еще. \p{Z} - это символы из категории "разделители", они перечислены например тут:
- http://www.fileformat.info/info/unicode/category/Zl/list.htm
- http://www.fileformat.info/info/unicode/category/Zp/list.htm
- http://www.fileformat.info/info/unicode/category/Zs/list.htm
Также, про юникодные пробелы есть статья на англ: https://www.cs.tut.fi/~jkorpela/chars/spaces.html
Далее, посмотрим что такое \h и \v для pcre в ее мануале:
> The sequences \h, \H, \v, and \V are features that were added to Perl at release 5.10. In contrast to the other sequences, which match only ASCII characters by default, these always match certain high-valued code points, whether or not PCRE_UCP is set. The horizontal space characters are:
И далее там перечислены конкретные символы.
В общем, в юникодном режиме \s соответствует "старым" ASCII-символам вроде пробела, \n, \t, неразрывному пробелу + множеству юникодных пробелов и разделителей строк и абзацев.
Если ты не очень понимаешь что такое кодировки, юникод, то советую мою статью про них: https://github.com/codedokode/pasta/blob/master/cs/strings.md
Также, вот статья про юникод и регулярки на англ: http://www.regular-expressions.info/unicode.html
Нужно сделать массив и в него добавлять по очереди слова для сотен, десяток, единиц, если они есть в числе:
- если число содержит сотни, добавить слово для сотен
- если число оканчивается на 11-20, добавить соотв. слово
- если число содержит десятки, добавить слово для них
И так далее. В конце из массива собрать строку.
>>986681
Обратимся к мануалу: http://php.net/manual/ru/regexp.reference.escape.php
> \s
> любой пробельный символ
> Следующие символы считаются как "пробельные": HT (9), LF (10), FF (12), CR (13), и пробел (32). Тем не менее, если идет локале-зависимый поиск, и произойдет совпадение с символами в диапазоне 128-255, они также будут восприняты как пробельные, например NBSP (A0).
К "пробельным" относятся символы пробела, перевод строки \n, табуляция \t (она добавляет отступ), и более экзотичные спецсимволы \r (используется вместе с \n под Windows) и \f.
Также, при отстутсвии флага u к ним могут добавиться другие пробельные символы вроде символа с кодом 160 (неразрывный пробел), если он есть в кодировке, которая выбрана в текущей локали. Но это нас не должно касаться, так как мы используем юникод, а не однобайтовые кодировки.
А что происходит в юникодном режиме? Обратимся к документации по библиотеке pcre, которую используют preg-функции: http://www.pcre.org/original/doc/html/pcrepattern.html (англ) и ищем там выражение \s
> ....
> If PCRE is compiled with Unicode property support, and the PCRE_UCP option is set, the behaviour is changed so that Unicode properties are used to determine character types, as follows:
> \s any character that matches \p{Z} or \h or \v
Что такое "\p{Z}"? Это описано тут http://php.net/manual/en/regexp.reference.unicode.php и тут https://en.wikipedia.org/wiki/Unicode_character_property . В Юникоде у каждого символа есть категория: является ли он буквой, цифрой, разделителем или чем-то еще. \p{Z} - это символы из категории "разделители", они перечислены например тут:
- http://www.fileformat.info/info/unicode/category/Zl/list.htm
- http://www.fileformat.info/info/unicode/category/Zp/list.htm
- http://www.fileformat.info/info/unicode/category/Zs/list.htm
Также, про юникодные пробелы есть статья на англ: https://www.cs.tut.fi/~jkorpela/chars/spaces.html
Далее, посмотрим что такое \h и \v для pcre в ее мануале:
> The sequences \h, \H, \v, and \V are features that were added to Perl at release 5.10. In contrast to the other sequences, which match only ASCII characters by default, these always match certain high-valued code points, whether or not PCRE_UCP is set. The horizontal space characters are:
И далее там перечислены конкретные символы.
В общем, в юникодном режиме \s соответствует "старым" ASCII-символам вроде пробела, \n, \t, неразрывному пробелу + множеству юникодных пробелов и разделителей строк и абзацев.
Если ты не очень понимаешь что такое кодировки, юникод, то советую мою статью про них: https://github.com/codedokode/pasta/blob/master/cs/strings.md
Также, вот статья про юникод и регулярки на англ: http://www.regular-expressions.info/unicode.html
Дело в том, что бекслеш используется как спецсимвол на 2 уровнях: в движке регулярок при разборе регулярного выражения и в синтаксисе PHP при разборе содержимого строки.
Например, когда ты пишешь "\\" в строку вставляется один бекслеш, что легко проверить с помощью echo:
echo "\\"; // выведет \
Это описано в мануале: http://php.net/manual/ru/language.types.string.php Потому, чтобы вставить в строку выражение \s, мы должны по правилам PHP записать \\s:
echo "\\s"; // выведет \s
Однако, \s не является в PHP особой последовательностью, потому мы можем написать просто \s:
echo "\s"; // выведет \s
Таким образом, \s можно записать как \s и как \\s. Но если ты хочешь написать регулярку для поиска бекслеша, то придется заморочиться. В регулярке мы хотим написать \\, но если мы напишем "\\" то это вставит в строку только один бекслеш. Потому мы вынуждены писать бекслеш 4 раза:
echo "\\\\"; // выведет \\
Либо использовать форму записи, которая не интерпретирует бекслеши:
echo <<<'EOF'
\\
EOF;
// выведет \\
>>986210
> ['question1' => 'Какая планета
> ['question2' => 'Столица Англии?',
Тут нет смысла использовать разные ключи, так как они находятся в разных массивах.
> $q1->text = $array['question1']['question1'];
> $q2->text = $array['question2']['question2'];
Это унылая копипаста. Ты бы мог использовать цикл, проходясь по массиву вопросов и создавая для каждого вопроса свой объект. Либо обойтись без массива вопросов и записывать значения прямо в объект.
>>986176
Это плохая идея, так как у тебя форма и для группировки элементов надо поместить из внутрь form. Чтобы форма не отправлялось, надо отменять действие по умолчанию для события submit (preventDefault).
> событие поставил при клике на кнопку
Это неправильно так как обычную форму можно отправить и нажатием Enter (и нажатием зеленой кнопки на виртуальной клавиатуре в Андроиде например). Ты вместо того, чтобы разобраться в событиях, испортил код и сделал форму менее удобной в использовании.
Дело в том, что бекслеш используется как спецсимвол на 2 уровнях: в движке регулярок при разборе регулярного выражения и в синтаксисе PHP при разборе содержимого строки.
Например, когда ты пишешь "\\" в строку вставляется один бекслеш, что легко проверить с помощью echo:
echo "\\"; // выведет \
Это описано в мануале: http://php.net/manual/ru/language.types.string.php Потому, чтобы вставить в строку выражение \s, мы должны по правилам PHP записать \\s:
echo "\\s"; // выведет \s
Однако, \s не является в PHP особой последовательностью, потому мы можем написать просто \s:
echo "\s"; // выведет \s
Таким образом, \s можно записать как \s и как \\s. Но если ты хочешь написать регулярку для поиска бекслеша, то придется заморочиться. В регулярке мы хотим написать \\, но если мы напишем "\\" то это вставит в строку только один бекслеш. Потому мы вынуждены писать бекслеш 4 раза:
echo "\\\\"; // выведет \\
Либо использовать форму записи, которая не интерпретирует бекслеши:
echo <<<'EOF'
\\
EOF;
// выведет \\
>>986210
> ['question1' => 'Какая планета
> ['question2' => 'Столица Англии?',
Тут нет смысла использовать разные ключи, так как они находятся в разных массивах.
> $q1->text = $array['question1']['question1'];
> $q2->text = $array['question2']['question2'];
Это унылая копипаста. Ты бы мог использовать цикл, проходясь по массиву вопросов и создавая для каждого вопроса свой объект. Либо обойтись без массива вопросов и записывать значения прямо в объект.
>>986176
Это плохая идея, так как у тебя форма и для группировки элементов надо поместить из внутрь form. Чтобы форма не отправлялось, надо отменять действие по умолчанию для события submit (preventDefault).
> событие поставил при клике на кнопку
Это неправильно так как обычную форму можно отправить и нажатием Enter (и нажатием зеленой кнопки на виртуальной клавиатуре в Андроиде например). Ты вместо того, чтобы разобраться в событиях, испортил код и сделал форму менее удобной в использовании.
Потому что в репозитории должен быть твой код. Зачем дублировать по всему интернету устаревшие версии библиотек? Идея композера в том, что автор программы просто описывает, какие библиотеки ему нужны, в файлике, а композер сам их скачает и поставит.
>>985775
http://php.net/manual/en/arrayiterator.offsetunset.php
Эта функция не документирована, я бы советовал ее не использовать пока. Потому что понять, как она работает, можно только изучив исходный код PHP, а мне лень это делать. Используй array_walk_recursive пока что.
Ну и кстати элемент там полезный, он содержит картинку в формате JPEG судя по всему. Можно было бы использовать ее как превьюшку.
> , что создает проблемы в базе данных когда я добавляю его в json столбец
Тут стоило бы разобраться, почему. Может у тебя ошибка в коде. Вроде судя по документации в JSON можно засунуть до 4 Гб данных.
>>985569
Использование плейсхолдеров защищает от SQL-инъекций (и от взлома базы), но не защитит от того, что пользователь вставит "Войну и Мир" в поле "имя" или введет телефон в поле email. Ты должен задать ограничения и проверять их, если не хочешь чтобы базу забили мусором.
> при помощи substr
substr не работает с кириллицей, советую использовать mb_substr.
>>985567
нужно отдавать с сервера JSON, например:
{"success": true, "id": 123456}
{"success": false, "errors": ["Пожалуйста, укажите имя пользователя"]}
> Главный вопрос, это слишком криво? так делать нельзя?
Конечно, криво.
Потому что в репозитории должен быть твой код. Зачем дублировать по всему интернету устаревшие версии библиотек? Идея композера в том, что автор программы просто описывает, какие библиотеки ему нужны, в файлике, а композер сам их скачает и поставит.
>>985775
http://php.net/manual/en/arrayiterator.offsetunset.php
Эта функция не документирована, я бы советовал ее не использовать пока. Потому что понять, как она работает, можно только изучив исходный код PHP, а мне лень это делать. Используй array_walk_recursive пока что.
Ну и кстати элемент там полезный, он содержит картинку в формате JPEG судя по всему. Можно было бы использовать ее как превьюшку.
> , что создает проблемы в базе данных когда я добавляю его в json столбец
Тут стоило бы разобраться, почему. Может у тебя ошибка в коде. Вроде судя по документации в JSON можно засунуть до 4 Гб данных.
>>985569
Использование плейсхолдеров защищает от SQL-инъекций (и от взлома базы), но не защитит от того, что пользователь вставит "Войну и Мир" в поле "имя" или введет телефон в поле email. Ты должен задать ограничения и проверять их, если не хочешь чтобы базу забили мусором.
> при помощи substr
substr не работает с кириллицей, советую использовать mb_substr.
>>985567
нужно отдавать с сервера JSON, например:
{"success": true, "id": 123456}
{"success": false, "errors": ["Пожалуйста, укажите имя пользователя"]}
> Главный вопрос, это слишком криво? так делать нельзя?
Конечно, криво.
> Если получаю id, то пишу (int)id, в аякс всёравно приходит строка.
Потому что в HTTP-ответе тело всегда содержит строку. Тип там не передается (точнее, есть Content-Type, но это немного другое).
>>985545
Вся кастомизация в вордпрессе по моему сводится к написанию тем или плагинов. Достаточно прочитать мануал вордпресса по этим 2 темам. Сложные вещи придется делать по сути целиком самому с нуля и пристраивать сбоку, так как вордпресс это блоговый движок, а не фреймворк для создания сложных сайтов.
>>985359
На ideone при обновлении PHP забыли включить модуль mbstring, и mb-функции не работают.
>>985354
Глянь для начала эти уроки, которые имеют косвенное отношение к теме:
https://github.com/codedokode/pasta/blob/master/js/minesweeper-mvc.md
https://github.com/codedokode/pasta/blob/master/js/spa.md
А так, на jQuery наверно будет проще.
>>985312
С помощью плейсхолдеров можно подставлять только значения, но не имена полей или таблиц. Твоц код формирует запрос вида
ORDER BY 'red'
вместо
ORDER BY red
Имена полей надо тщательно проверять и подставлять напрямую.
>>985165
Ну так у нас есть класс Question, а создание объектов мы решили пока сделать функцией, это урок для начинающих. А так, можно конечно сделать какой-нибудь QuestionLoader или QuestionService который создает вопросы.
> Если получаю id, то пишу (int)id, в аякс всёравно приходит строка.
Потому что в HTTP-ответе тело всегда содержит строку. Тип там не передается (точнее, есть Content-Type, но это немного другое).
>>985545
Вся кастомизация в вордпрессе по моему сводится к написанию тем или плагинов. Достаточно прочитать мануал вордпресса по этим 2 темам. Сложные вещи придется делать по сути целиком самому с нуля и пристраивать сбоку, так как вордпресс это блоговый движок, а не фреймворк для создания сложных сайтов.
>>985359
На ideone при обновлении PHP забыли включить модуль mbstring, и mb-функции не работают.
>>985354
Глянь для начала эти уроки, которые имеют косвенное отношение к теме:
https://github.com/codedokode/pasta/blob/master/js/minesweeper-mvc.md
https://github.com/codedokode/pasta/blob/master/js/spa.md
А так, на jQuery наверно будет проще.
>>985312
С помощью плейсхолдеров можно подставлять только значения, но не имена полей или таблиц. Твоц код формирует запрос вида
ORDER BY 'red'
вместо
ORDER BY red
Имена полей надо тщательно проверять и подставлять напрямую.
>>985165
Ну так у нас есть класс Question, а создание объектов мы решили пока сделать функцией, это урок для начинающих. А так, можно конечно сделать какой-нибудь QuestionLoader или QuestionService который создает вопросы.
Заглядывает
>>984954
Добавь еще кириллический адрес ivPxJanANUSпримерkP|PUNCTUMр N)ф или ива!L>нANUSпр;KSимерPUNCTUMрT$|ф
>>984949
Использовать preventDefault
>>984920
Я бы сделал просто скриптом из 10 строк. А так, можно сделать класс FizzBuzzGenerator с статическим методом getFizzBuzzValues(....), куда бы передавал аргументы (не в конструктор). Либо можно сделать этот метод генератором, чтобы не хранить в памяти массив.
>>984823
По поводу архивов, 25 тред есть только с архивача. Видимо, была какая-то проблема с сервером или вайп, и тред потерялся. Вот ссылки:
- http://www.mediafire.com/file/r8vs6odv6bfe37l/threads-pr-25-arhivach.zip
- http://www.mediafire.com/file/16zwvu74mzo7yhh/threads-archive-pr-40-59.zip
- http://www.mediafire.com/file/kpot4mx3tbd4zad/threads-archive-pr-18-24-and-26-39.zip
Вообще, сфинкс и mysql работает по сети, так что ты бы мог разместить их на разных машинах, но смысла особого нет, так как надо настраивать ограничение доступа, проще поместить на одной машине.
> Есть какое-нибудь решение чтобы объединить два сервера и/или хостинга в один? Или обычно просто указывают абсолютный адрес изображения в шаблоне?
Вот там ниже кто-то советовал сетевую файловую систему, но я считаю такое решение "костылем". Его используют, когда нет ресурсов на то, чтобы переделать приложение, и подключают сетевую ФС, чтобы для приложения это выглядело как будто все файлы лежат локально. Но это работает не очень эффективно.
Сетевая ФС - это штука, которая как бы "монтирует" папку с удаленной системы в локальную файловую систему. В реальности при обращении к файлу идет запрос по сети на другой сервер. Это например существующая давно под линуксом NFS, Samba для Windows.
Тебе лучше генерировать абсолютные URL и сделать настройку домена в конфиге. Также, тебе может понадобиться решение для автоматической загрузки файлов на хостинг, тут можно подумать над использованием ssh/sftp, на худой конец FTP (он не защищен и пароль передается открытым текстом, не рекомендую) или той самой сетевой ФС (только хостинг вряд ли тебе даст ее подключить в отличие от ssh или FTP).
Вообще, для больших проектов (вроде соцсетей) обычно делают так: выделяют N серверов, на них ставят nginx для раздачи файлов + мини-приложение через которое по внутреннему API (а иногда и снаружи, например, через HTML форму) можно закачивать файлы и управлять ими. Если интересно, https://www.insight-it.ru/highload/2010/arkhitektura-facebook/#khranenie-fotografii
(вообще тут интересные статьи по highload-проектам: https://www.insight-it.ru/highload/ )
И соответственно где-то в базе хранят, на каком сервере (серверах) доступен файл. Чтобы сгенерировать нужную ссылку.
Есть еще сторонние хранилища вроде
- http://docs.aws.amazon.com/gettingstarted/latest/awsgsg-intro/gsg-aws-storage-cdn.html
- https://selectel.ru/services/cloud/storage/
Это по сути и есть те сервера с нгинксом и API для управления файлами. Насчет цен, конечно, не знаю насколько они выгодны.
> Как преобразовать $_GET запрос отправляемой формы из /search.php?q=... в /search/... ? Нужно разбирать ссылку в контроллере и делать ридерект?
Можно, но не очень понимаю смысл этого редиректа. Что мешает отдать данные сразу?
> Хотелось бы иметь собственное доменное имя.
Доменная система иерархическая. Есть корневые сервера (a.root-servers.net и так далее). Они хранят базу данных для TLD (и являются авторитетными серверами для нее), то есть они могут сказать, какой сервер является авторитетным для зоны .com, какой для зоны .ru. Эта база данных управляется ICANN.
Авторитетный сервер - это сервер, который смотрит ответ на запрос в соотв-й базе данных. Сторонние DNS-сервера вроде 8.8.8.8 - не авторитетные, так как у них нет доступа к базе доменов, они запрашивают данные у авторитетных серверов.
Каждой зоной управляет свой администратор, назначеныый ICANN, он ведет базу доменов 2 уровня в этой зоне, и его авторитетный сервер может дать адрес сервера, отвечающего за тот или иной домен.
Например доменом .ru управляет https://en.wikipedia.org/wiki/Coordination_Center_for_TLD_RU
Часто администратор не продает домены напрямую пользователям, а использует для этого посредников - сторонних регистраторов, которым дает доступ к своему API.
Соответственно при покупке домена ты добавляешь информацию о нем в соответствующий реестр, это название домена, 2 или больше NS (name server) для него, и whois-информация. И соответственно DNS-запросы к твоему домену example.com будут идти на твой сервер. А он уже будет отдавать IP-адрес для домена и другие данные.
Поскольку поддержка своего DNS-сервер требует определеных усилий, многие регистраторы позволяют при покупке домена использовать их DNS-сервер. Также, есть бесплатные DNS-сервера, например у Яндекса: https://yandex.ru/support/pdd/domain/dns.xml Но используя свой сервер, ты можешь реализовать больше возможностей, например раздавать разные Ip-адреса в зависимости от расположения пользователя, управлять временем кеширования данных и тд.
Если у тебя есть под рукой линукс, ты можешь увидеть как именно происходит разрешение запроса. Обычно приложения просто отправляют запрос на не-авторитетный DNS-сервер вроде 8.8.8.8 или сервер местного провайдера, а тот уже идет по цепочке авторитетных серверов, кеширует их ответы и тд. Но мы попробуем разрешить адрес узла вручную, используя только авторитетные сервера.
Допустим мы хотим узнать информацию о домене weather.yandex.ru. Для начала мы должны узнать названия корневых серверов. Они есть на сайте ICANN: https://www.internic.net/zones/named.cache
Далее, мы отправим запрос на корневой сервер A.ROOT-SERVERS.NET, чтобы узнать кто является авторитетным сервером для зоны .ru:
robot@debian:/tmp$ host -a -r ru a.root-servers.net
Trying "ru"
Using domain server:
Name: a.root-servers.net
Address: 198.41.0.4#53
Aliases:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 30041
;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 5, ADDITIONAL: 10
;; QUESTION SECTION:
;ru. IN ANY
;; AUTHORITY SECTION:
ru. 172800 IN NS a.dns.ripn.net.
ru. 172800 IN NS b.dns.ripn.net.
ru. 172800 IN NS d.dns.ripn.net.
ru. 172800 IN NS e.dns.ripn.net.
ru. 172800 IN NS f.dns.ripn.net.
;; ADDITIONAL SECTION:
a.dns.ripn.net. 172800 IN A 193.232.128.6
b.dns.ripn.net. 172800 IN A 194.85.252.62
d.dns.ripn.net. 172800 IN A 194.190.124.17
e.dns.ripn.net. 172800 IN A 193.232.142.17
f.dns.ripn.net. 172800 IN A 193.232.156.17
a.dns.ripn.net. 172800 IN AAAA 2001:678:17:0:193:232:128:6
b.dns.ripn.net. 172800 IN AAAA 2001:678:16:0:194:85:252:62
d.dns.ripn.net. 172800 IN AAAA 2001:678:18:0:194:190:124:17
e.dns.ripn.net. 172800 IN AAAA 2001:678:15:0:193:232:142:17
f.dns.ripn.net. 172800 IN AAAA 2001:678:14:0:193:232:156:17
Число 172800 - это время в секундах, на которое можно закешироввать ответ.
Если мы попробуем у корневого сервера запросить например IP-адрес для yandex.ru, то он даст тот же ответ, то есть имена серверов, отвечающих за зону .ru, и предложит нам обратиться к ним.
Далее, узнаем кто является авторитетным сервером для yandex.ru:
robot@debian:/tmp$ host -a -r yandex.ru a.dns.ripn.net
Trying "yandex.ru"
Using domain server:
Name: a.dns.ripn.net
Address: 193.232.128.6#53
Aliases:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 52434
;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 2, ADDITIONAL: 4
;; QUESTION SECTION:
;yandex.ru. IN ANY
;; AUTHORITY SECTION:
YANDEX.RU. 345600 IN NS ns2.yandex.RU.
YANDEX.RU. 345600 IN NS ns1.yandex.RU.
;; ADDITIONAL SECTION:
ns1.YANDEX.RU. 345600 IN A 213.180.193.1
ns2.YANDEX.RU. 345600 IN A 93.158.134.1
ns1.YANDEX.RU. 345600 IN AAAA 2a02:6b8::1
ns2.YANDEX.RU. 345600 IN AAAA 2a02:6b8:0:1::1
Сделаем запрос к серверу Яндекса:
robot@debian:/tmp$ host -a -r weather.yandex.ru ns1.yandex.ru
....
;; AUTHORITY SECTION:
weather.yandex.ru. 3600 IN NS ns4.yandex.ru.
weather.yandex.ru. 3600 IN NS ns3.yandex.ru.
Нам опять предлагают спросить у других серверов. Обратимся к ним:
robot@debian:/tmp$ host -a -r weather.yandex.ru ns3.yandex.ru
Trying "weather.yandex.ru"
Using domain server:
Name: ns3.yandex.ru
Address: 87.250.250.1#53
Aliases:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 17848
;; flags: qr aa; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;weather.yandex.ru. IN ANY
;; ANSWER SECTION:
weather.yandex.ru. 172800 IN NS ns3.yandex.ru.
weather.yandex.ru. 172800 IN NS ns4.yandex.ru.
weather.yandex.ru. 600 IN A 213.180.193.248
weather.yandex.ru. 3600 IN MX 0 mx.yandex.ru.
weather.yandex.ru. 600 IN AAAA 2a02:6b8::1:248
weather.yandex.ru. 600 IN SOA ns3.yandex.ru. sysadmin.yandex.ru. 2015050
822 900 600 3600000 300
Теперь ответ получен - IP-адрес для weather.yandex.ru - это 213.180.193.248
Заметь, что система использует дублирование - для каждой зоны есть минимум 2 авторитетных сервера.
Неавторитетные DNS-сервера провайдеров обычно сами делают рекурсивные запросы и кешируют ответы, чтобы снизить нагрузку на авторитетные серверы. Если мы отправим запрос к 8.8.8.8, то он даст ответ сразу:
robot@debian:/tmp$ host -a weather.yandex.ru 8.8.8.8
....
weather.yandex.ru. 599 IN A 213.180.193.248
Конечные пользователи, как правило, пользуются такими неавторитетными серверами.
Заглядывает
>>984954
Добавь еще кириллический адрес ivPxJanANUSпримерkP|PUNCTUMр N)ф или ива!L>нANUSпр;KSимерPUNCTUMрT$|ф
>>984949
Использовать preventDefault
>>984920
Я бы сделал просто скриптом из 10 строк. А так, можно сделать класс FizzBuzzGenerator с статическим методом getFizzBuzzValues(....), куда бы передавал аргументы (не в конструктор). Либо можно сделать этот метод генератором, чтобы не хранить в памяти массив.
>>984823
По поводу архивов, 25 тред есть только с архивача. Видимо, была какая-то проблема с сервером или вайп, и тред потерялся. Вот ссылки:
- http://www.mediafire.com/file/r8vs6odv6bfe37l/threads-pr-25-arhivach.zip
- http://www.mediafire.com/file/16zwvu74mzo7yhh/threads-archive-pr-40-59.zip
- http://www.mediafire.com/file/kpot4mx3tbd4zad/threads-archive-pr-18-24-and-26-39.zip
Вообще, сфинкс и mysql работает по сети, так что ты бы мог разместить их на разных машинах, но смысла особого нет, так как надо настраивать ограничение доступа, проще поместить на одной машине.
> Есть какое-нибудь решение чтобы объединить два сервера и/или хостинга в один? Или обычно просто указывают абсолютный адрес изображения в шаблоне?
Вот там ниже кто-то советовал сетевую файловую систему, но я считаю такое решение "костылем". Его используют, когда нет ресурсов на то, чтобы переделать приложение, и подключают сетевую ФС, чтобы для приложения это выглядело как будто все файлы лежат локально. Но это работает не очень эффективно.
Сетевая ФС - это штука, которая как бы "монтирует" папку с удаленной системы в локальную файловую систему. В реальности при обращении к файлу идет запрос по сети на другой сервер. Это например существующая давно под линуксом NFS, Samba для Windows.
Тебе лучше генерировать абсолютные URL и сделать настройку домена в конфиге. Также, тебе может понадобиться решение для автоматической загрузки файлов на хостинг, тут можно подумать над использованием ssh/sftp, на худой конец FTP (он не защищен и пароль передается открытым текстом, не рекомендую) или той самой сетевой ФС (только хостинг вряд ли тебе даст ее подключить в отличие от ssh или FTP).
Вообще, для больших проектов (вроде соцсетей) обычно делают так: выделяют N серверов, на них ставят nginx для раздачи файлов + мини-приложение через которое по внутреннему API (а иногда и снаружи, например, через HTML форму) можно закачивать файлы и управлять ими. Если интересно, https://www.insight-it.ru/highload/2010/arkhitektura-facebook/#khranenie-fotografii
(вообще тут интересные статьи по highload-проектам: https://www.insight-it.ru/highload/ )
И соответственно где-то в базе хранят, на каком сервере (серверах) доступен файл. Чтобы сгенерировать нужную ссылку.
Есть еще сторонние хранилища вроде
- http://docs.aws.amazon.com/gettingstarted/latest/awsgsg-intro/gsg-aws-storage-cdn.html
- https://selectel.ru/services/cloud/storage/
Это по сути и есть те сервера с нгинксом и API для управления файлами. Насчет цен, конечно, не знаю насколько они выгодны.
> Как преобразовать $_GET запрос отправляемой формы из /search.php?q=... в /search/... ? Нужно разбирать ссылку в контроллере и делать ридерект?
Можно, но не очень понимаю смысл этого редиректа. Что мешает отдать данные сразу?
> Хотелось бы иметь собственное доменное имя.
Доменная система иерархическая. Есть корневые сервера (a.root-servers.net и так далее). Они хранят базу данных для TLD (и являются авторитетными серверами для нее), то есть они могут сказать, какой сервер является авторитетным для зоны .com, какой для зоны .ru. Эта база данных управляется ICANN.
Авторитетный сервер - это сервер, который смотрит ответ на запрос в соотв-й базе данных. Сторонние DNS-сервера вроде 8.8.8.8 - не авторитетные, так как у них нет доступа к базе доменов, они запрашивают данные у авторитетных серверов.
Каждой зоной управляет свой администратор, назначеныый ICANN, он ведет базу доменов 2 уровня в этой зоне, и его авторитетный сервер может дать адрес сервера, отвечающего за тот или иной домен.
Например доменом .ru управляет https://en.wikipedia.org/wiki/Coordination_Center_for_TLD_RU
Часто администратор не продает домены напрямую пользователям, а использует для этого посредников - сторонних регистраторов, которым дает доступ к своему API.
Соответственно при покупке домена ты добавляешь информацию о нем в соответствующий реестр, это название домена, 2 или больше NS (name server) для него, и whois-информация. И соответственно DNS-запросы к твоему домену example.com будут идти на твой сервер. А он уже будет отдавать IP-адрес для домена и другие данные.
Поскольку поддержка своего DNS-сервер требует определеных усилий, многие регистраторы позволяют при покупке домена использовать их DNS-сервер. Также, есть бесплатные DNS-сервера, например у Яндекса: https://yandex.ru/support/pdd/domain/dns.xml Но используя свой сервер, ты можешь реализовать больше возможностей, например раздавать разные Ip-адреса в зависимости от расположения пользователя, управлять временем кеширования данных и тд.
Если у тебя есть под рукой линукс, ты можешь увидеть как именно происходит разрешение запроса. Обычно приложения просто отправляют запрос на не-авторитетный DNS-сервер вроде 8.8.8.8 или сервер местного провайдера, а тот уже идет по цепочке авторитетных серверов, кеширует их ответы и тд. Но мы попробуем разрешить адрес узла вручную, используя только авторитетные сервера.
Допустим мы хотим узнать информацию о домене weather.yandex.ru. Для начала мы должны узнать названия корневых серверов. Они есть на сайте ICANN: https://www.internic.net/zones/named.cache
Далее, мы отправим запрос на корневой сервер A.ROOT-SERVERS.NET, чтобы узнать кто является авторитетным сервером для зоны .ru:
robot@debian:/tmp$ host -a -r ru a.root-servers.net
Trying "ru"
Using domain server:
Name: a.root-servers.net
Address: 198.41.0.4#53
Aliases:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 30041
;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 5, ADDITIONAL: 10
;; QUESTION SECTION:
;ru. IN ANY
;; AUTHORITY SECTION:
ru. 172800 IN NS a.dns.ripn.net.
ru. 172800 IN NS b.dns.ripn.net.
ru. 172800 IN NS d.dns.ripn.net.
ru. 172800 IN NS e.dns.ripn.net.
ru. 172800 IN NS f.dns.ripn.net.
;; ADDITIONAL SECTION:
a.dns.ripn.net. 172800 IN A 193.232.128.6
b.dns.ripn.net. 172800 IN A 194.85.252.62
d.dns.ripn.net. 172800 IN A 194.190.124.17
e.dns.ripn.net. 172800 IN A 193.232.142.17
f.dns.ripn.net. 172800 IN A 193.232.156.17
a.dns.ripn.net. 172800 IN AAAA 2001:678:17:0:193:232:128:6
b.dns.ripn.net. 172800 IN AAAA 2001:678:16:0:194:85:252:62
d.dns.ripn.net. 172800 IN AAAA 2001:678:18:0:194:190:124:17
e.dns.ripn.net. 172800 IN AAAA 2001:678:15:0:193:232:142:17
f.dns.ripn.net. 172800 IN AAAA 2001:678:14:0:193:232:156:17
Число 172800 - это время в секундах, на которое можно закешироввать ответ.
Если мы попробуем у корневого сервера запросить например IP-адрес для yandex.ru, то он даст тот же ответ, то есть имена серверов, отвечающих за зону .ru, и предложит нам обратиться к ним.
Далее, узнаем кто является авторитетным сервером для yandex.ru:
robot@debian:/tmp$ host -a -r yandex.ru a.dns.ripn.net
Trying "yandex.ru"
Using domain server:
Name: a.dns.ripn.net
Address: 193.232.128.6#53
Aliases:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 52434
;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 2, ADDITIONAL: 4
;; QUESTION SECTION:
;yandex.ru. IN ANY
;; AUTHORITY SECTION:
YANDEX.RU. 345600 IN NS ns2.yandex.RU.
YANDEX.RU. 345600 IN NS ns1.yandex.RU.
;; ADDITIONAL SECTION:
ns1.YANDEX.RU. 345600 IN A 213.180.193.1
ns2.YANDEX.RU. 345600 IN A 93.158.134.1
ns1.YANDEX.RU. 345600 IN AAAA 2a02:6b8::1
ns2.YANDEX.RU. 345600 IN AAAA 2a02:6b8:0:1::1
Сделаем запрос к серверу Яндекса:
robot@debian:/tmp$ host -a -r weather.yandex.ru ns1.yandex.ru
....
;; AUTHORITY SECTION:
weather.yandex.ru. 3600 IN NS ns4.yandex.ru.
weather.yandex.ru. 3600 IN NS ns3.yandex.ru.
Нам опять предлагают спросить у других серверов. Обратимся к ним:
robot@debian:/tmp$ host -a -r weather.yandex.ru ns3.yandex.ru
Trying "weather.yandex.ru"
Using domain server:
Name: ns3.yandex.ru
Address: 87.250.250.1#53
Aliases:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 17848
;; flags: qr aa; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;weather.yandex.ru. IN ANY
;; ANSWER SECTION:
weather.yandex.ru. 172800 IN NS ns3.yandex.ru.
weather.yandex.ru. 172800 IN NS ns4.yandex.ru.
weather.yandex.ru. 600 IN A 213.180.193.248
weather.yandex.ru. 3600 IN MX 0 mx.yandex.ru.
weather.yandex.ru. 600 IN AAAA 2a02:6b8::1:248
weather.yandex.ru. 600 IN SOA ns3.yandex.ru. sysadmin.yandex.ru. 2015050
822 900 600 3600000 300
Теперь ответ получен - IP-адрес для weather.yandex.ru - это 213.180.193.248
Заметь, что система использует дублирование - для каждой зоны есть минимум 2 авторитетных сервера.
Неавторитетные DNS-сервера провайдеров обычно сами делают рекурсивные запросы и кешируют ответы, чтобы снизить нагрузку на авторитетные серверы. Если мы отправим запрос к 8.8.8.8, то он даст ответ сразу:
robot@debian:/tmp$ host -a weather.yandex.ru 8.8.8.8
....
weather.yandex.ru. 599 IN A 213.180.193.248
Конечные пользователи, как правило, пользуются такими неавторитетными серверами.
> Цепь блоков состоит из узлов. Когда мы устанавливаем Bitcoin Core мы создаем новый узел?
Нет, когда ты устанавливаешь клиент Bitcoin, ты становишься узлом (node) сети Биткойн.
А цепь блоков (blockchain) состоит из блоков, каждый из которых хранит N транзакций. Транзакция - это запись о переводе средств с одного кошелька на другой, подписанная ключом исходного кошелька.
Новые блоки генерируют узлы сети, которые занимаются майнингом. Узел делает ресурсоемкий перебор чисел (майнинг), чтобы найти число, соответствующее определенным условиям. Как только он его нашел, он получает возможность добавить новый блок в блокчейн (найденное число позволяет подписать новый блок, без него твой блок никто не примет). Каждый блок содержит определенное число монет, и тот, кто его создал, распоряжается ими как хочет - он может перевести их себе или на любой кошелек. Также тот, кто создал блок, может добавить в него транзакции от других участников сети, обычно он за это берет плату с них (разница между деньгами на входе транзакции и на выходе и есть эта комиссия и она достается майнеру). Создав и подписав блок, он рассылает его другим узла сети, они проверяют блок, все транзакции в нем, если они валидные, то добавляют блок в свою копию блокчейна.
Таким образом, единственный источник средств - это новые блоки. Тот, кто создал блок, получает это возможность распорядиться определенным числом новых монет. Все транзакции записаны в блокчейне, и любой, имеющий его копию, может убедиться, что кошелек X имеет Y монет.
Майнинг и комиссии создают мотивацию для создания и поддержки узлов сети.
Тот, кто хочет перевести деньги со своего кошелька, формирует транзакцию, включает в нее выплату комиссии (размер комиссии задает владелец кошелька, комиссия определяется как разница между деньгами на входе и на выходе транзакции) и рассылает эту транзакцию майнерам для включения в новый блок. Майнеры сортируют пришедшие транзакции по убыванию комиссии и включают в блок самые прибыльные для них транзакции. Так производится регулировка комисси с помощью рыночных механизмов. Ты можешь ставить комиссию меньше, но ниже вероятность, что транзакцию включат в блокчейн.
У каждой транзакции есть N входов и M выходов. Как я понимаю, перевод 1 биткойна с кошелька A с 10 биткойнами на B выглядит как транзакция, на вход которой поступает A, на выходе 1 биткойн передается в B, 8.99 передаются назад в A и 0.01 станут щедрой комиссией тому, кто включит транзакцию в блок.
https://en.bitcoin.it/wiki/Transaction
https://en.bitcoin.it/wiki/Protocol_documentation#Transaction_Verification
Также, если ты прочитаешь, то увидишь что в транзакциии есть поле, содержающее скрипт на специальном языке для ее верификации.
Биткойн интересен не только в плане использования криптографии, но и тем, как выстроена система мотивации, вознаграждений.
https://en.bitcoin.it/wiki/Block_chain
Что касается объема блокчейна - есть вариант "тонкого клиента", когда ты используешь сервер, которму доверяешь, для проверки транзакций:
https://en.bitcoin.it/wiki/Scalability#Simplified_payment_verification
https://www.quora.com/Why-isnt-the-size-of-the-blockchain-a-serious-problem-for-Bitcoin
> В примерах приведенных в документации есть пример с командой sendtoaddress https://bitcoin.org/en/developer-examples#simple-spending . Там создается новый кошелек на который переводиться сумма, но не создается кошелек с которого это сумма переводиться.
Там по моему может быть только один кошелек и он задается в конфиге: https://github.com/bitcoin/bitcoin/issues/3113
Я не знаю, может ли у одного кошелька быть несколько адресов или нет.
Также, там написано:
> The sendtoaddress RPC automatically selects an unspent transaction output (UTXO) from which to spend the satoshis. In this case, it withdrew the satoshis from our only available UTXO, the coinbase transaction for block #1 which matured with the creation of block #101.
> Мне же не обязательно хранить закрытый ключ в БД, если я хочу чтобы у каждого пользователя был собственный кошелек? Ведь его можно получить в любой момент с помощью команды dumpprivkey.
Не уверен, может ли он управлять кошельками для разных пользователей.
> В примере с simple raw transaction ( https://bitcoin.org/en/developer-examples#simple-raw-transaction ) это делать не обязательно. Получается Bitcoin Core это всего лишь кошелек, который может работать только с его собственными адресами
Ты можешь только делать операции с кошельками, к которым у тебя есть приватный ключ. Так что скорее всего кошелек там один, но возможно, для него можно создавать много адресов.
Также, в примерах используется специальный режим regtest, вместо работы с настоящей сетью Биткойн: https://bitcoin.org/en/developer-examples#regtest-mode
Там данные хранятся в файлах:
> Regtest wallets and block chain state (chainstate) are saved in the regtest subdirectory of the Bitcoin Core configuration directory.
> Наверно, должен быть способ чтобы перенести закрытые и открытые ключи на другой носитель. Как они хранятся?
Надо смотреть документацию конкретной программы. Скорее всего в файле. Вот тут есть общая информация: https://bitcoin.org/en/developer-guide#wallets
> Цепь блоков состоит из узлов. Когда мы устанавливаем Bitcoin Core мы создаем новый узел?
Нет, когда ты устанавливаешь клиент Bitcoin, ты становишься узлом (node) сети Биткойн.
А цепь блоков (blockchain) состоит из блоков, каждый из которых хранит N транзакций. Транзакция - это запись о переводе средств с одного кошелька на другой, подписанная ключом исходного кошелька.
Новые блоки генерируют узлы сети, которые занимаются майнингом. Узел делает ресурсоемкий перебор чисел (майнинг), чтобы найти число, соответствующее определенным условиям. Как только он его нашел, он получает возможность добавить новый блок в блокчейн (найденное число позволяет подписать новый блок, без него твой блок никто не примет). Каждый блок содержит определенное число монет, и тот, кто его создал, распоряжается ими как хочет - он может перевести их себе или на любой кошелек. Также тот, кто создал блок, может добавить в него транзакции от других участников сети, обычно он за это берет плату с них (разница между деньгами на входе транзакции и на выходе и есть эта комиссия и она достается майнеру). Создав и подписав блок, он рассылает его другим узла сети, они проверяют блок, все транзакции в нем, если они валидные, то добавляют блок в свою копию блокчейна.
Таким образом, единственный источник средств - это новые блоки. Тот, кто создал блок, получает это возможность распорядиться определенным числом новых монет. Все транзакции записаны в блокчейне, и любой, имеющий его копию, может убедиться, что кошелек X имеет Y монет.
Майнинг и комиссии создают мотивацию для создания и поддержки узлов сети.
Тот, кто хочет перевести деньги со своего кошелька, формирует транзакцию, включает в нее выплату комиссии (размер комиссии задает владелец кошелька, комиссия определяется как разница между деньгами на входе и на выходе транзакции) и рассылает эту транзакцию майнерам для включения в новый блок. Майнеры сортируют пришедшие транзакции по убыванию комиссии и включают в блок самые прибыльные для них транзакции. Так производится регулировка комисси с помощью рыночных механизмов. Ты можешь ставить комиссию меньше, но ниже вероятность, что транзакцию включат в блокчейн.
У каждой транзакции есть N входов и M выходов. Как я понимаю, перевод 1 биткойна с кошелька A с 10 биткойнами на B выглядит как транзакция, на вход которой поступает A, на выходе 1 биткойн передается в B, 8.99 передаются назад в A и 0.01 станут щедрой комиссией тому, кто включит транзакцию в блок.
https://en.bitcoin.it/wiki/Transaction
https://en.bitcoin.it/wiki/Protocol_documentation#Transaction_Verification
Также, если ты прочитаешь, то увидишь что в транзакциии есть поле, содержающее скрипт на специальном языке для ее верификации.
Биткойн интересен не только в плане использования криптографии, но и тем, как выстроена система мотивации, вознаграждений.
https://en.bitcoin.it/wiki/Block_chain
Что касается объема блокчейна - есть вариант "тонкого клиента", когда ты используешь сервер, которму доверяешь, для проверки транзакций:
https://en.bitcoin.it/wiki/Scalability#Simplified_payment_verification
https://www.quora.com/Why-isnt-the-size-of-the-blockchain-a-serious-problem-for-Bitcoin
> В примерах приведенных в документации есть пример с командой sendtoaddress https://bitcoin.org/en/developer-examples#simple-spending . Там создается новый кошелек на который переводиться сумма, но не создается кошелек с которого это сумма переводиться.
Там по моему может быть только один кошелек и он задается в конфиге: https://github.com/bitcoin/bitcoin/issues/3113
Я не знаю, может ли у одного кошелька быть несколько адресов или нет.
Также, там написано:
> The sendtoaddress RPC automatically selects an unspent transaction output (UTXO) from which to spend the satoshis. In this case, it withdrew the satoshis from our only available UTXO, the coinbase transaction for block #1 which matured with the creation of block #101.
> Мне же не обязательно хранить закрытый ключ в БД, если я хочу чтобы у каждого пользователя был собственный кошелек? Ведь его можно получить в любой момент с помощью команды dumpprivkey.
Не уверен, может ли он управлять кошельками для разных пользователей.
> В примере с simple raw transaction ( https://bitcoin.org/en/developer-examples#simple-raw-transaction ) это делать не обязательно. Получается Bitcoin Core это всего лишь кошелек, который может работать только с его собственными адресами
Ты можешь только делать операции с кошельками, к которым у тебя есть приватный ключ. Так что скорее всего кошелек там один, но возможно, для него можно создавать много адресов.
Также, в примерах используется специальный режим regtest, вместо работы с настоящей сетью Биткойн: https://bitcoin.org/en/developer-examples#regtest-mode
Там данные хранятся в файлах:
> Regtest wallets and block chain state (chainstate) are saved in the regtest subdirectory of the Bitcoin Core configuration directory.
> Наверно, должен быть способ чтобы перенести закрытые и открытые ключи на другой носитель. Как они хранятся?
Надо смотреть документацию конкретной программы. Скорее всего в файле. Вот тут есть общая информация: https://bitcoin.org/en/developer-guide#wallets
Не понял вопрос. Там же форма? Значит значения ее элементов присылаются на сервер в запросе (GET/POST).
Продолжаю пилить поделку:
Сделал страницу с рандомной цитатой в возможностью их листать по одной
Сделал список цитат с якорями
Сделал предложку цитат
Шаблон не осилил, верстка поехала, не смог в CSS. Благо на MVC всего один файл надо поправить, чтоб на другой перекатится.
Дальше буду админку пилить.
Я знаю, что ОП найдет десяток пунктов по которым меня можно справедливо обоссать, поэтому разборов пока никаких не прошу, только по желанию.
То был не я.
сук, бля, ору
Пример кода покажи или задачи, что там надо.
SELECT FROM table WHERE x <> 1
Индекс не поможет. Не знаю, уместна ли такая аналогия: мы хотим найти в словаре все слова не X c помощью бинарного поиска. Открываем словарь по середине, допустим там слово Y, ок, но куда теперь двигаться дальше? Непонятно ведь какую часть словаря теперь открывать, нужен полный перебор.
SELECT FROM table WHERE x + y < 100
Индекс на x не будет использоваться. Это потому, что индекс построен для X, а мы запрашиваем X+Y? Затрудняюсь провести аналогию со словарём.
SELECT MAX(a) FROM table WHERE b = 2
Индекс на b поможет.
SELECT FROM table WHERE name LIKE '%Иван%'
Для такого запроса индекс по name не поможет, всё равно что искать в словаре слова с неизвестной первой буквой. Как понял, должен помочь FULLTEXT индекс и операторы AGAINST/MATCH
SELECT FROM table WHERE b = 1 AND a < 10
Это не понял, как и эту статью https://ruhighload.com/post/Работа+с+индексами+в+MySQL
Автор сначала создаёт индекс age_gender и пишет, что значения индекса будут такими:
12male
15female
29male
89tsar
И утверждает, что запрос SELECT * FROM users WHERE age <= 29 AND gender = 'male' не будет использовать полный индекс, т.к. "значения gender будут отличаться для разных значений колонки age.". Я понимаю, отбираем 12male, 15female, 29tsar и нужно пройтись по значениям, чтобы отобрать gender = 'male'
Но потом он добавляет индекс gender_age и пишет, что теперь запросы будет использовать полный индекс. Выходит такой индекс
male12
male29
female15
tsar89
male99 -- добавил я
По аналогии отбираем male12 и male29, male99. Выходит, что по ним теперь тоже нужно пройтись, чтобы отобрать те, где age <= 29?
SELECT FROM table WHERE x <> 1
Индекс не поможет. Не знаю, уместна ли такая аналогия: мы хотим найти в словаре все слова не X c помощью бинарного поиска. Открываем словарь по середине, допустим там слово Y, ок, но куда теперь двигаться дальше? Непонятно ведь какую часть словаря теперь открывать, нужен полный перебор.
SELECT FROM table WHERE x + y < 100
Индекс на x не будет использоваться. Это потому, что индекс построен для X, а мы запрашиваем X+Y? Затрудняюсь провести аналогию со словарём.
SELECT MAX(a) FROM table WHERE b = 2
Индекс на b поможет.
SELECT FROM table WHERE name LIKE '%Иван%'
Для такого запроса индекс по name не поможет, всё равно что искать в словаре слова с неизвестной первой буквой. Как понял, должен помочь FULLTEXT индекс и операторы AGAINST/MATCH
SELECT FROM table WHERE b = 1 AND a < 10
Это не понял, как и эту статью https://ruhighload.com/post/Работа+с+индексами+в+MySQL
Автор сначала создаёт индекс age_gender и пишет, что значения индекса будут такими:
12male
15female
29male
89tsar
И утверждает, что запрос SELECT * FROM users WHERE age <= 29 AND gender = 'male' не будет использовать полный индекс, т.к. "значения gender будут отличаться для разных значений колонки age.". Я понимаю, отбираем 12male, 15female, 29tsar и нужно пройтись по значениям, чтобы отобрать gender = 'male'
Но потом он добавляет индекс gender_age и пишет, что теперь запросы будет использовать полный индекс. Выходит такой индекс
male12
male29
female15
tsar89
male99 -- добавил я
По аналогии отбираем male12 и male29, male99. Выходит, что по ним теперь тоже нужно пройтись, чтобы отобрать те, где age <= 29?
>Тебе лучше генерировать абсолютные URL и сделать настройку домена в конфиге.
О какой настройке идёт речь? Можно же и так ссылаться на любой домен в html ссылке.
>> Как преобразовать $_GET запрос отправляемой формы из /search.php?q=... в /search/... ? Нужно разбирать ссылку в контроллере и делать ридерект?
>Можно, но не очень понимаю смысл этого редиректа. Что мешает отдать данные сразу?
Ничего, просто хотелось иметь красивую ссылку. В принципе, можно обойтись и без этого.
>Часто администратор не продает домены напрямую пользователям, а использует для этого посредников - сторонних регистраторов, которым дает доступ к своему API.
Значит не получиться обойтись без посредников. Это печально, потому что регистраторы с первой страницы гугла выглядят как очередные корпорации зла. Хотелось бы обойтись без них.
Есть такое понятие, как синтаксис, или грамматика. Это набор правил, которые заложены в интерпретатор PHP. Эти правила описывают, из каких частей состоит программа, из каких символов состоят отдельные части. Ну например, "переменная" описывается как последовательность из знака доллара и идущих за ним определенных символов (букв, цифр и тд). Или "целое число" - это последовательность из необязательного знака минус, и 1 или более цифр от 0 до 9. Из этих маленьких неделимых кусочков (они называются терминалы) составляются более сложные части. Например, "математическое выражение" - это последовательность, состоящая из переменных, чисел, знаков математических операций. Или "цикл for" - это конструкция из ключевого слова for, 3 выражений в скобках и тела цикла.
Ты наверно не поймешь его полностью, но вот ссылки на реальный код из интерпретатора PHP, который описывает грамматику языка PHP. Имено по этим правилам анализируется текст программы перед выполнением:
https://github.com/php/php-src/blob/master/Zend/zend_language_scanner.l
https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y
Это файлы содержат смесь кода на Си и языка Yacc, который позволяет описывать грамматики. Ну вот например кусочек из первого файла, описывающий синтаксис переменной:
https://github.com/php/php-src/blob/master/Zend/zend_language_scanner.l#L1870
> <ST_IN_SCRIPTING,ST_DOUBLE_QUOTES,ST_HEREDOC,ST_BACKQUOTE,ST_VAR_OFFSET>"$"{LABEL} ...
> RETURN_TOKEN(T_VARIABLE);
> ...
Это можно прочитать так:
- ST_IN_SCRIPTING - если мы находимся где-то в тексте программы
- ST_DOUBLE_QUOTES - или внутри строки с двойными кавычками
- ST_HEREDFOC - или внутри конструкции heredoc (гугли)
- ST_BACKQUOTE - или внутри строки с косыми кавычками
- ST_VAR_OFFSET - или внутри квадратных скобок
- "$"{LABEL} - и видим знак доллара, за которым идут символы, подходящие под правило LABEL
- RETURN_TOKEN(T_VARIABLE) - значит это обозначение переменной
Кстати, определение правила LABEL есть в том же файле:
https://github.com/php/php-src/blob/master/Zend/zend_language_scanner.l#L1115
> LABEL [a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*
Это регулярное выражение определяет, какие символы можно использовать в имени переменной.
Первый файл описывает терминалы - маленькие неделимые кусочки программы. Второй файл описывает более сложные конструкции, которые можно составлять из этих кусочков.
Вот например правило, которое описывает, из чего может состоять выражение (оно довольно большое, я скопирую лишь кусочек):
https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L872
> expr_without_variable:
> | variable '=' expr
> | expr '+' expr
> | expr '-' expr
То есть выражение может состоять из переменной, знака равно и другого выражения, или же из 2 выражений, разделенных знаком плюс или минус. Это я скопировал только часть, на самом деле там правило гораздо больше и сложнее.
Когда ты запускаешь свою программу, то PHP используя эти правила, анализирует текст программы и разбирает ее на составляющие. Программа разбивается на инструкции (команды), а каждая из них на более мелкие составные части. Ну например, строка
$x = $y + 1;
Разбивается примерно на такие части:
- команда, содержащая операцию присваивания значения переменной
- где переменная называется $x
- а значение, которое ей надо присвоить, это выражение:
- сумма 2 слагаемых
- первое - переменная $y
- второе - число 1
Что касается операции echo, про нее можно почитать в мануале: http://php.net/manual/ru/function.echo.php
Если ты дашь PHP программу, которая не соответствует правилам, то получишь ошибку "Syntax error in line N".
Ну то есть, если кратко ответить на твой вопрос, "почему именно так", потому что такие правила заложены в язык PHP его создателями.
Если тебя вдруг заинтересовала тема грамматик и синтаксического анализа, то гугл в помощь: https://www.google.ru/search?q=грамматика+синтаксический+анализ&newwindow=1&gbv=1&sei=L0gSWbWrOoPE6ASt6aCwDA
Есть такое понятие, как синтаксис, или грамматика. Это набор правил, которые заложены в интерпретатор PHP. Эти правила описывают, из каких частей состоит программа, из каких символов состоят отдельные части. Ну например, "переменная" описывается как последовательность из знака доллара и идущих за ним определенных символов (букв, цифр и тд). Или "целое число" - это последовательность из необязательного знака минус, и 1 или более цифр от 0 до 9. Из этих маленьких неделимых кусочков (они называются терминалы) составляются более сложные части. Например, "математическое выражение" - это последовательность, состоящая из переменных, чисел, знаков математических операций. Или "цикл for" - это конструкция из ключевого слова for, 3 выражений в скобках и тела цикла.
Ты наверно не поймешь его полностью, но вот ссылки на реальный код из интерпретатора PHP, который описывает грамматику языка PHP. Имено по этим правилам анализируется текст программы перед выполнением:
https://github.com/php/php-src/blob/master/Zend/zend_language_scanner.l
https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y
Это файлы содержат смесь кода на Си и языка Yacc, который позволяет описывать грамматики. Ну вот например кусочек из первого файла, описывающий синтаксис переменной:
https://github.com/php/php-src/blob/master/Zend/zend_language_scanner.l#L1870
> <ST_IN_SCRIPTING,ST_DOUBLE_QUOTES,ST_HEREDOC,ST_BACKQUOTE,ST_VAR_OFFSET>"$"{LABEL} ...
> RETURN_TOKEN(T_VARIABLE);
> ...
Это можно прочитать так:
- ST_IN_SCRIPTING - если мы находимся где-то в тексте программы
- ST_DOUBLE_QUOTES - или внутри строки с двойными кавычками
- ST_HEREDFOC - или внутри конструкции heredoc (гугли)
- ST_BACKQUOTE - или внутри строки с косыми кавычками
- ST_VAR_OFFSET - или внутри квадратных скобок
- "$"{LABEL} - и видим знак доллара, за которым идут символы, подходящие под правило LABEL
- RETURN_TOKEN(T_VARIABLE) - значит это обозначение переменной
Кстати, определение правила LABEL есть в том же файле:
https://github.com/php/php-src/blob/master/Zend/zend_language_scanner.l#L1115
> LABEL [a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*
Это регулярное выражение определяет, какие символы можно использовать в имени переменной.
Первый файл описывает терминалы - маленькие неделимые кусочки программы. Второй файл описывает более сложные конструкции, которые можно составлять из этих кусочков.
Вот например правило, которое описывает, из чего может состоять выражение (оно довольно большое, я скопирую лишь кусочек):
https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L872
> expr_without_variable:
> | variable '=' expr
> | expr '+' expr
> | expr '-' expr
То есть выражение может состоять из переменной, знака равно и другого выражения, или же из 2 выражений, разделенных знаком плюс или минус. Это я скопировал только часть, на самом деле там правило гораздо больше и сложнее.
Когда ты запускаешь свою программу, то PHP используя эти правила, анализирует текст программы и разбирает ее на составляющие. Программа разбивается на инструкции (команды), а каждая из них на более мелкие составные части. Ну например, строка
$x = $y + 1;
Разбивается примерно на такие части:
- команда, содержащая операцию присваивания значения переменной
- где переменная называется $x
- а значение, которое ей надо присвоить, это выражение:
- сумма 2 слагаемых
- первое - переменная $y
- второе - число 1
Что касается операции echo, про нее можно почитать в мануале: http://php.net/manual/ru/function.echo.php
Если ты дашь PHP программу, которая не соответствует правилам, то получишь ошибку "Syntax error in line N".
Ну то есть, если кратко ответить на твой вопрос, "почему именно так", потому что такие правила заложены в язык PHP его создателями.
Если тебя вдруг заинтересовала тема грамматик и синтаксического анализа, то гугл в помощь: https://www.google.ru/search?q=грамматика+синтаксический+анализ&newwindow=1&gbv=1&sei=L0gSWbWrOoPE6ASt6aCwDA
Ты, конечно, за словом в карман не лезешь, когда нубик всего лишь про эхо спрашивает.
Лол, страшно представить что будет, если о переменных спросить
Давай с последним шагом подробнее. Не понимаю, что значит дошли до конца цикла https://3v4l.org/SZo4b
>>988054
Конкретно для твоего случая это значит нормальное завершение цикла по счетчику, а не по брику. Как уж ты будешь понимать, что у тебя он нормально все проверил сам решай.
Не знаю чего оп не перекатывает раньше 1к постов, тут тухло всегда из-за этого.
Ну не делать же за тебя все.
>Что касается объема блокчейна - есть вариант "тонкого клиента", когда ты используешь сервер, которму доверяешь, для проверки транзакций:
У клиента есть ещё вариант с ограничением дискового пространства: https://bitcoin.org/en/full-node#configuration-tuning
А ты про Айфон вообще делал задачу? Какие-то непонятные вопросы задаешь для этого уровня.
Еще ты будешь меня гнать, с тебя не убудет мои мусорные посты отсеивать, хуй ленивый.
Я тут сижу и жду какой-нибудь энергичной движухи, которой не будет без переката, только унылая проверка нубских задачек. Ты думаешь тут одни обучающиеся сидят чтоли? Попиздеть за жизнь и разработку тоже хочется.
Собственно то, что делает пхп на беке сайта - это тоже программа. Не все то программа, во что можно потыкать мышкой. Да, ПО других типов на нем не принято писать от слова совсем (хоть и возможно).
Из актуальных направлений:
Ведро - java, kotlin, scala (и для ndk толи на крестах, толи на чем-то таком)
Яблоко - obj c, swift
Фронтенд сайтов - js и его диалекты.
А первый высокоуровневый язык вообще создан нацистами. Что-то тут не чисто.
Лучше вернись к ней, это стоит того.
Такие вещи надо понять однажды, чтобы потом не ошибаться во всём этом.
Дошли руки до админки, крудошлепствую. Приятно работать в парадигме MVC :3
Ты же видишь мой уровень, какая работа. Самому стыдно, что такой хуйней занимаюсь. Не знаю чего хочу, потерянный человек
Дворником бы работать и Хайдеггера с Шопенгауэром читать
26 лвл
Точнее не бывает.
Я просто сам так леплю объекты везде, всегда задумывался правильно ли, может стоит Dependency injection покурить, в тему ли это вообще
Зависит от логики. В конструкторе самое необходимое, если без ди, без чего жить нельзя. Все остальное по мере надобности. Либо сразу с ди делать.
Сиди и жди блядь ОПа, а я жду перекат.
>>988547
<!--
Ребята не стоит вскрывать этот код. Вы молодые, шутливые, вам все легко.
Это не то.
Это не Чикатило и даже не архивы спецслужб. Сюда лучше не лезть.
Серьезно, любой из вас будет жалеть. Лучше закройте код и забудьте что тут писалось.
Я вполне понимаю что данным сообщением вызову дополнительный интерес, но хочу сразу предостеречь пытливых - стоп.
Остальные просто не найдут...
-->
Если тебе нужно обновление стилей динамически, то юзай нужный софт, например Brackets, плагин для Atom.
В хроме можно дебажить свои стили, смотреть, что генерируется и редактировать.
Да нахуй реал тайм, это наоборот не убодно, не видишь изменений, я про F5, обновляется только хтмл-разметка, стили из памяти браузера подгружаются.
Во-первых, возможно. Но это тема для другой парадигмы разработки, тут обычно не обсуждается.
Во-вторых, все так живут и не парятся. Это нормальная ситуация. В особо критичных по этой теме местах перекрывается частичным реалтаймом (чаты например). В остальных ошибка - значит ошибка, это правильная реакция.
>Но это тема для другой парадигмы разработки, тут обычно не обсуждается.
Какой? Где обсуждается?
Это зависит от того, что ты разрабатываешь. Если ты пилишь сайтик с реалтаймом, что соотвествует тематике треда, то следует в сторону вебсокетов посмотреть как следует, либо на паб/саб сервисы (или свои реализации), и тут уже хорошенько так башкой подумтаь. Почему дургая парадигма? Потому что разработка в этом стиле (ивент драйвен) сильно отилчается от того, что мы обычно на сайтах видим (мвс, контроллеры эти и эндпоинты). Грубо говоря начнеш ьпилить так - тебе мало поможет опыт в стандартном мвс. По этой же причине и обсуждается редко.
Обсуждается, мб, в жс треде. Но это не точно, я там не сижу.
Ну, это я с потолка сказал.
В жс треде возможно обсуждают сокет.ио просто (кстати это пиздец блевотня, но пока что самая быстрая блевотня из аналогов, препэар йор ебало фор грабли, доки можешь даже не читать, там ни слова правды нет). На пхп тоже есть решения, ратчет например, просто они медленнее (но удобнее притом на порядок и сука прозрачнее), тут есть люди, которые с подобным работали. Паб/саб дрисня не зависит от языка, реализаций миллиард, но такой подход покрывает не все задачи хорошо, сокеты более гибкие в этом плане. А вообще ты зря вскрываешь эту тему. Если тебе прямо ойой реалтайм не нужен, а просто стандартный жизненный цикл веб-приложения требуется, и тебя запарило, что может где-то у кого-то запись пропадет, то это пустая причина для беспокойства, ибо является нормой, просто обрабатывай эти ситуации. Не спеши в это дерьмо лезть, еще успеешь потонуть.
При этом оно продолжается не правильно, а скрипт тупо падает на каком-нибудь вызове функции, типа попытка обратиться к null. И падает он независимо от того, что я нажму после точки останова (F7, F8, F9).
Кто-нибудь сталкивался с такой проблемой?
UPD. Нет, оно идёт не так, как будто я нажал Run, если там поставить трай кэтчи, поставить точку останова внутри трая, и после остановки на ней нажать шаг, то оно сразу выбрасывает на строчку ЗА кэтчем. И далее опять та же история.
UPD. Сменил версию PHP с 7 на 5.6 (использую OpenServer), тут работает. Но всё равно интересно, что случилось на седьмой такого.
https://github.com/enotocode/minesweeper.mvc
online test https://enotocode.github.io/minesweeper.mvc/
>>Можешь прочитать про системы модулей в JS: CommonJS и AMD. Затем - про сборщики и загрузчики модулей вроде WebPack.
>>Советую настроить сборщик так, чтобы в режиме разработки не требовалась бы сборка и файлы бы грузились напрямую (это упрощает и ускоряет отладку), а в режиме релиза собирался бы единый JS файл.
Поставил webpack.
Модули node и commonjs имеют одинаковый синтаксис? Есть ли экспорт по умолчанию в commonjs: module.export = MyClass или это только фишка node модулей?
Как я понял, webpack не умеет грузить напрямую, зато есть режим watch, который обновляет сборку в режиме реального времени, и несколько видов карты файлов.
>>В классе MinesweeperGame, возможно, лучше было бы сделать 2 словаря:
>>- cells[y][x] с объектами Cell с информацией о клеточке
>>- openedCells[y][x] с true/false, показывает, открыта ли клетка
>>- markedCells[y][x] true/false
>>Можно сделать даже один словарь, если сделать у ячейки свойства isOpened/isMarked, но тогда их можно случайно поменять, и MinesweeperGame об этом не узнает (и не сгенерирует событие). Но можно конечно договориться так не делать.
>>Или можно сделать Cell тоже источником событий, и подписываться на событие открытия, но это конечно немного усложнит жизнь.
>>А у тебя этого нет, у тебя одна и та же клеточка может быть представлена 2 разными объектами в minedCells и openCells, это, мне кажется, нехорошо. Ведь тогда, если мы хотим что-то у клеточки поменять, мы должны найти все экземпляры и поменять нужное свойство. Лучше делать, что 1 сущности соответствует ровно 1 экземпляр объекта.
Я сделал один словарь cells[y][x] с объектами Cell с информацией о клеточках. Договорился сам с собою, что свойство _cells и объекты Cell - это формат для хранения данных, доступ к которым(ому) имеет только класс MinesweeperGame, и никто снаружи не знает о их существовании. Словарь наполняется автоматически при создании игры, а класс может только изменять свойства внутри каждого Cell.
>>https://github.com/enotocode/minesweeper.mvc/blob/master/app/GameEvent.js
>>Здесь, ты может сам заметил, проблема в том, что у разных событий может быть разное число аргументов, с разными названиями. Получается, надо либо сделать разные классы событий, либо сделать один класс, а аргументы передавать словарем вроде { cell: someCell, action: SomeClass.ACTION_OPEN }
>>Использование нескольких классов требует больше кода, но позволяет ставить jsDoc, добавлять кастомные методы и свойства в события.
Добавил
- ButtonEvent // события кнопок View
- CellEvent // клетки по которым кликнули во View и клетки которые отрыли/отметили в MinesweeperGame
- StatusEvent // изменение статуса игры MinesweeperGame
>>Еще, наверно, стоило бы начать раскидывать файлы по папкам.
А как делить файлы по папкам, View/Controller/Other ?
>>https://github.com/enotocode/minesweeper.mvc/tree/master/app
>>Ну и насчет 2 независимых контроллеров (ModalController/BrowserViewController) - вот я не уверен, а не лучше ли сделать ModalController/ModalView подчиненными BrowserViewController, чтобы он им говорил, когда показать диалог, а не они сами решали?
>>А то просто у тебя получается что диалог сам решает, когда ему открываться, как-то иерархия управления размывается, это как 2 директора на одном предприятии.
Сделал так:
1. пара ModalView/ModalController создается в Controller,
2. Controller же следит за событиями модели, чтобы вызывать методы show()/hide() модального окна (но через ModalController)
3. ModalController имеет прямой доступ к модели, чтобы обрабатывать события ModalView.
4. ModalView ничего ни о ком не знает
Мне не нравится 2 пункт, т.к. Controller теперь связан еще с одним классом кроме View. И пункт 3 - если у контроллера модального окна есть доступ к модели, может быть пусть сам запускает show()/hide(), или убрать доступ, тогда Controller должен подписаться на события ModalController, или ModalController иметь доступ к методу Controller что увеличит их связанность?
>>BrowserViewController очень сильно привязан к BrowserView, оно в общем-то логично, но я поймал себя на мысли, что может быть, проще было его код во View и поместить?
Понять что происходит будет определенно проще. Но пока оставлю так.
>>ConsoleController.prototype.updateCellStatus = function(status, cell){
>>Проще наверно просто пересоздавать строку с нуля, а не мучаться с заменой отдельного символа. там все равно отрисовка этого поля потом больше времени займет.
Тогда мне нужно получать все ячейки из модели при каждой отрисовке. Т.к. я договорился что внутреннее хранилище с ячейкими не покинет модели, мне нужно сделать метод получения данных о всех ячейках, т.е. создать новый формат для передачи данных или клонировать массив со всеми классами внутри. А потом отрисовывать его?
И нужно будет перерисовывать поле каждый раз, при открытии каждой клетки, но за один ход могут открыться сразу несколько соседних, если рядом с ними нет мин. Сейчас так выглядит вывод поля в консоли браузера.
>>А так тебе приходится держать копию данных модели и синхронизировать ее постоянно. Сложно и есть риск что-то забыть.
В BrowserView тоже хранится копия данных в DOM и также происходит отрисовка, мы начинаем с поля где все ячейки не раскрыты, и при появлении события от модели открываем по одной ячейке. Хотя для добаления возможности отменить действие, вариант с полной отрисовкой надежнее. Осталось решить в каком виде получать данные о клетках из модели.
>>https://github.com/enotocode/minesweeper.mvc/tree/master/templates/css
>>Это надо поместить в public.
Public вообще пришлось убрать, чтобы не дублировать файлы, т.к. gitPages берет index.html из корневой папки проекта.
>>если за раз открывается несколько клеточек, в консоль вываливается куча изображений поля
Придумал пока два варианта как это сделать.
1. Сделать буфер для задания на отрисовку и задержку на его выполнение, каждое новое задание заменяет старое, и обновляет таймер задержки. Но как-то не надежно.
2. Можно добавить два статуса для метода модели openCell(), при запуске метода статус изменяется на OPENING, в самом конце выполнения статус на - WAITING. Функция входит в рекурсию до изменения статуса на WAITING, а в режиме рекурсии не меняет совсем. View должна иметь прямой доступ к модели или сделать этот статус свойством события открытия каждой клетки.
https://github.com/enotocode/minesweeper.mvc
online test https://enotocode.github.io/minesweeper.mvc/
>>Можешь прочитать про системы модулей в JS: CommonJS и AMD. Затем - про сборщики и загрузчики модулей вроде WebPack.
>>Советую настроить сборщик так, чтобы в режиме разработки не требовалась бы сборка и файлы бы грузились напрямую (это упрощает и ускоряет отладку), а в режиме релиза собирался бы единый JS файл.
Поставил webpack.
Модули node и commonjs имеют одинаковый синтаксис? Есть ли экспорт по умолчанию в commonjs: module.export = MyClass или это только фишка node модулей?
Как я понял, webpack не умеет грузить напрямую, зато есть режим watch, который обновляет сборку в режиме реального времени, и несколько видов карты файлов.
>>В классе MinesweeperGame, возможно, лучше было бы сделать 2 словаря:
>>- cells[y][x] с объектами Cell с информацией о клеточке
>>- openedCells[y][x] с true/false, показывает, открыта ли клетка
>>- markedCells[y][x] true/false
>>Можно сделать даже один словарь, если сделать у ячейки свойства isOpened/isMarked, но тогда их можно случайно поменять, и MinesweeperGame об этом не узнает (и не сгенерирует событие). Но можно конечно договориться так не делать.
>>Или можно сделать Cell тоже источником событий, и подписываться на событие открытия, но это конечно немного усложнит жизнь.
>>А у тебя этого нет, у тебя одна и та же клеточка может быть представлена 2 разными объектами в minedCells и openCells, это, мне кажется, нехорошо. Ведь тогда, если мы хотим что-то у клеточки поменять, мы должны найти все экземпляры и поменять нужное свойство. Лучше делать, что 1 сущности соответствует ровно 1 экземпляр объекта.
Я сделал один словарь cells[y][x] с объектами Cell с информацией о клеточках. Договорился сам с собою, что свойство _cells и объекты Cell - это формат для хранения данных, доступ к которым(ому) имеет только класс MinesweeperGame, и никто снаружи не знает о их существовании. Словарь наполняется автоматически при создании игры, а класс может только изменять свойства внутри каждого Cell.
>>https://github.com/enotocode/minesweeper.mvc/blob/master/app/GameEvent.js
>>Здесь, ты может сам заметил, проблема в том, что у разных событий может быть разное число аргументов, с разными названиями. Получается, надо либо сделать разные классы событий, либо сделать один класс, а аргументы передавать словарем вроде { cell: someCell, action: SomeClass.ACTION_OPEN }
>>Использование нескольких классов требует больше кода, но позволяет ставить jsDoc, добавлять кастомные методы и свойства в события.
Добавил
- ButtonEvent // события кнопок View
- CellEvent // клетки по которым кликнули во View и клетки которые отрыли/отметили в MinesweeperGame
- StatusEvent // изменение статуса игры MinesweeperGame
>>Еще, наверно, стоило бы начать раскидывать файлы по папкам.
А как делить файлы по папкам, View/Controller/Other ?
>>https://github.com/enotocode/minesweeper.mvc/tree/master/app
>>Ну и насчет 2 независимых контроллеров (ModalController/BrowserViewController) - вот я не уверен, а не лучше ли сделать ModalController/ModalView подчиненными BrowserViewController, чтобы он им говорил, когда показать диалог, а не они сами решали?
>>А то просто у тебя получается что диалог сам решает, когда ему открываться, как-то иерархия управления размывается, это как 2 директора на одном предприятии.
Сделал так:
1. пара ModalView/ModalController создается в Controller,
2. Controller же следит за событиями модели, чтобы вызывать методы show()/hide() модального окна (но через ModalController)
3. ModalController имеет прямой доступ к модели, чтобы обрабатывать события ModalView.
4. ModalView ничего ни о ком не знает
Мне не нравится 2 пункт, т.к. Controller теперь связан еще с одним классом кроме View. И пункт 3 - если у контроллера модального окна есть доступ к модели, может быть пусть сам запускает show()/hide(), или убрать доступ, тогда Controller должен подписаться на события ModalController, или ModalController иметь доступ к методу Controller что увеличит их связанность?
>>BrowserViewController очень сильно привязан к BrowserView, оно в общем-то логично, но я поймал себя на мысли, что может быть, проще было его код во View и поместить?
Понять что происходит будет определенно проще. Но пока оставлю так.
>>ConsoleController.prototype.updateCellStatus = function(status, cell){
>>Проще наверно просто пересоздавать строку с нуля, а не мучаться с заменой отдельного символа. там все равно отрисовка этого поля потом больше времени займет.
Тогда мне нужно получать все ячейки из модели при каждой отрисовке. Т.к. я договорился что внутреннее хранилище с ячейкими не покинет модели, мне нужно сделать метод получения данных о всех ячейках, т.е. создать новый формат для передачи данных или клонировать массив со всеми классами внутри. А потом отрисовывать его?
И нужно будет перерисовывать поле каждый раз, при открытии каждой клетки, но за один ход могут открыться сразу несколько соседних, если рядом с ними нет мин. Сейчас так выглядит вывод поля в консоли браузера.
>>А так тебе приходится держать копию данных модели и синхронизировать ее постоянно. Сложно и есть риск что-то забыть.
В BrowserView тоже хранится копия данных в DOM и также происходит отрисовка, мы начинаем с поля где все ячейки не раскрыты, и при появлении события от модели открываем по одной ячейке. Хотя для добаления возможности отменить действие, вариант с полной отрисовкой надежнее. Осталось решить в каком виде получать данные о клетках из модели.
>>https://github.com/enotocode/minesweeper.mvc/tree/master/templates/css
>>Это надо поместить в public.
Public вообще пришлось убрать, чтобы не дублировать файлы, т.к. gitPages берет index.html из корневой папки проекта.
>>если за раз открывается несколько клеточек, в консоль вываливается куча изображений поля
Придумал пока два варианта как это сделать.
1. Сделать буфер для задания на отрисовку и задержку на его выполнение, каждое новое задание заменяет старое, и обновляет таймер задержки. Но как-то не надежно.
2. Можно добавить два статуса для метода модели openCell(), при запуске метода статус изменяется на OPENING, в самом конце выполнения статус на - WAITING. Функция входит в рекурсию до изменения статуса на WAITING, а в режиме рекурсии не меняет совсем. View должна иметь прямой доступ к модели или сделать этот статус свойством события открытия каждой клетки.
Я делал без js, задача по PHP же. Перезагружал страницу, чтобы отобразить следующих 10 студентов.
Ну мне просто показалось странным(диким) перезагружать страницу, но раз надо тогда ладно...(если щас начать учить жаву будет ведь каша из синтаксиса и встроенных методов в языки).
Тут отдельные проблемы, которые надо решать по отдельности. Вот там человек пишет советы по принципу "слышал звон", а я напишу конкретно.
"я уже начал изменять его, а когда он решит изменить, ему полезут ошибки" - для предотвращения этой проблемы можно использовать блокировки. При редактировании берется блокировка на запись, и при попытке открыть форму редактирования на другом компьютере или что-то сделать с записью выводится соответствующее сообщение.
Блокировку нужно брать только на определенное время, так как если пользователь отсоединился по каким-то причинам, запись не должна оставаться заблокированной навечно. Ну и наоборот, пока пользователь редактируети данные, надо продлевать блокировку. Даже тут возможны конфликты, если пользователь A открыл форму редактирвоания, взял блокировку, затем у него пропал интернет и блокировку взял пользователь B. Когда у A появяится соединение с сетью, он обнаружит, что блокировка потеряна и данные, возможно, изменены другим пользователем.
Кстати, блокировки бывают 2 видов: пессимистичные и оптимистичные. При пессимистичной мы берем блокировку до редактирования данных и не даем другому пользователю их редактировать. При оптимистичной - мы используем версионирование и при попытке сохранить данные обнаруживаем, что они были изменены другим пользователем и предлагаем что-нибудь сделать.
Другая проблема, что данные могут изменяться одним пользователем, пока их просматривает другой пользователь. Если так принципиально обновлять их в реальном времени, то надо делать на сервере систему трансляции обновлений. Клиент, который загружает какие-то данные, соединяется с сервером, подписывается на получение их изменений, и обновляет данные на экране при поступлении таких данных. Также, в простых случаях есть вариант поллинга - вместо возни с вебсокетами можно просто отправлять запросы на сервер раз в N секунд и спрашивать, не изменились ли данные. Разумеется, на сервере надо будет хранить для каждой записи время ее изменения или номер версии, чтобы это реализовать.
То есть здесь важно сначала проработать модель, как это все будет работать, учесть все возможные ситуации, а потом только браться за написание кода. Ну и такие вещи конечно удобно решать не на уровне отдельной формы, а сделать какой-то фреймворк, чтобы это поведение легко можно было добавить к любой форме.
>>988547
Ты даже не пытался разобраться, а уже обвиняешь Хром. А правильно ли настроены кеширующие HTTP заголовки на твоем сервере? А ставишь ли ты галочку "не использовать кеш" в инструментах разработчика. 99%, что виноват не Хром, а ты.
Для очистки кеша не требуется удалять куки и терять авторизацию. Можно очистить только кеш.
>>988540
Видимо нет. Не знаю, зачем тебе виртуальная машина конечно.
>>988493
В парадигме MVC не передают request в модель. Да и если отложить в сторону MVC, я вот сомневаюсь что модели нужен request целиком - скорее всего какие-то отдельные маленькие части.
Напомню что у меня есть урок по MVC, наверно тебе пригодится: https://github.com/codedokode/pasta/blob/master/arch/mvc.md
>>988397
Когда мы в выражении "2 + 3 - 1" доходим до плюса, мы не можем выполнить сложение, так как не прочитали еще число 3. Потому мы сохраняем операцию в переменную на будущее, читаем второй аргумент, и когда дойдем до минуса, выполняем ранее сохраненную операцию.
Тут отдельные проблемы, которые надо решать по отдельности. Вот там человек пишет советы по принципу "слышал звон", а я напишу конкретно.
"я уже начал изменять его, а когда он решит изменить, ему полезут ошибки" - для предотвращения этой проблемы можно использовать блокировки. При редактировании берется блокировка на запись, и при попытке открыть форму редактирования на другом компьютере или что-то сделать с записью выводится соответствующее сообщение.
Блокировку нужно брать только на определенное время, так как если пользователь отсоединился по каким-то причинам, запись не должна оставаться заблокированной навечно. Ну и наоборот, пока пользователь редактируети данные, надо продлевать блокировку. Даже тут возможны конфликты, если пользователь A открыл форму редактирвоания, взял блокировку, затем у него пропал интернет и блокировку взял пользователь B. Когда у A появяится соединение с сетью, он обнаружит, что блокировка потеряна и данные, возможно, изменены другим пользователем.
Кстати, блокировки бывают 2 видов: пессимистичные и оптимистичные. При пессимистичной мы берем блокировку до редактирования данных и не даем другому пользователю их редактировать. При оптимистичной - мы используем версионирование и при попытке сохранить данные обнаруживаем, что они были изменены другим пользователем и предлагаем что-нибудь сделать.
Другая проблема, что данные могут изменяться одним пользователем, пока их просматривает другой пользователь. Если так принципиально обновлять их в реальном времени, то надо делать на сервере систему трансляции обновлений. Клиент, который загружает какие-то данные, соединяется с сервером, подписывается на получение их изменений, и обновляет данные на экране при поступлении таких данных. Также, в простых случаях есть вариант поллинга - вместо возни с вебсокетами можно просто отправлять запросы на сервер раз в N секунд и спрашивать, не изменились ли данные. Разумеется, на сервере надо будет хранить для каждой записи время ее изменения или номер версии, чтобы это реализовать.
То есть здесь важно сначала проработать модель, как это все будет работать, учесть все возможные ситуации, а потом только браться за написание кода. Ну и такие вещи конечно удобно решать не на уровне отдельной формы, а сделать какой-то фреймворк, чтобы это поведение легко можно было добавить к любой форме.
>>988547
Ты даже не пытался разобраться, а уже обвиняешь Хром. А правильно ли настроены кеширующие HTTP заголовки на твоем сервере? А ставишь ли ты галочку "не использовать кеш" в инструментах разработчика. 99%, что виноват не Хром, а ты.
Для очистки кеша не требуется удалять куки и терять авторизацию. Можно очистить только кеш.
>>988540
Видимо нет. Не знаю, зачем тебе виртуальная машина конечно.
>>988493
В парадигме MVC не передают request в модель. Да и если отложить в сторону MVC, я вот сомневаюсь что модели нужен request целиком - скорее всего какие-то отдельные маленькие части.
Напомню что у меня есть урок по MVC, наверно тебе пригодится: https://github.com/codedokode/pasta/blob/master/arch/mvc.md
>>988397
Когда мы в выражении "2 + 3 - 1" доходим до плюса, мы не можем выполнить сложение, так как не прочитали еще число 3. Потому мы сохраняем операцию в переменную на будущее, читаем второй аргумент, и когда дойдем до минуса, выполняем ранее сохраненную операцию.
Да, интерпретатор PHP - это программа, написанная в основном на языке Си. Для описания правил используется специальный язык вроде Yacc (я могу ошибаться в названии), который придуман специально для описания грамматик. То есть правила пишут на языке Yacc, а он из них генерирует код на Си, который анализирует текст программы по этим правилам.
Вообще, какой элемент компьютера выполняет программы? Это процессор, CPU. Процессор - это по сути калькулятор, который работает по программе, хранящейся в памяти. Процессор "понимает" только один язык - машинные коды. Это числа, каждое из которых обозначает определенную операцию. Ну например, там есть коды, которые обозначают команды вроде "поместить число N в регистр A", "прибавить к содержимому регистра A число X", "поместить число X в ячейку памяти Y". В памяти компьютера хранятся эти коды, процессор читает их по одному и выполняет.
То есть команды процессора очень примитивные. Потому машинные коды называют "низкоуровневым" языком. Чтобы просто посчитать какое-то математическое выражение вроде $x + $y, ты должен разложить его на отдельные операции (взять число из памяти, поместить в регистр процессора A, взять второе число, поместить в регистр B, сложить регистры A и B, поместить результат в память) и записать в виде кодов.
Приведу другой пример: в процессоре нет команды вывода текста на экран - это слишком сложно для него. Чтобы вывести букву на экран, мы должны записывать определенные числа в определенные ячейки памяти, каждая из которых управляет состоянием отдельного пикселя на экране. То есть, чтобы вывести букву "A" на экран, нужно выполнить сотни машинных команд (делая определенные пиксели экрана темными или светлыми).
Понятно, что вручную писать эти коды - долго, и неудобно. Потому люди придумали множество высокоуровневых языков программирования, на которых можно писать более понятный человеку код. Ну например, $x = $x + 1; или echo "A". Такой код удобен для человека, но непонятен процессору. Он не может его выполнить. И есть 2 способа решить эту проблему - компиляция и интерпретация.
При компиляции программа-компилятор разбирает текст высокоуровневой программы и преобразует ее в машинные коды, выдавая на выходе исполняемый файл (под Windows это будет exe-файл, под линуксом - файл формата ELF). Затем ты можешь запустить этот файл. Когда ты запускаешь exe-файл, операционная система (Windows) загружает хранящиеся в нем машинные коды с диска в память и процессор их выполняет.
Если ты хочешь что-то поменять в исходном коде - надо запускать компиляцию заново и генерировать новый исполняемый файл.
Такой подход используют языки Си, Го, Раст.
Другой подход - интерпретация. При этом подходе мы запускаем программу-интерпретатор, которая принимает на вход высокоуровневый код, разбирает его и выполняет инструкции в нем по очереди. В отличие от предыдущего подхода, тут не создается исполняемый файл, не генерируются машинные коды и не требуется перекомпиляция при правке кода. Но, как правило, с интепретатором код выполняется медленнее, так как он выполняется не напрямую процессором, а интерпретируется другой программой.
PHP использует второй подход, то есть интерпретирует код. Но сам интепретатор PHP написан на языке Си, который использует подход с компиляцией. На Гитхабе выложен исходный код интерпретатора PHP ( https://github.com/php/php-src ) на языке Си. Разработчики PHP компилируют этот код в исполняемый exe-файл и выкладывают на свой сайт, откуда все его скачивают.
То есть получается что интерпретатор php - это программа в машинных кодах, сгенерированных из исходного кода на Си. И эта программа анализирует и выполняет программу на языке PHP, которую ты написал. Такая вот система.
Кроме PHP, интепретацию используют языки Яваскрипт, Питон, Руби.
Также, если тебе интересно, есть еще смешанный подход - интерпретатор интепретирует программу, но если какой-то ее кусочек выполняется много раз, то он компилирует этот кусочек в машинные коды и выполняет их напрямую на процессоре ради повышения быстродействия. Это называется JIT - компиляция кода "на лету". Если ты используешь Хром, то в нем есть интерпретатор языка Яваскрипт, который содержит в себе JIT-компилятор.
И есть еще один вариант, когда высокоуровневая программа компилируется, но не в машинные коды процессора, а просто в какие-то условные коды (байткод), которые интерпретирует программа под названием "виртуальная машина". То есть это подход, который содержит и компиляцию в коды, и интепретацию этих кодов виртуальной машиной. Зачем такие сложности? Дело в том, что машинные коды у разных процессоров разные. Программа, скопилированная под процессор смартфона, не запустится на процессоре настольного компьютера. А программа, скопилированная для 64-битного процессора, не запустится на 32-битном. Компиляция в байткод (который не привязан к конкретной модели процессора) позволяет решить эту проблему. Также, байткод может содержать более высокоуровневые операции, чем те, что выполняет процессор. Такой код работает чуть медленнее, чем скомпилированный в настоящий машинный код, но быстрее чем при интерпретации. Этот подход используют языки Ява и C# (и другие дотнет-языки).
Код на Си работает быстрее, чем на PHP, но ему требуется компиляция перед выполнением, а также язык Си не такой высокоуровневый, как PHP и написание программы на нем займет больше времени. Также, он сложнее и требует больше времени для изучения.
Да, интерпретатор PHP - это программа, написанная в основном на языке Си. Для описания правил используется специальный язык вроде Yacc (я могу ошибаться в названии), который придуман специально для описания грамматик. То есть правила пишут на языке Yacc, а он из них генерирует код на Си, который анализирует текст программы по этим правилам.
Вообще, какой элемент компьютера выполняет программы? Это процессор, CPU. Процессор - это по сути калькулятор, который работает по программе, хранящейся в памяти. Процессор "понимает" только один язык - машинные коды. Это числа, каждое из которых обозначает определенную операцию. Ну например, там есть коды, которые обозначают команды вроде "поместить число N в регистр A", "прибавить к содержимому регистра A число X", "поместить число X в ячейку памяти Y". В памяти компьютера хранятся эти коды, процессор читает их по одному и выполняет.
То есть команды процессора очень примитивные. Потому машинные коды называют "низкоуровневым" языком. Чтобы просто посчитать какое-то математическое выражение вроде $x + $y, ты должен разложить его на отдельные операции (взять число из памяти, поместить в регистр процессора A, взять второе число, поместить в регистр B, сложить регистры A и B, поместить результат в память) и записать в виде кодов.
Приведу другой пример: в процессоре нет команды вывода текста на экран - это слишком сложно для него. Чтобы вывести букву на экран, мы должны записывать определенные числа в определенные ячейки памяти, каждая из которых управляет состоянием отдельного пикселя на экране. То есть, чтобы вывести букву "A" на экран, нужно выполнить сотни машинных команд (делая определенные пиксели экрана темными или светлыми).
Понятно, что вручную писать эти коды - долго, и неудобно. Потому люди придумали множество высокоуровневых языков программирования, на которых можно писать более понятный человеку код. Ну например, $x = $x + 1; или echo "A". Такой код удобен для человека, но непонятен процессору. Он не может его выполнить. И есть 2 способа решить эту проблему - компиляция и интерпретация.
При компиляции программа-компилятор разбирает текст высокоуровневой программы и преобразует ее в машинные коды, выдавая на выходе исполняемый файл (под Windows это будет exe-файл, под линуксом - файл формата ELF). Затем ты можешь запустить этот файл. Когда ты запускаешь exe-файл, операционная система (Windows) загружает хранящиеся в нем машинные коды с диска в память и процессор их выполняет.
Если ты хочешь что-то поменять в исходном коде - надо запускать компиляцию заново и генерировать новый исполняемый файл.
Такой подход используют языки Си, Го, Раст.
Другой подход - интерпретация. При этом подходе мы запускаем программу-интерпретатор, которая принимает на вход высокоуровневый код, разбирает его и выполняет инструкции в нем по очереди. В отличие от предыдущего подхода, тут не создается исполняемый файл, не генерируются машинные коды и не требуется перекомпиляция при правке кода. Но, как правило, с интепретатором код выполняется медленнее, так как он выполняется не напрямую процессором, а интерпретируется другой программой.
PHP использует второй подход, то есть интерпретирует код. Но сам интепретатор PHP написан на языке Си, который использует подход с компиляцией. На Гитхабе выложен исходный код интерпретатора PHP ( https://github.com/php/php-src ) на языке Си. Разработчики PHP компилируют этот код в исполняемый exe-файл и выкладывают на свой сайт, откуда все его скачивают.
То есть получается что интерпретатор php - это программа в машинных кодах, сгенерированных из исходного кода на Си. И эта программа анализирует и выполняет программу на языке PHP, которую ты написал. Такая вот система.
Кроме PHP, интепретацию используют языки Яваскрипт, Питон, Руби.
Также, если тебе интересно, есть еще смешанный подход - интерпретатор интепретирует программу, но если какой-то ее кусочек выполняется много раз, то он компилирует этот кусочек в машинные коды и выполняет их напрямую на процессоре ради повышения быстродействия. Это называется JIT - компиляция кода "на лету". Если ты используешь Хром, то в нем есть интерпретатор языка Яваскрипт, который содержит в себе JIT-компилятор.
И есть еще один вариант, когда высокоуровневая программа компилируется, но не в машинные коды процессора, а просто в какие-то условные коды (байткод), которые интерпретирует программа под названием "виртуальная машина". То есть это подход, который содержит и компиляцию в коды, и интепретацию этих кодов виртуальной машиной. Зачем такие сложности? Дело в том, что машинные коды у разных процессоров разные. Программа, скопилированная под процессор смартфона, не запустится на процессоре настольного компьютера. А программа, скопилированная для 64-битного процессора, не запустится на 32-битном. Компиляция в байткод (который не привязан к конкретной модели процессора) позволяет решить эту проблему. Также, байткод может содержать более высокоуровневые операции, чем те, что выполняет процессор. Такой код работает чуть медленнее, чем скомпилированный в настоящий машинный код, но быстрее чем при интерпретации. Этот подход используют языки Ява и C# (и другие дотнет-языки).
Код на Си работает быстрее, чем на PHP, но ему требуется компиляция перед выполнением, а также язык Си не такой высокоуровневый, как PHP и написание программы на нем займет больше времени. Также, он сложнее и требует больше времени для изучения.
Для разных случаев подходят разные языки.
Программы под Андроид обычно пишут на Яве (но есть варианты использования HTML/CSS/JS)
Под iOS и мак - на Swift, Objective-C
Под Windows - обычно на Си++ или Си. Иногда на Яве или C#.
Под веб - на PHP, Питоне, Руби, Яве, Яваскрипте, Го
>>988303
Толсто же. Для обсуждения жизни есть другие треды и доски. А наш тред как раз для вопросов от начинающих.
>>988069
Перекатывать я стараюсь на 700-800 постах, чтобы по возможности ответить на все вопросы в треде. И мне не принципиально, чтобы наш тред был всегда на первой странице, зачем? Я и так знаю, что он очень популярный и посещаемый.
А проблем промотать до 2-3 страницы я не вижу. Также можно просто добавить тред в закладки или не закрывать вкладку с ним.
>>987901
В этой задаче ты должен придумать какой-то алгоритм. То есть описать как-то, что должен делать компьютер, чтобы проверить, является слово палиндромом или нет. Ты должен разбить этот алгоритм на отдельные действия и уже после этого писать программу.
И не пропускай задачи, я бы тебе советовал потом попросить у ОПа дополнительную задачку на циклы и строки.
> О какой настройке идёт речь? Можно же и так ссылаться на любой домен в html ссылке.
Я имел в виду, если ты выносишь картинки на отдельный домен, то прописать этот домен в конфиге, чтобы его можно было легко менять, не трогая код. А также чтобы можно было на локальной версии сайта использовать локальный домен.
> Ничего, просто хотелось иметь красивую ссылку.
Так вроде никто и не делает, кроме каких-то случаев адской SEO оптимизации. Форма ведь не генерирует красивые URL.
> Значит не получиться обойтись без посредников. Это печально, потому что регистраторы с первой страницы гугла выглядят как очередные корпорации зла. Хотелось бы обойтись без них.
Можно сделать свою доменнную зону, правда это дороговато... Но вообще, тут есть причины: администратор зоны не очень хочет заморачиваться с продажами, техподдержкой - ему проще дать доступ к API и получать деньги. Ну и как плюс, один регистратор может работать с многими зонами, давать какие-то дополнительные услуги вроде DNS-хостинга.
Если тебя беспокоит цена, можно поискать какие-то дешевые зоны, есть даже бесплатные домены (вроде .tk), но там какие-то свои подвохи. Бывают бесплатные домены 3-го уровня.
>>987588
> SELECT FROM table WHERE x <> 1
> Индекс не поможет.
Верно
> SELECT FROM table WHERE x + y < 100
> Индекс на x не будет использоваться. Это потому, что индекс построен для X, а мы запрашиваем X+Y? Затрудняюсь провести аналогию со словарём.
Чтобы индекс использовался, поле должно стоять отдельно (x < 100), а не как часть выражения. В других БД, вроде Oracle или Postgres, кстати, есть функциональные индексы - индексы по результату выражения. Там можно было бы построить индекс по выражению x + y и использовать его: https://postgrespro.ru/docs/postgrespro/9.5/indexes-expressional.html
> SELECT MAX(a) FROM table WHERE b = 2
> Индекс на b поможет.
Да, он поможет, но можно сделать лучше. Индекс по b позволит быстро найти все записи с b = 2, но далее СУБД будет обходить их по одной, ища запись с наибольшим значением a. А что, если их миллион? Тут лучше поможет индекс по паре (b, a). В нем при b = 2 записи будут выстроены по возрастанию a, и мы можем просто взять последнюю запись у которой b = 2, в ней a будет наибольшее.
Если записать:
b | a
1 100
2 1
2 5
2 100
3 1
Тут MySQL может быстро найти в индексе начало и конец диапазона где b = 2, и взять MAX(a) из последней записи "2 100". Хотя конечно это стоило бы проверить с помощью EXPLAIN.
Также, если бы мы написали запрос WHERE b = 2 AND a <= 5 то он оптимизируется так: MySQL найдет в индексе строку "2 5" и будет шагать вверх (в сторону убывания a), пока b = 2. То есть он возьмет записи "2 5", затем "2 1", затем увидит "1 100" и остановится, так как b больше не равно 2. Или может, наоборот, он найдет строку "2 1" и будет шагать от нее вперед по индексу, пока одно из условий (b = 2 или a <= 5) не нарушится. Это по сути то же самое.
> SELECT FROM table WHERE name LIKE '%Иван%'
> Для такого запроса индекс по name не поможет, всё равно что искать в словаре слова с неизвестной первой буквой. Как понял, должен помочь FULLTEXT индекс и операторы AGAINST/MATCH
FULLTEXT не поможет (по моему) при поиске по части слова, только по полному слову или началу слова.
> SELECT FROM table WHERE b = 1 AND a < 10
Тут надо разобраться как работают составные индексы пол нескольким полям. В индексе (x, y, z) записи выстраиваются по возрастанию x, при равном x - по возрастанию y, при равных x и y - по возрастанию z.
Такой индекс позволяет искать по условиям:
x = ?
x = ? AND y = ?
x < ?
x = ? AND y < ?
x = ? AND y BETWEEN ? AND ?
MAX(y) WHERE x = ?
и так далее.
Тут нам нужен индекс, где записи, подпадающие под условие b = 1 AND a < 10 будут идти одним блоком, так что можно найти в индексе точку где b = 1, a = 10, и шагать от нее в сторону убывания a, пока b не поменяет свое значение (перестанет быть равной 1).
> Но потом он добавляет индекс gender_age и пишет, что теперь запросы будет использовать полный индекс. Выходит такой индекс
У тебя неправильный индекс, так как male99 должен идти между male29 и female15, а не в конце списка. Если ты построишь индекс правильно, то увидишь что для выполнения запроса достаточно найти в индексе запись male29 и шагать от нее к началу индекса, до тех пор, пока первое поле все еще равно male.
> О какой настройке идёт речь? Можно же и так ссылаться на любой домен в html ссылке.
Я имел в виду, если ты выносишь картинки на отдельный домен, то прописать этот домен в конфиге, чтобы его можно было легко менять, не трогая код. А также чтобы можно было на локальной версии сайта использовать локальный домен.
> Ничего, просто хотелось иметь красивую ссылку.
Так вроде никто и не делает, кроме каких-то случаев адской SEO оптимизации. Форма ведь не генерирует красивые URL.
> Значит не получиться обойтись без посредников. Это печально, потому что регистраторы с первой страницы гугла выглядят как очередные корпорации зла. Хотелось бы обойтись без них.
Можно сделать свою доменнную зону, правда это дороговато... Но вообще, тут есть причины: администратор зоны не очень хочет заморачиваться с продажами, техподдержкой - ему проще дать доступ к API и получать деньги. Ну и как плюс, один регистратор может работать с многими зонами, давать какие-то дополнительные услуги вроде DNS-хостинга.
Если тебя беспокоит цена, можно поискать какие-то дешевые зоны, есть даже бесплатные домены (вроде .tk), но там какие-то свои подвохи. Бывают бесплатные домены 3-го уровня.
>>987588
> SELECT FROM table WHERE x <> 1
> Индекс не поможет.
Верно
> SELECT FROM table WHERE x + y < 100
> Индекс на x не будет использоваться. Это потому, что индекс построен для X, а мы запрашиваем X+Y? Затрудняюсь провести аналогию со словарём.
Чтобы индекс использовался, поле должно стоять отдельно (x < 100), а не как часть выражения. В других БД, вроде Oracle или Postgres, кстати, есть функциональные индексы - индексы по результату выражения. Там можно было бы построить индекс по выражению x + y и использовать его: https://postgrespro.ru/docs/postgrespro/9.5/indexes-expressional.html
> SELECT MAX(a) FROM table WHERE b = 2
> Индекс на b поможет.
Да, он поможет, но можно сделать лучше. Индекс по b позволит быстро найти все записи с b = 2, но далее СУБД будет обходить их по одной, ища запись с наибольшим значением a. А что, если их миллион? Тут лучше поможет индекс по паре (b, a). В нем при b = 2 записи будут выстроены по возрастанию a, и мы можем просто взять последнюю запись у которой b = 2, в ней a будет наибольшее.
Если записать:
b | a
1 100
2 1
2 5
2 100
3 1
Тут MySQL может быстро найти в индексе начало и конец диапазона где b = 2, и взять MAX(a) из последней записи "2 100". Хотя конечно это стоило бы проверить с помощью EXPLAIN.
Также, если бы мы написали запрос WHERE b = 2 AND a <= 5 то он оптимизируется так: MySQL найдет в индексе строку "2 5" и будет шагать вверх (в сторону убывания a), пока b = 2. То есть он возьмет записи "2 5", затем "2 1", затем увидит "1 100" и остановится, так как b больше не равно 2. Или может, наоборот, он найдет строку "2 1" и будет шагать от нее вперед по индексу, пока одно из условий (b = 2 или a <= 5) не нарушится. Это по сути то же самое.
> SELECT FROM table WHERE name LIKE '%Иван%'
> Для такого запроса индекс по name не поможет, всё равно что искать в словаре слова с неизвестной первой буквой. Как понял, должен помочь FULLTEXT индекс и операторы AGAINST/MATCH
FULLTEXT не поможет (по моему) при поиске по части слова, только по полному слову или началу слова.
> SELECT FROM table WHERE b = 1 AND a < 10
Тут надо разобраться как работают составные индексы пол нескольким полям. В индексе (x, y, z) записи выстраиваются по возрастанию x, при равном x - по возрастанию y, при равных x и y - по возрастанию z.
Такой индекс позволяет искать по условиям:
x = ?
x = ? AND y = ?
x < ?
x = ? AND y < ?
x = ? AND y BETWEEN ? AND ?
MAX(y) WHERE x = ?
и так далее.
Тут нам нужен индекс, где записи, подпадающие под условие b = 1 AND a < 10 будут идти одним блоком, так что можно найти в индексе точку где b = 1, a = 10, и шагать от нее в сторону убывания a, пока b не поменяет свое значение (перестанет быть равной 1).
> Но потом он добавляет индекс gender_age и пишет, что теперь запросы будет использовать полный индекс. Выходит такой индекс
У тебя неправильный индекс, так как male99 должен идти между male29 и female15, а не в конце списка. Если ты построишь индекс правильно, то увидишь что для выполнения запроса достаточно найти в индексе запись male29 и шагать от нее к началу индекса, до тех пор, пока первое поле все еще равно male.
Немного глянул https://github.com/grigoryMovchan/AphorismCMS/
Вообще, я бы тебе советовал почитать комментарии к задаче о студентах в ОП посте. Так как не хочется по второму разу их пересказывать.
У тебя есть папка public - почему тогда index.php вне нее? Ты по моему не понял идею, там идея в том, что public должна быть корневой папкой веб-сервера, и код лежит снаружи нее.
Папка vendor не должна быть в репозитории (ее надо добавить в гитигнор), зато в него стоит положить composer.lock.
https://github.com/grigoryMovchan/AphorismCMS/blob/master/db.sql#L25
> ENGINE=MyISAM
Почитай сравнение движков MyISAM и InnoDB
> `password_user` varchar(255) NOT NULL,
Тут нужен комментарий, что там хранится. Надеюсь, соленый хеш пароля, а не сам пароль в открытом виде?
В базе нужно проставить внешние ключи.
https://github.com/grigoryMovchan/AphorismCMS/blob/master/app/core/Route.php#L69
Тут непонимание протокола HTTP. Нельзя отдавать заголовок Location при коде 4xx. Он используется с кодом 3xx в тех случаях, когда страница переехала на другой адрес. Если страница не найдена, надо отдавать код 404. Почитай назначение кодов состояния HTTP.
Класс Route должен правильно называться FrontController.
Используемый подход к роутингу плох тем, что для одной страницы существует много URL, например /controller, /CONTROLLER, /controller/index/1/2/3, /controller/index/4/5/6 - при ошибке в URL ты можешь не заметить что ошибся, и на индексации поисковиками это плохо скажется.
Убрать query string из URL лучше с помощью parse_url().
> $url = 'Location: /' . strtolower($controllerName) . '/';
> header($url);
Тут после отдачи Location скрипт продолжает выполняться.
Также, код в Route->start() плохочитаемый, попробуй сам прочесть. Стена кода, ты бы хоть на функции ее разбил.
https://github.com/grigoryMovchan/AphorismCMS/blob/master/app/core/Request.php#L45
> public function getFeedbackString($separator = "<br>")
Класс Request не должен отвечать за вывод информации и ее оформление, генерацию HTML кода.
https://github.com/grigoryMovchan/AphorismCMS/blob/master/app/core/View.php#L8
> @param str
> @param arr
В phpdoc нет типов str и arr: https://phpdoc.org/docs/latest/guides/types.html
> public function generate($content_view, $template_view, $data = null, $error = null)
Не очень понятно, почему для $error сделан отдельный аргумент, а все остальное передается в $data.
https://github.com/grigoryMovchan/AphorismCMS/blob/master/app/core/Model.php
Этот класс выглядит сомнительно (например не очень понятно что такое в твоем понимании Model, для чего этот класс предназначен. Надо добавить комментарий перед ним). ensure() там явно не к месту, так как эта функция может быть полезна не только в модели и ее лучше сделать отдельным статическим методов в отдельном классе.
Не соблюдается PSR-4. Например неймспейс имеет вид namespace Application\Core, а папка называется core, с маленькой буквы.
https://github.com/grigoryMovchan/AphorismCMS/blob/master/app/configs/app_example.ini
Плохой пример так как не содержит пояснений и непонятно зачем там 2 секции с БД.
https://github.com/grigoryMovchan/AphorismCMS/blob/master/app/controllers/QuotesController.php#L16
> $this->data['thisPage'][0] = 'quotes';
Тут по моему ты добавляешь элемент 0 в несуществующий массив. Зачем так запутывать код?
> $this->quotes = new QuotesModel($this->request);
Непонятно зачем Модели нужен request. В MVC модели он не нужен.
https://github.com/grigoryMovchan/AphorismCMS/blob/master/app/models/QuotesModel.php#L22
> $this->dbh = new MysqlModel(ConfigModel::UNMARRIED);
Почитай мой урок про DI. https://github.com/codedokode/pasta/blob/master/arch/di.md
https://github.com/grigoryMovchan/AphorismCMS/blob/master/app/models/QuotesModel.php#L207
тут видно полное непонимание идеи MVC. Идея ведь там отделить логику приложения (модель) от взаимодействия с внешним миром (контроллер).
У тебя получилась плохая функция getQuote(). Вот допустим я хочу получить цитату с id = 7. Как ее получить, если в функцию нельзя передать id?
Получить след/пред цитату проще через WHERE id > ? ORDER BY id LIMIT 1
Также, подход что при ошибке поиска возвращается имитация цитаты, тоже плохой. Ведь при твоем подходе непонятно как определить, что цитата не найдена. Да и при ненайденной цитате логичнее отдавать 404, а не притворяться что такая страница есть.
Выборка случайного id неэффективно сделана. Погугли про оптимизацию выборки случайной записи.
https://github.com/grigoryMovchan/AphorismCMS/blob/master/app/models/MysqlModel.php
Тут непонятно на каком основании MysqlModel наследуется от Model (у них ведь ничего общего нет) и почему она вообще назвается Model. тебе надо определиться для начала, что ты называешь моделью.
https://github.com/grigoryMovchan/AphorismCMS/blob/master/app/models/MysqlModel.php#L50
Тут неудачный подход, ты зря пытаешься объединить разные функции (fetchAll, fetch) в одну - это только создает неудобства. Ну например, из-за этого функция возвращает разные типы данных, а не один определенный. Ну и непонятно, зачем это сделано, такое ощущение что ты себе жизнь усложнить пытаешься.
> без понятия зачем тут нужен новый уровень абстракции
Если без понятия, то не надо делать. Ты должен понимать каждую строчку кода. А так ты просто копируешь то, что увидел где-то, не понимая. Это какой-то культ карго. Зачем? Если ты хочешь произвести впечатление на собеседовании своим кодом, то любой опытный программист легко тебя раскусит.
https://github.com/grigoryMovchan/AphorismCMS/blob/master/app/models/AuthModel.php#L66
Тут зачем htmlspecialchars? Это же не шаблон.
Вообще AuthModel требует упорядочивания, там как-то все перемешано. ну например, операции с БД можно из него убрать в другой класс.
Функции и переменные надо назвыать единообразно, а не одну с подчеркиванием, а другую кемел кейсом.
Дальше не смотрел.
По дизайну - я не дизайнер, но кое-что бросается в глаза. У тебя на странице с цитатой самый "тяжелый" элемент, на который обращаешь внимание в первую очередь - это кнопки. Мало того, что они залиты, так еще и ярко-белым цветом, который ярче, чем текст. Но ведь главный-то элемент наверно не они, а цитата. Я бы советовал попробовать поиграть с кнопками - сделать их менее яркими или убрать белую заливку - и посмотреть что получится. Также, плашка слева от цитаты тоже выглядит тяжеловатой, может быть стоит попробовать сделать ее побледнее?
Непонятно, что обозначает третья кнопка с иконкой комментария (вторая - это случайная цитата или "поделиться"? Тоже не очень понятно).
В форме ошибки нечитаемы, белый текст на светлом фоне.
> Шаблон не осилил, верстка поехала, не смог в CSS.
Пройди наши задачи на HTML/CSS из ОП поста и наверно тогда осилишь. Также, есть заблуждение, что использование бустрапа избавляет от необходимости учить CSS (как и использование ORM избавляет от необходимости учить SQL).
Немного глянул https://github.com/grigoryMovchan/AphorismCMS/
Вообще, я бы тебе советовал почитать комментарии к задаче о студентах в ОП посте. Так как не хочется по второму разу их пересказывать.
У тебя есть папка public - почему тогда index.php вне нее? Ты по моему не понял идею, там идея в том, что public должна быть корневой папкой веб-сервера, и код лежит снаружи нее.
Папка vendor не должна быть в репозитории (ее надо добавить в гитигнор), зато в него стоит положить composer.lock.
https://github.com/grigoryMovchan/AphorismCMS/blob/master/db.sql#L25
> ENGINE=MyISAM
Почитай сравнение движков MyISAM и InnoDB
> `password_user` varchar(255) NOT NULL,
Тут нужен комментарий, что там хранится. Надеюсь, соленый хеш пароля, а не сам пароль в открытом виде?
В базе нужно проставить внешние ключи.
https://github.com/grigoryMovchan/AphorismCMS/blob/master/app/core/Route.php#L69
Тут непонимание протокола HTTP. Нельзя отдавать заголовок Location при коде 4xx. Он используется с кодом 3xx в тех случаях, когда страница переехала на другой адрес. Если страница не найдена, надо отдавать код 404. Почитай назначение кодов состояния HTTP.
Класс Route должен правильно называться FrontController.
Используемый подход к роутингу плох тем, что для одной страницы существует много URL, например /controller, /CONTROLLER, /controller/index/1/2/3, /controller/index/4/5/6 - при ошибке в URL ты можешь не заметить что ошибся, и на индексации поисковиками это плохо скажется.
Убрать query string из URL лучше с помощью parse_url().
> $url = 'Location: /' . strtolower($controllerName) . '/';
> header($url);
Тут после отдачи Location скрипт продолжает выполняться.
Также, код в Route->start() плохочитаемый, попробуй сам прочесть. Стена кода, ты бы хоть на функции ее разбил.
https://github.com/grigoryMovchan/AphorismCMS/blob/master/app/core/Request.php#L45
> public function getFeedbackString($separator = "<br>")
Класс Request не должен отвечать за вывод информации и ее оформление, генерацию HTML кода.
https://github.com/grigoryMovchan/AphorismCMS/blob/master/app/core/View.php#L8
> @param str
> @param arr
В phpdoc нет типов str и arr: https://phpdoc.org/docs/latest/guides/types.html
> public function generate($content_view, $template_view, $data = null, $error = null)
Не очень понятно, почему для $error сделан отдельный аргумент, а все остальное передается в $data.
https://github.com/grigoryMovchan/AphorismCMS/blob/master/app/core/Model.php
Этот класс выглядит сомнительно (например не очень понятно что такое в твоем понимании Model, для чего этот класс предназначен. Надо добавить комментарий перед ним). ensure() там явно не к месту, так как эта функция может быть полезна не только в модели и ее лучше сделать отдельным статическим методов в отдельном классе.
Не соблюдается PSR-4. Например неймспейс имеет вид namespace Application\Core, а папка называется core, с маленькой буквы.
https://github.com/grigoryMovchan/AphorismCMS/blob/master/app/configs/app_example.ini
Плохой пример так как не содержит пояснений и непонятно зачем там 2 секции с БД.
https://github.com/grigoryMovchan/AphorismCMS/blob/master/app/controllers/QuotesController.php#L16
> $this->data['thisPage'][0] = 'quotes';
Тут по моему ты добавляешь элемент 0 в несуществующий массив. Зачем так запутывать код?
> $this->quotes = new QuotesModel($this->request);
Непонятно зачем Модели нужен request. В MVC модели он не нужен.
https://github.com/grigoryMovchan/AphorismCMS/blob/master/app/models/QuotesModel.php#L22
> $this->dbh = new MysqlModel(ConfigModel::UNMARRIED);
Почитай мой урок про DI. https://github.com/codedokode/pasta/blob/master/arch/di.md
https://github.com/grigoryMovchan/AphorismCMS/blob/master/app/models/QuotesModel.php#L207
тут видно полное непонимание идеи MVC. Идея ведь там отделить логику приложения (модель) от взаимодействия с внешним миром (контроллер).
У тебя получилась плохая функция getQuote(). Вот допустим я хочу получить цитату с id = 7. Как ее получить, если в функцию нельзя передать id?
Получить след/пред цитату проще через WHERE id > ? ORDER BY id LIMIT 1
Также, подход что при ошибке поиска возвращается имитация цитаты, тоже плохой. Ведь при твоем подходе непонятно как определить, что цитата не найдена. Да и при ненайденной цитате логичнее отдавать 404, а не притворяться что такая страница есть.
Выборка случайного id неэффективно сделана. Погугли про оптимизацию выборки случайной записи.
https://github.com/grigoryMovchan/AphorismCMS/blob/master/app/models/MysqlModel.php
Тут непонятно на каком основании MysqlModel наследуется от Model (у них ведь ничего общего нет) и почему она вообще назвается Model. тебе надо определиться для начала, что ты называешь моделью.
https://github.com/grigoryMovchan/AphorismCMS/blob/master/app/models/MysqlModel.php#L50
Тут неудачный подход, ты зря пытаешься объединить разные функции (fetchAll, fetch) в одну - это только создает неудобства. Ну например, из-за этого функция возвращает разные типы данных, а не один определенный. Ну и непонятно, зачем это сделано, такое ощущение что ты себе жизнь усложнить пытаешься.
> без понятия зачем тут нужен новый уровень абстракции
Если без понятия, то не надо делать. Ты должен понимать каждую строчку кода. А так ты просто копируешь то, что увидел где-то, не понимая. Это какой-то культ карго. Зачем? Если ты хочешь произвести впечатление на собеседовании своим кодом, то любой опытный программист легко тебя раскусит.
https://github.com/grigoryMovchan/AphorismCMS/blob/master/app/models/AuthModel.php#L66
Тут зачем htmlspecialchars? Это же не шаблон.
Вообще AuthModel требует упорядочивания, там как-то все перемешано. ну например, операции с БД можно из него убрать в другой класс.
Функции и переменные надо назвыать единообразно, а не одну с подчеркиванием, а другую кемел кейсом.
Дальше не смотрел.
По дизайну - я не дизайнер, но кое-что бросается в глаза. У тебя на странице с цитатой самый "тяжелый" элемент, на который обращаешь внимание в первую очередь - это кнопки. Мало того, что они залиты, так еще и ярко-белым цветом, который ярче, чем текст. Но ведь главный-то элемент наверно не они, а цитата. Я бы советовал попробовать поиграть с кнопками - сделать их менее яркими или убрать белую заливку - и посмотреть что получится. Также, плашка слева от цитаты тоже выглядит тяжеловатой, может быть стоит попробовать сделать ее побледнее?
Непонятно, что обозначает третья кнопка с иконкой комментария (вторая - это случайная цитата или "поделиться"? Тоже не очень понятно).
В форме ошибки нечитаемы, белый текст на светлом фоне.
> Шаблон не осилил, верстка поехала, не смог в CSS.
Пройди наши задачи на HTML/CSS из ОП поста и наверно тогда осилишь. Также, есть заблуждение, что использование бустрапа избавляет от необходимости учить CSS (как и использование ORM избавляет от необходимости учить SQL).
Потому что в PHP применение ++ к строке с буквами вызвает изменение букв (ставится следующая в алфавите буква вместо последней). Описано тут: http://php.net/manual/ru/language.operators.increment.php
>>988817
Можно перезагружать страницу, почему нет? Ну и роботам, поисковикам с такими сайтами работать проще.
>>988745
Вряд ли тут дело в Windows.
>Также, в простых случаях есть вариант поллинга - вместо возни с вебсокетами можно просто отправлять запросы на сервер раз в N секунд и спрашивать, не изменились ли данные
Он оказывается менее эффективным, чем сокеты для тех же целей. Для таких простых случаев реализация простая и там и там.
>пишет советы по принципу "слышал звон"
А вот тут иди нахуй. Я больше года работаю над распределенными реалтаймовыми сервисами, заебался как черт, потому и отговариваю понемногу вообще от затеи этой, если ему не горит.
Добро пожаловать в наш уютный тред. Тут мы изучаем язык PHP (а также JS/CSS/HTML/SQL), решаем задачки и даже делаем простые сайты! Зачем? Кто-то хочет научиться программировать, кто-то - делать сайты, кто-то - просто размять мозги и заняться чем-то полезным.
Пожалуйста, пишите один большой пост вместо нескольких маленьких и не флудите не по теме. ОПу ведь все это читать придется.
Это тред для начинающих. Не написал за свою жизнь ни одной программы и имеешь тройку по математике? Ты наш человек.
Устанавливать пока что ничего не требуется, разве что редактор кода вроде Sublime Text 3, Notepad++, Visual Studio Code, Netbeans PHP или PhpStorm (с ним будет удобнее).
Предыдущий тред был тут: >>966608 (OP) ( http://arhivach.org/thread/254710/ )
Что самое главное для программиста? Умение аккуратно оформлять код (читай второй пост, прежде чем писать код).
Правила: ведем себя воспитанно, помогаем новичкам, постим ссылки на решения задачек, ОП их проверяет и дает советы и замечания. ОП заходит редко, где-то раз в 2-3 дня, у него мало времени, не жди его, решай задачки дальше. ОП отвечает на все вопросы по его задачкам и учебнику, а вот насчет каких-то других вещей - только если останется время. Но в треде немало анонимных экспертов разного уровня, так что вряд ли вопрос останется без ответа.
У нас есть уроки по основам PHP, они собраны и выложены по адресу http://archive-ipq-co.narod.ru/ Это учебник для изучающих с нуля, то есть если ты вообще ничего не знаешь, то надо начать с него. Он простой и понятный (по крайней мере в начале). Там есть задачи, их надо решать обязательно (чтобы стать программистом, надо писать код — иначе никак). Пости ссылки на решения в тред, мы их проверим, напишем замечания и дадим советы по улучшению.
Если не знаешь как решать, запости код, напиши в каком месте остановился и попроси подсказку.
Ты прошел весь учебник? Молодец, но это были лишь основы языка PHP, этого недостаточно. Вот что в идеале надо изучить еще: ООП, как работает веб-сервер, HTML/CSS, SQL, PDO, работа с таблицами в БД, работа с формами, MVC, git, composer, JS, фреймворки, автоматизированное тестирование.
Надо переходить к более серьезным задачкам, которые научат тебя всему этому.
- для начала прочти урок https://github.com/codedokode/pasta/blob/master/soft/web-server.md
- установи Апач + PHP (советы выше и ниже) и читай туториал http://php.net/manual/ru/tutorial.php
- Учи HTML/CSS и SQL, PDO, хотя бы основы
- Далее простая, но полезная задача сделать список студентов, в ней много полезных советов: https://github.com/codedokode/pasta/blob/master/student-list.md
- Более сложная задача сделать файлообменник на микрофреймворке Slim: https://gist.github.com/codedokode/9424217
- Еще более сложная и долгая задача на Yii/Symfony: https://gist.github.com/codedokode/8733007
- После нее можно изучать автоматизированное тестирование https://gist.github.com/codedokode/a455bde7d0748c0a351a
- Если ты все решил, переходи к Symfony 2/Doctrine 2
- Почитать про паттерны http://designpatternsphp.readthedocs.org/ru/latest/README.html (если ты не изучил ни одного фреймворка, то это будет рановато), тут с примерами кода http://designpatternsphp.readthedocs.org/ru/latest/README.html . Имей в виду что без примеров использования их учить бесполезно - не поймешь, хочешь увидеть примеры использования паттернов - ковыряй исходники Симфони, например Symfony Forms. Не заучивай паттерны - смотри код и думай, зачем тут они использованы.
Чтобы делать эти задания, тебе надо установить Апач + PHP (можно заодно сразу и MySQL) на компьютер. Вот полезные инструкции:
https://github.com/codedokode/pasta/blob/master/soft/php-install.md
https://github.com/codedokode/pasta/blob/master/soft/apache-install.md
Может тебе понадобится пользоваться командной строкой, вот гайд https://github.com/codedokode/pasta/blob/master/soft/cli.md
Решения задач лучше показать мне, особенно на ООП,так как сам ты вряд ли увидишь все ошибки. Пости свой код на гитхаб и вкидывай ссылку в тред по мере решения. Я прокомментирую и укажу на ошибки.
Также, у нас есть задачи которые позволят тебе изучить или подтянуть до нормального уровня знания JS/HTML/CSS/SQL. Решай их параллельно с задачами выше.
- HTML/CSS: https://github.com/codedokode/pasta/blob/master/html/html.md
- JS: https://gist.github.com/codedokode/ce30e7a036f18f416ae0
- SPA (сложно): https://github.com/codedokode/pasta/blob/master/js/spa.md
- Проверялка решений на JS: http://dkab.github.io/jasmine-tests/
- MySQL: https://github.com/codedokode/pasta/blob/master/db/databases.md
Что почитать
- Мануал по PHP — http://www.php.net/manual/ru/langref.php
- Сайт phptherightway (перевод на русский: http://getjump.me/ru-php-the-right-way/ )
- По PHP: Профессиональное программирование на PHP Джордж Шлосснейгл
- По PHP: Мэтт Зандстра — PHP: Объекты, шаблоны, методики программирования
- JS: learn.javascript.ru
- Про Git: https://git-scm.com/book/ru/v1
Оформляй код аккуратно!!! — например пропусти через phpformatter.com . Также, если ты пользуешься IDE вроде PhpStorm, Netbeans, Eclipse, то в них эта опция встроена, подробнее: https://gist.github.com/codedokode/8759492
У ОПа нет аккаунтов и групп вконтакте, в фейсбуке, в твиттере, все "пхп-треды" там поддельные.
Платиновые вопросы
- Почему PHP? Потому что фейсбук и википедия на нем написаны, и вакансий море, и учить легко.
- Сайт опять упал!!!!! — Не паникуй, а открой http://rghost.ru/6bfCY9lfl и получи личную немного устаревшую оффлайновую копию сайта (можно читать хоть на андроиде без интернета)
- Что надо знать чтобы найти работу - разработчику: PHP, SQL, HTML/CSS, JS, ООП, Git, композер, MVC, фреймворк. Верстальщику - HTML/CSS, JS, jQuery
- Можно подробнее про поиск работы, собеседования - нет, ОП писать не будет, но может кто из анонов захочет рассказать. Поищите тред перезвонивших, а также раздел /wrk/.
- Сколько времени надо изучать все это? - все зависит от тебя, но не меньше 6-8 месяцев
- Посоветуйте редактор кода - Sublime Text 3, Notepad++, PhpStorm
- Нужен ли ООП, фреймворки, MVC, git, composer? — Да, однозначно. Посмотри любую вакансию.
- Что самое главное для программиста? Умение аккуратно оформлять код.
- ОП, сделай за меня мою работу или домашнее задание? — Это конечно, хорошая идея, но нет.
- Подскажи сайты для поиска работы, я не умею гуглить? — hh.ru, geekjob.ru, moikrug.ru (склеен с brainstorage.me), fl.ru, upwork.com (бывший одеск). Имей в виду, что кроме фриланса есть еще постоянная удаленная работа (remote job) когда тебе не надо тратить время на поиск заказов и переговоры с неадекватными заказчиками.
Добро пожаловать в наш уютный тред. Тут мы изучаем язык PHP (а также JS/CSS/HTML/SQL), решаем задачки и даже делаем простые сайты! Зачем? Кто-то хочет научиться программировать, кто-то - делать сайты, кто-то - просто размять мозги и заняться чем-то полезным.
Пожалуйста, пишите один большой пост вместо нескольких маленьких и не флудите не по теме. ОПу ведь все это читать придется.
Это тред для начинающих. Не написал за свою жизнь ни одной программы и имеешь тройку по математике? Ты наш человек.
Устанавливать пока что ничего не требуется, разве что редактор кода вроде Sublime Text 3, Notepad++, Visual Studio Code, Netbeans PHP или PhpStorm (с ним будет удобнее).
Предыдущий тред был тут: >>966608 (OP) ( http://arhivach.org/thread/254710/ )
Что самое главное для программиста? Умение аккуратно оформлять код (читай второй пост, прежде чем писать код).
Правила: ведем себя воспитанно, помогаем новичкам, постим ссылки на решения задачек, ОП их проверяет и дает советы и замечания. ОП заходит редко, где-то раз в 2-3 дня, у него мало времени, не жди его, решай задачки дальше. ОП отвечает на все вопросы по его задачкам и учебнику, а вот насчет каких-то других вещей - только если останется время. Но в треде немало анонимных экспертов разного уровня, так что вряд ли вопрос останется без ответа.
У нас есть уроки по основам PHP, они собраны и выложены по адресу http://archive-ipq-co.narod.ru/ Это учебник для изучающих с нуля, то есть если ты вообще ничего не знаешь, то надо начать с него. Он простой и понятный (по крайней мере в начале). Там есть задачи, их надо решать обязательно (чтобы стать программистом, надо писать код — иначе никак). Пости ссылки на решения в тред, мы их проверим, напишем замечания и дадим советы по улучшению.
Если не знаешь как решать, запости код, напиши в каком месте остановился и попроси подсказку.
Ты прошел весь учебник? Молодец, но это были лишь основы языка PHP, этого недостаточно. Вот что в идеале надо изучить еще: ООП, как работает веб-сервер, HTML/CSS, SQL, PDO, работа с таблицами в БД, работа с формами, MVC, git, composer, JS, фреймворки, автоматизированное тестирование.
Надо переходить к более серьезным задачкам, которые научат тебя всему этому.
- для начала прочти урок https://github.com/codedokode/pasta/blob/master/soft/web-server.md
- установи Апач + PHP (советы выше и ниже) и читай туториал http://php.net/manual/ru/tutorial.php
- Учи HTML/CSS и SQL, PDO, хотя бы основы
- Далее простая, но полезная задача сделать список студентов, в ней много полезных советов: https://github.com/codedokode/pasta/blob/master/student-list.md
- Более сложная задача сделать файлообменник на микрофреймворке Slim: https://gist.github.com/codedokode/9424217
- Еще более сложная и долгая задача на Yii/Symfony: https://gist.github.com/codedokode/8733007
- После нее можно изучать автоматизированное тестирование https://gist.github.com/codedokode/a455bde7d0748c0a351a
- Если ты все решил, переходи к Symfony 2/Doctrine 2
- Почитать про паттерны http://designpatternsphp.readthedocs.org/ru/latest/README.html (если ты не изучил ни одного фреймворка, то это будет рановато), тут с примерами кода http://designpatternsphp.readthedocs.org/ru/latest/README.html . Имей в виду что без примеров использования их учить бесполезно - не поймешь, хочешь увидеть примеры использования паттернов - ковыряй исходники Симфони, например Symfony Forms. Не заучивай паттерны - смотри код и думай, зачем тут они использованы.
Чтобы делать эти задания, тебе надо установить Апач + PHP (можно заодно сразу и MySQL) на компьютер. Вот полезные инструкции:
https://github.com/codedokode/pasta/blob/master/soft/php-install.md
https://github.com/codedokode/pasta/blob/master/soft/apache-install.md
Может тебе понадобится пользоваться командной строкой, вот гайд https://github.com/codedokode/pasta/blob/master/soft/cli.md
Решения задач лучше показать мне, особенно на ООП,так как сам ты вряд ли увидишь все ошибки. Пости свой код на гитхаб и вкидывай ссылку в тред по мере решения. Я прокомментирую и укажу на ошибки.
Также, у нас есть задачи которые позволят тебе изучить или подтянуть до нормального уровня знания JS/HTML/CSS/SQL. Решай их параллельно с задачами выше.
- HTML/CSS: https://github.com/codedokode/pasta/blob/master/html/html.md
- JS: https://gist.github.com/codedokode/ce30e7a036f18f416ae0
- SPA (сложно): https://github.com/codedokode/pasta/blob/master/js/spa.md
- Проверялка решений на JS: http://dkab.github.io/jasmine-tests/
- MySQL: https://github.com/codedokode/pasta/blob/master/db/databases.md
Что почитать
- Мануал по PHP — http://www.php.net/manual/ru/langref.php
- Сайт phptherightway (перевод на русский: http://getjump.me/ru-php-the-right-way/ )
- По PHP: Профессиональное программирование на PHP Джордж Шлосснейгл
- По PHP: Мэтт Зандстра — PHP: Объекты, шаблоны, методики программирования
- JS: learn.javascript.ru
- Про Git: https://git-scm.com/book/ru/v1
Оформляй код аккуратно!!! — например пропусти через phpformatter.com . Также, если ты пользуешься IDE вроде PhpStorm, Netbeans, Eclipse, то в них эта опция встроена, подробнее: https://gist.github.com/codedokode/8759492
У ОПа нет аккаунтов и групп вконтакте, в фейсбуке, в твиттере, все "пхп-треды" там поддельные.
Платиновые вопросы
- Почему PHP? Потому что фейсбук и википедия на нем написаны, и вакансий море, и учить легко.
- Сайт опять упал!!!!! — Не паникуй, а открой http://rghost.ru/6bfCY9lfl и получи личную немного устаревшую оффлайновую копию сайта (можно читать хоть на андроиде без интернета)
- Что надо знать чтобы найти работу - разработчику: PHP, SQL, HTML/CSS, JS, ООП, Git, композер, MVC, фреймворк. Верстальщику - HTML/CSS, JS, jQuery
- Можно подробнее про поиск работы, собеседования - нет, ОП писать не будет, но может кто из анонов захочет рассказать. Поищите тред перезвонивших, а также раздел /wrk/.
- Сколько времени надо изучать все это? - все зависит от тебя, но не меньше 6-8 месяцев
- Посоветуйте редактор кода - Sublime Text 3, Notepad++, PhpStorm
- Нужен ли ООП, фреймворки, MVC, git, composer? — Да, однозначно. Посмотри любую вакансию.
- Что самое главное для программиста? Умение аккуратно оформлять код.
- ОП, сделай за меня мою работу или домашнее задание? — Это конечно, хорошая идея, но нет.
- Подскажи сайты для поиска работы, я не умею гуглить? — hh.ru, geekjob.ru, moikrug.ru (склеен с brainstorage.me), fl.ru, upwork.com (бывший одеск). Имей в виду, что кроме фриланса есть еще постоянная удаленная работа (remote job) когда тебе не надо тратить время на поиск заказов и переговоры с неадекватными заказчиками.
Мейлач лежит? Есть запасной тред:
-----
Кому я не ответил - напомните о себе в новом треде. enotocode, твой сегодняшний пост вижу, можно не напоминать.
Спасибо за понятный и доходчивый ответ по индексам. А можно ещё задачу, где нужно подумать над проставлением индексов? Ты вроде раньше кому-то предлагал БД для борды проектировать, но я, к сожалению, не смог этот пост найти c полным текстом задачи.
Засунул Собакину в $_SESSIONS['last_name'], достал Собакину на другой странице $last_name = $_SESSIONS['last_name'].
И ПОЛУЧИЛ ВОПРОСИКИ)))
Я просто за сегодня порвался с таких нелепых проблем.
Кругом выставил header("Content-Type: text/html; charset=utf-8"); Даже маме своей позонил и сказал: "ХЕАДЕР ЧАРСЕТ УТФ-8".
Скачал нотепад, проверил BOM, НИГДЕ НЕТ ЕГО, НИ НА ОДНОЙ БЛЯДСКОЙ СТРАНИЦЕ. Пхп-сторм не даёт удалить BOM, потому что его НЕТ.
СТАРТ
<?php
session_start();
В самой первой строке, самого первого файла, фронт-котроллер, что бы ты не делал - всё начинается с него.
Потушите мою Собакину.
Как достать Сабакину из массива Сессии?
>>989673
Этот тред закрыт. Переходите в новый тред >>988868 (OP)
Здесь на вопросы никто отвечать больше не будет.
Это копия, сохраненная 24 мая 2017 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.