Этого треда уже нет.
Это копия, сохраненная 6 марта 2018 года.

Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее

Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
Клуб изучающих PHP и webdev #98 1118555 В конец треда | Веб
Добро пожаловать. Тут мы изучаем язык PHP (а также JS/CSS/HTML/SQL), решаем задачки и даже делаем простые сайты! Зачем? Кто-то хочет сделать себе блог, кто-то приобрести новую профессию, кому-то просто нечего делать.

Пожалуйста, пишите один большой пост вместо нескольких маленьких и не флудите не по теме.

Это тред для начинающих. Не написал за свою жизнь ни одной программы и имеешь тройку по математике? Ты наш человек.

Предыдущий тред был тут: >>1109863 (OP). Остальные треды есть в архиве: https://phpclub.tech/ или ищутся в гугле по словам "клуб изучающих php" и в архиваче.

Мейлач лежит? Есть запасной тред на доброчане: /s/res/23225.xhtml#i46467

Что самое главное для программиста? Умение аккуратно оформлять код (как, написано во втором посте).

Правила: ведем себя воспитанно, помогаем новичкам, читаем учебники, решаем задачки, постим ссылки на решения, ОП их проверяет и дает советы и замечания. ОП заходит редко, где-то раз в 2-3 дня, у него мало времени, не жди его, решай задачки дальше. ОП отвечает на все вопросы по его задачкам и учебнику, а вот насчет каких-то других вещей - только если останется время. Но в треде немало анонимных экспертов разного уровня, так что вряд ли вопрос останется без ответа.

С чего начать

У нас есть свои уроки по основам PHP, они собраны и выложены по адресу http://archive-ipq-co.narod.ru/ Это учебник для изучающих с нуля, то есть если ты вообще ничего не знаешь, то можно начать с него. Он простой и понятный. Там есть задачи, их нужно решать (чтобы стать программистом, надо писать код — иначе никак). Пости ссылки на решения в тред, мы их проверим, напишем замечания и дадим советы по улучшению. С другой стороны, если этот учебник тебе не нравится, можно читать любой другой. Или официальный мануал. Или все сразу.

Устанавливать пока что ничего не требуется, разве что редактор кода вроде Sublime Text 3, Notepad++, Visual Studio Code, Netbeans PHP или PhpStorm (с ним будет удобнее).

Если не знаешь как решать, запости код, напиши в каком месте остановился и попроси подсказку.

Ты прошел весь учебник? Молодец, но это были лишь основы языка 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 3/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. У нас в треде были люди, которые практически с нуля учились и смогли найти работу.
- Что будут спрашивать на собеседовании если 0 опыта - гонять по теории, по официальному мануалу PHP, давать дурацкие задачки на переворачивание строк, гонять по SQL (транзакции, внешние ключи, напиши запрос), по JS (как сделать анимацию при нажатии кнопки), ну погугли, не ленись
- Можно подробнее про поиск работы, собеседования - нет, ОП писать не будет, но может кто из анонов захочет рассказать. Поищите тред перезвонивших, а также раздел /wrk/
- Сколько времени надо изучать все это? - все зависит от тебя, но не меньше 6-8 месяцев
- Нужен ли ООП, фреймворки, MVC, git, composer? — Да, однозначно. Посмотри любую вакансию.
grammar-nazi.png56 Кб, 500x644
2 1118556
Код нужно писать не как попало, а аккуратно и по правилам. Почему? Потому, что на неакуратно написанный код не хочется даже смотреть.

Если тебе лень выравнивать код руками, закачай его на 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
3 1118558
Напомню себе проверить:

>>1117075 >>1117974 7 янв https://github.com/moabit/student-list
>>1118051 10 янв https://github.com/TheSidSpears/testhub/

Уже проверил:

- https://github.com/pmaprog/codedokode-html - тут >>1117863
- https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2 - тут >>1118527 >>1117864

Напомню, что стоит не откладывать на потом изучение английского. Читать можно news.ycombinator.com - это что-то вроде их хабра.

Если я кому-то не ответил в прошлом треде, напомните о себе тут.
4 1118564
Сап анончики. У меня интересная задачка. В прошлом треде я уже спрашивал но тут мне понадобилось кое что уточнить.

Суть такова.
Допустим есть карта (просто jpg изображение на котором карта ).
Нужно поверх этого изображения разместить ещё 40-50 мелких изображений (20*20px).
При этом если первое изображение карта занимает всю страницу, то другие изображения будут мелкими типа маркеров на гуглмапсе.
При это каждое из 40 мелких должно иметь свои координаты.
В прошлом треде мне помогли с координатами z index и CSS скинув очень годные ссылки.

Эти
https://www.w3schools.com/cssref/pr_pos_z-index.asp
https://www.w3schools.com/css/css_positioning.asp


Но теперь вопрос как будет лучше это всё размещать так чтобы небыло говнокода. И при этом работало.
Например есть карты с 59 обьектами (или 23, или вовсе 2 чтобы вы поняли). Я скриптом прохожусь чтобы узнать количество обьектов, потом формирую страницу, и сразу генерирую CSS встроенный в страницу чтобы создать 59 обьектов и сразу дать им координаты? Или можно это всё сделать по другому, например через JS?
5 1118578
>>1118287
Я не смог применить эти функции, у меня с ними не работает и я так до конца и не понял, каким образом их использовать.
>>1118475

>Ты каждый раз заполняешь строку в ручную, а нужно делать это программно, чтобы программа работала с заведомо неизвестным количеством массивов и элементов


Ну эту проблему я тоже не смог решить, до оепратора точка не додумался.
>>1118548

>// Идем по массиву массивов слов и на каждом шаге выбираем 1 слово


foreach ($allWords as $variants) {
var_dump($variants);
}
Но как он будет случайные слова подбирать? Он же их просто перебирает.
6 1118580
Свежий хлеб! Опчик, дорогой, делай так почаще
7 1118581
>>18578
Зарандомь $variants и выводи в нужном тебе порядке результат
Screenshot564.png8 Кб, 550x258
8 1118584
Такие дела, пацаны. Давно стоял апачи для хтмл, работает исправно. А вот при пхп он тупо выдает мне код, а не выполняет его. Как фиксить?
9 1118585
>>18584
Например запускать через браузер. А не просто открывать PHP файл браузером.
10 1118586
>>18585
Аналогично. Через разные браузеры попробовал даже.
12 1118611
>>18564
Вопрос, как ты хранишь эти изображения и их координаты?

Думаю, лучше делать это через js, можно с использованием canvas. https://www.html5canvastutorials.com/tutorials/html5-canvas-image-loader/

Для твоей задачи на js есть много библиотек, например https://github.com/d3/d3/wiki/Gallery
13 1118617
Это снова я со своим массивом, спасибо анончикам за их терпение и помощь, уменьшил количество кода, запилив все циклом с условиями.
https://ideone.com/YMAqiv
Ниже функции пока не пробовал применить, ща буду макакить

>foreach ($allWords as $variants) {


var_dump($variants);
14 1118618
>>18617
Дополню, что по условиям должно быть

>words1, words2, word3


>words1, words2, words3


>words4, words5


то есть четко поставлены условия, из каких массивов должны быть взяты рандомные слова.
15 1118638
Анон, как вывести ссылкой?

echo $second[$n],"-",$first[$k]," ", <a href='"https://example.ru/?callback=search&country={$did}&city={$id}\n"'></a>;

не работает.
16 1118645
>>18578

>Я не смог применить эти функции, у меня с ними не работает и я так до конца и не понял, каким образом их использовать.



вместо
$element = count($words['word1']);
$r = mt_rand(0,($element - 1));
$b = $words['word1'][$r];
echo "$b ";

можно написать
echo $words['word'1][array_rand($words['word'1])] . ' ';
17 1118655
Как вкатится в bootstrap и стоит ли?
18 1118701
>>18655

Прочитать документацию. Вроде даже русский перевод доступен.

Ну и конечно, надо знать HTML и CSS.
19 1118707
>>18655

Правда, я попробовал почитать, русский перевод очень плохой, и сделан явно через Гугл Translate (и это не мешает сайту быть в топе выдачи). Так что по возможности лучше читать исходную документацию на английском.
20 1118712
Никогда не сталкивался с докером, но сейчас придется. Вопрос у меня вот в чём: достаточно ли одного докера или нужно будет ещё что-то для того, чтобы на чистой убунте создать несколько виртуальных машин на борту, каждая из которых будет загружать определенный контейнер. (хочу потестировать горизонтальное масштабирование)
21 1118759
Возможно очень тупой вопрос: в чем разница между mysql и mariadb?
22 1118795
>>18759
вопрос сам по себе не тупой, но, мне кажется, нет смысла задавать тут вопросы, на которые можно найти ответ в первой строчке гугла

https://mariadb.com/kb/en/library/mariadb-vs-mysql-features/
23 1118828
Как растянуть контейнер по картинке?
24 1118830
>>18586
Ты хоть в конфигурации пхп то указал?
25 1118843
Имеются более менее знания python/django, знаю что такое ООП и нахуя оно, БД так сяк.
Вопрос стоит ли вкатиться в php? (в основном из-за большего количества как вакансий, так и заказов на фрилансе)
И смогу ли уложиться в 3 месяца (начинаю прям щас), если буду ебашить прерываясь только на поспать и посрать?
26 1118846
https://ideone.com/goHGCT
что думаете по поводу такого решения? в задании говорилось про цикл, но я не понял, как его там задействовать
27 1118851
https://gist.github.com/codedokode/9424217
А можно эту задачку на laravel запилить?
28 1118864
Начал вкатываться. Писал пару пробных чятиков и гостевуху, теперь хочу поближе познакомиться с основами, скачал какое-то приложение на телефон, вникаю.
Язык не нравится. Как сишника, отталкивает буквально всё. Но учу. Зачем? Потому что простой. Потому что хочу понимать различные технологии, а не говноедствовать, задрачивая на один язык.
29 1118924
>>18611

>Вопрос, как ты хранишь эти изображения и их координаты?


Изображения - это просто jpg. Координаты в базе данных, 2 поля x и y.
30 1118930
>>18830
Нет. Я не знаю, как это делается.
31 1118954
Есть код https://ideone.com/x30EQK

Логика такова: я получаю массив таблиц с результатами sql-запросов.
Из этого надо сделать массив из значений, находящихся в таблицах.

Можно ли написать этот код без трех циклов, вложенных друг в друга?
32 1118955
>>18954
Сразу скажу: 2 скобки просто не добавил в код, но так они у меня есть и все работает.
33 1118958
>>18712
Насколько я понял, докер разворачивает каждый процесс как отдельный контейнер, и так как я думал: nginx + php-fpm + mysql в одном контейнере не выйдет, или я ошибаюсь? Или посоветуйте что-то для быстрого деплоя/развертывания одного проекта на N-нод
34 1118981
>>18608
Да

>>18617
http://archive-ipq-co.narod.ru/l1/strings.html

>Подсказка: так как первая и вторая строка формируются по одинаковому принципу, то незачем копировать код 2 раза, можно использовать цикл из 2 шагов.


Тебе просто нужно выполнить два раза циклом склеивоние 1-ых по 3-их слов и добавить перенос строки, и затем отдельно вначале добавить "Я", и склить 4-ые и 5-ые

>>18618

>Подсказка: можно упростить программу, сделав что-то вроде шаблона для генерации стиха на основе массива. В каждый элемент массива мы кладем массив вариантов слова или строки, из которого надо сделать выбор: [$word1, $word2, $word3, ["\n"], ...]. Мы добавляем массив с "\n", чтобы в нужном месте вывелся перевод строки. Остается только пройти по массиву циклом и сгенерировать стих..


В этом случае можно будет воспользоваться foreach

>>18638
https://3v4l.org/Qk3jJ

>Parse error: syntax error, unexpected '<' in /in/Qk3jJ on line 3



Нужно заключить её в ковычки

>>18846
Другое дело

>в задании говорилось про цикл, но я не понял, как его там задействовать


Он нужен чтобы не повторять одни и те же строки дважды

>$piece1 = array_rand($word1);


>$piece2 = array_rand($word2);


>$piece3 = array_rand($word3);



//тут тоже

>$piece4 = array_rand($word1);


>$piece5 = array_rand($word2);


>$piece6 = array_rand($word3);



>$pieceOfPoem1 = $word1[$piece1] . $word2[$piece2] . $word3[$piece3];


>$pieceOfPoem2 = $word1[$piece4] . $word2[$piece5] . $word3[$piece6];



Так же, код можно упростить $word1[array_rand($word1)]

У тебя проблемы с циклами и массивами - изучи уроки по ним ещё раз

>>18954
Скинь массив результата таблицы
34 1118981
>>18608
Да

>>18617
http://archive-ipq-co.narod.ru/l1/strings.html

>Подсказка: так как первая и вторая строка формируются по одинаковому принципу, то незачем копировать код 2 раза, можно использовать цикл из 2 шагов.


Тебе просто нужно выполнить два раза циклом склеивоние 1-ых по 3-их слов и добавить перенос строки, и затем отдельно вначале добавить "Я", и склить 4-ые и 5-ые

>>18618

>Подсказка: можно упростить программу, сделав что-то вроде шаблона для генерации стиха на основе массива. В каждый элемент массива мы кладем массив вариантов слова или строки, из которого надо сделать выбор: [$word1, $word2, $word3, ["\n"], ...]. Мы добавляем массив с "\n", чтобы в нужном месте вывелся перевод строки. Остается только пройти по массиву циклом и сгенерировать стих..


В этом случае можно будет воспользоваться foreach

>>18638
https://3v4l.org/Qk3jJ

>Parse error: syntax error, unexpected '<' in /in/Qk3jJ on line 3



Нужно заключить её в ковычки

>>18846
Другое дело

>в задании говорилось про цикл, но я не понял, как его там задействовать


Он нужен чтобы не повторять одни и те же строки дважды

>$piece1 = array_rand($word1);


>$piece2 = array_rand($word2);


>$piece3 = array_rand($word3);



//тут тоже

>$piece4 = array_rand($word1);


>$piece5 = array_rand($word2);


>$piece6 = array_rand($word3);



>$pieceOfPoem1 = $word1[$piece1] . $word2[$piece2] . $word3[$piece3];


>$pieceOfPoem2 = $word1[$piece4] . $word2[$piece5] . $word3[$piece6];



Так же, код можно упростить $word1[array_rand($word1)]

У тебя проблемы с циклами и массивами - изучи уроки по ним ещё раз

>>18954
Скинь массив результата таблицы
35 1118998
>>18843
если видел большие проекты, то хватит
36 1119002
>>18584 бамп.
Скажите, как делать >>18830 пожалуйста.
37 1119009
>>18584
>>19002
Тебе нужно запустить веб-сервер

У PHP есть собственный встроенный

https://secure.php.net/manual/ru/features.commandline.webserver.php

Так же, у нас есть урок по установке и настройке PHP и сервера

https://github.com/codedokode/pasta/blob/master/soft/php-install.md
https://github.com/codedokode/pasta/blob/master/soft/web-server.md
38 1119016
>>19009
Благодарю, добра тебе.
39 1119098
>>18584

Чтобы Апач выполнял PHP код, а не отдавал, нужно:

- установить PHP на компьютер
- в конфиге Апача подгрузить модуль mod_php и прописать, что PHP файлы должен обрабатывать он

Директивы для конфига Апача можно найти тут http://php.net/manual/ru/install.unix.apache2.php

Если ты запускаешь простые скрипты, то тебе может быть проще просто использовать встроенный в PHP веб-сервер как описано по ссылке, которую дал анон выше.
40 1119100
>>18584

После правки конфига не забудь перезапустить Апач.
41 1119115
пацаны, подскажите лоху в верстке.

есть код
<div class="sidebar-module">
<ol class="list-unstyled">
<li><a href="#">October 2013</a></li>
</ol>
</div>

я допустим хочу сделать стайл для всех ссылок, которые лежат в диве с классом sidebar-module

пишу в style.css
a.sidebar {color: #555;}

но нихуя не работает. подскажите, что в стайл прописать
42 1119122
>>19115
.sidebar-module a {color: #555;}

Гугли наследование css селекторов, поймёшь всё очень быстро. Если коротко, то ты даёшь стиль элементу а внутри класса sidebar-module, а если ты напишешь a.sidebar-module, то получиться, что ты даёшь стиль всем элементам a с классом sidebar-module.
43 1119126
>>19122
благодарю!
44 1119242
кто фронтом и версткой занимается, как вы это делаете вообще? решил себе сайт запилить, абсолютно невозможно спрогнозировать, что сколько времени займет. можно за 5 минут приделать всплывающую подсказку для формы поиска, а потом час равнять два дива по высоте. и главное в итоге удовольствия никакого (в отличие от бэкенда)
45 1119246
>>19242

>равнять два дива по высоте


загугли ебаные флексбоксы
46 1119250
Как правильно кнопки оформлять? Я сейчас не про внешний вид, а про сам код. Задавать через <a href="#"> и потом их оформлять я уже заебался, подкидывая при этом <a>дский костёр градиенты, вертикальные линии и ставя красивые границы, а ещё нужно стили убрать, ух бля. Знаю про элемент button, но нигде не видел по этому поводу, формы не подходят изначально, они для другого сделаны, для отправки данных на сервер, или я долбоёб? Скажите что-то по этому поводу, вкатился недавно и верстаю себе очко пока что, через неделю-две вкатываюсь в джс и нужно до конца отдрочить этот html/css.
47 1119251
>>19250
Знаю элемент button, но нигде не видел связанных с ним внятных статьей или хорошего кода

быстрофикс
48 1119264
>>18981
анон, я разобрался и программа получилась на столько короткой, что я просто ахуел, спасибо
https://ideone.com/4OINVC
49 1119266
>>19251

>сбрасываешь стили


>ставишь дисплей блок


>оформляешь как обычный див


>profit...


Мимо вкатывальщик из фронт-энд треда, а еще есть фреймворки типа бутстрапа...
50 1119267
>>19250
Смысл вкатываться через две недели. Мне вот надоедает дрочить верстку долго, жс тоже надоедает дрочить. Поэтому обмазываюсь ими по очереди.
51 1119300
Задачка про банки и планшет, пойдет?

http://sandbox.onlinephpfunctions.com/code/59ad0f4278069af0ceacfc199c6d4518b6cd0aff
52 1119307
Аноны если мне нужно в слиме в middleware доступ к бд.
А получить через контейрнер его я там не вижу как. То это хуевая реализация. Или мне создать свой пдо в нем?
53 1119325
>>19264
А с помощью foreach сможешь решить?
54 1119326
>>19307
Разве ты не регистрируешь __invoke() класс в контейнере прежде чем добавить его в промежуточный слой?
В нём и добавляй все зависимости через конструктор.

Должно получиться.
55 1119328
>>19300
Нет, у тебя там 3 функции с одинаковым кодом, это плохо - копипаста. У тебя должна быть одна функция, а переменные, которые ты задаешь в начале, должны передаваться через аргументы.
56 1119337
https://2ch.hk/b/res/168642277.html (М)
Как вам новость?
57 1119340
>>18843

>если буду ебашить прерываясь только на поспать и посрать?


Выгоришь же
58 1119341
>>19337
А что такого? Вообще нейросети довольно старое понятие, их ещё в прошлом веке наверное с 60ых годов разрабатывали, потом хайп ушел так как не хватало мощностей, сейчас вторая волна началась (может и не вторая, а N-волна). Во-вторых кому-то надо будет поддерживать эту верстку, кому-то надо будет работать с самими нейронками, заказчики сами этого не сделают. Я глазами пробежал, там только статика? Сейчас любой сайт, это наполовину js-приложение, которое без js зачастую просто развалится либо превратится в тыкву. Ну и в третьих, это даже хорошо когда механические задачи больше не надо будет делать.
59 1119343
>>19337
Удобно, че
60 1119344
>>19326
спасибо анон. вообще я сразу так не делал потому что в документации он примерно вот так делает
$app->add( new NEwMiddleware());
61 1119358
>>19325
смог, хотя не уверен, что это именно то, что ты имел ввиду типа цикл в цикле получился
https://ideone.com/Ehcsuj
62 1119367
>>19337
по правде говоря, тот самый "верстальщик", который 10 лет назад верстал статику, уже не существует в природе. щас любую статику можно сделать быстро и без гемора с помощью существующих инструментов (бутстрап, например) при наличии минимального опыта. то есть, такой профессии уже давно нет, сейчас есть фронты.
63 1119406
>>19344
У тебя получилось?

Прежде чем создать какой-то сервис нужно зарегистрировать его в контейнере. Но это не точно.

>>19358

>хотя не уверен, что это именно то, что ты имел ввиду


В задаче сначала был массив массивов $words с всеми словами

В посте >>18981 есть подсказка как решить такую задачу

>>Подсказка: можно упростить программу, сделав что-то вроде шаблона для генерации стиха на основе массива. В каждый элемент массива мы кладем массив вариантов слова или строки, из которого надо сделать выбор: [$word1, $word2, $word3, ["\n"], ...]. Мы добавляем массив с "\n", чтобы в нужном месте вывелся перевод строки. Остается только пройти по массиву циклом и сгенерировать стих..

64 1119435
Какие фреймворки нужно знать в php?
65 1119447
>>19406
да. в итоге вот так теперь $app->add($container['newMiddleware']);
66 1119518
>>19435
Лучше не к фреймворкам привязываться, а делать упор на фундаментальные вещи - сети, ООП, линукс. Я к примеру устраивался Symfony джуном и за полгода успел поработать с Laravel, Yii2, Zend. При том, что ранее с этими фреймворками знаком не был.
67 1119524
>>19447
Вроде, даже можно просто написать просто $app->add('newMiddleware') если оно зарегистрировано в контейнере.
68 1119527
>>19524
рли сработало. спасиб анон
69 1119539
>>19341

Вот именно. Плотники и обработчики металла не исчезли с появлением станков и циркулярных пил.
70 1119540
>>19518
а зачем линукс в пхп?
71 1119542
>>19540
пхп как бы не только в окошечке браузера работает. большую часть современных больших приложений составляют cli-скрипты.
также потому что ты будешь подключаться по ssh к удаленному серверу, который на линуксе.
плюс гит. плюс баш-скрипты автоматизации на дев-сервере. плюс перезапуск сервисов, сборка фронта, еще куча всего.
72 1119543
>>19518

>устраивался Symfony джуном


какие вопросы задавали на собесе?
73 1119545
>>19542
а на окнах это всё не работает?
74 1119577
>>19545
учитывая, что я тебе говорю про удаленный сервер, не работает, т.к. такой вещи как винда+пхп на продакшне не существует.
75 1119594
>>18555 (OP)

>пишите один большой пост вместо нескольких маленьких


Лол, как в исходники Moodle заглянул.
76 1119604
Вопрос по doctrine. Почему у меня структура БД не создается из комментариев к классам, как это показано в примере http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/getting-started.html#starting-with-the-product-entity ? Срабатывает только из XML или из Yaml файла. Алсо, я на windows.
77 1119631
А PDO полностью можно заменить msqli? Как на это пдо создать форму отправки значений в базу данных?
78 1119669
как же всё заебало
79 1119720
>>19669
И не говори. Никто не заставляет учить, и в итоге получается так что пердолишься в лучшем случае 15 часов в месяц
80 1119742
>>18555 (OP)
Кто хочет поучаствовать в пет-проекте за опыт напишите в телегу @monada
81 1119783
>>19543

>> устраивался Symfony джуном


> какие вопросы задавали на собесе?


Конкретно по Symfony не спрашивали ничего серьёзного - какие FormType использовать если есть сущность и связанные с ней через 1:M другие сущности, какие существуют способы описания метаданных сущностей, в чём преимущества недостатки у каждого из способов, какие бандлы юзал и т.д.

Больше было общих вопросов, например как работают сессии, что такое DNS, зачем используются трейты/итераторы/генераторы, магические методы, какие новые фичи в PHP7. Тестовые задания не просили делать, видимо из-за аккаунта на гитхабе, но было пару задачек на проектирование простой иерархии классов и на рекурсивный обход массива (у ОПа как раз есть эта похожая задача: https://github.com/codedokode/pasta/blob/master/interview-tasks.md#Дерево ). Код на листочке не писал (как этим любят запугивать в перезвоним-тредах), описывал алгоритмы словами.

По JS - чем отличаются call и apply, почему теряется this, что нового в ES6, что такое прототипы (ни разу не юзал их за всё время что работаю, но на собесе ответил, так как решал здесь задачи). Ещё немного тут писал: https://phpclub.tech/pr/res/1067944.html#1075232
82 1119794
>>19783
спасибо. судя по вопросам, должна быть хорошая контора.

щас сам симфони учу, начал сразу как вышла 4. очень интересно, но местами сложновато и неочевидно.

а что ты имеешь в виду под метаданными? записи типа @ORM\Table(name="blog") или что-то другое?
83 1119800
не могу понять сакральный смысл данного кода. нашел в одном скрипте. зачем столько кавычек?

preg_replace(array("`'`", "`[^A-z0-9]+`"), array("", "-"), $str)
84 1119815
>>19800
Автор не знал об волшебстве бекслеша и обошел проблему по-своему.
fe.gif122 Кб, 200x112
85 1119828
>>19815
точно блин
86 1119829
Как вообще называется этот символ `
И как пхп с ним работает?
87 1119832
>>19829

>Как вообще называется этот символ `


гравис

>И как пхп с ним работает?


оператор исполнения
89 1119836
>>19800
Полагаю автор соснул. Его использование обратной кавычки делало код бесполезным для санации строки.
90 1119847
Бампану своих студентов в новом треде:
https://phpclub.tech/pr/res/1109863.html#1117076
91 1119867
>>19577
Вообще ещё есть такие товарищи, кто крутит продакшн на IIS.
92 1119877
>>19742
Где поучавствовать? Кокой скилл нужен?
93 1119895
А есть какой-нибудь чатик? телеграмм какой-нибудь где можно помочь/получить помощь?
94 1119898
>>19895
Дискорд было вроде. Го туда
95 1119900
>>19895
Шарящие люди не будут сидеть в чатике. А здесь мимокрокодилы отвечают.
96 1119901
>>19898
скинь
97 1119902
>>19877
любой напиши обсудим
php.jpg54 Кб, 600x424
98 1119905
Нампоню как всё начиналось 20 лет назад.
99 1119909
>>19900
В том и дело, хотел пообщаться с кем-то по поводу докера и систем виртуализации в целом, но никто не отвечает. В чате может быстрее это произошло бы
100 1119910
>>19867
есть. тут даже был один, который пытался версию пхп обновить что ли. просто я к тому что это не повод не учить линукс в надежде, что попадется виндос сервер (который поди еще замороченнее линукса в изучении).
101 1119911
>>19909
@monada напиши добавлю в конфу
error-100700406-large.jpg34 Кб, 700x350
Обработка ошибок 102 1119912
Такая задача:
Необходимо написать скрипт парсера, который будет выполняться несколько дней неиспользуйпхпшники идут нахуй.

Проблема в том, что во время выполнения скрипта может произойти где-то ошибка, например мне нужно писать спрасеное в удаленные БД, где админы любят мутить всякую хуйню из-за чего порой можно не получить соденения с базой. Либо еще какойто ноунейм fatal error.

Соответственно скрипт упадет. А мне этого ненужно.

Пишу перехватчики через set_error_handler() и set_exception_handler() при получении ошибки - шлю к себе на почту. Но как быть в случае fatal error? Как сделать так, чтобы при получении таковой ошибки скрипт продолжил выполнение?

Можно конечно обвешать все try catch throwable, но это хуита ибо не всего не учесть. Ваши предложения?
tagsarticles.png24 Кб, 1192x420
103 1119932
я правильно нарисовал?
104 1119939
>>19932
а почему слева рядом с таблицей две палочки, а справа одна?
105 1119940
>>19847

Ты обещал ридми сделать и до сих пор так и не сделал.
106 1119941
>>19847

Я конечно, все равно проверю, как будет время, но ридми бы не помешал.
107 1119947
>>19939
ошибся, хотел справа поставить тоже две.

вот тут у меня основной вопрос: одна палочка значит "один", а две - "один и только один". в чем разница между ними?
108 1119954
>>19947

>один и только один


Попахивает индексом Unique для поля в БД. В принципе, в твоем случае идентификация происходит по Primary key а он всегда unique. А какой программой ты пользуешься для моделирования?
109 1119959
>>19932
а субд - postresql?
110 1120014
Можно ли вкатиться в веб без изучения пхп? Не хочется просто учить лишний язык
111 1120023
>>19954
https://www.lucidchart.com/ попал туда с туториала https://www.youtube.com/watch?v=-CuY5ADwn24
но я уже не уверен, что это относится к проектированию бд.

>>19959
да.
112 1120024
>>20014
новые проекты на пхп не пишут, вкатывайся.
113 1120028
Как решить первую задачу? Скопировал оба параметра и поставил знак умножения, не работает.
114 1120038
>>20023

>но я уже не уверен, что это относится к проектированию бд.


это я имел в виду про одинарную черточку, т.к.
они там моделируют далеко не только бд. возможно в бд достаточно обозначить тип связи и все
115 1120065
ОП, посмотри задачу про антикризисные меры, пожалуйста

https://3v4l.org/h4J4X
116 1120095
>>19941
>>19940
Ридми допилил.
117 1120109

>public function setRank(int $rank): void


>{ $this->rank = $rank; }


Правильно ли я понял, что ПХП внезапно стал языком со строгой типизацией?
118 1120110
>>20109
Судя по всему ты вообще не понимаешь что такое строгая типизация.
119 1120112
>>20110
Может быть и не знаю, но вопрос тем не менее остаётся в силе, с каких пор в пхп можно или нужно указывать типы данных при объявлении функций?
120 1120113
>>20112
Очевидно с 7 версии.
121 1120116
ОП, а можно свой проект пилить по мотивам задачи "Список студентов"? Ты тогда посмотришь ошибки?
122 1120117
www.bananagiveaway.com
123 1120126
>>20023

>https://www.lucidchart.com/


Не вижу там возможности экспорта схемы БД. Подобный софт должен это делать в форматах SQL и XML, да еще и с тестовыми данными, как это делает Sybase Power Designer. А в идеале он еще должен генерировать классы для работы с базой и фреймворка, как это делает Skipper (ORM Designer), но для него кряка нет, а он стоит баков 300 отсоси у тракториста.
124 1120128
Ананасы, такая проблема:

Есть у меня допустим страница с кнопками от бутстрапа. Есть файл php скрипта.
Как их законектить самым простым способом? Чтоб при нажатии на кнопку выполнялся скрипт.

Гуглением нашел всякие ассинхронные фреймворки, но мне нужен максимально простой способ.
Или хотя бы хороший пример - потому что в гугле тонна примеров сабмит формы, но мне это не очень подходит.
125 1120168
>>19912
Никто не знает?
126 1120180
>>19912

>try catch throwable, но это хуита ибо не всего не учесть.


Это ты хуита. PDO кидает исключение, если база не доступна, его и обрабатывай.
127 1120183
https://ideone.com/Mj4kRe
Уже пару часов не могу доту пить как же сделать переборку слогов, через foreach? ЧЯДНТ?
128 1120186
>>20183

>не могу дотупить


Т9 на ведре подвёл.
129 1120204
>>20128
-можешь положить все кнопочки в форму в которой у тебя прописан action='твой скрипт'
-Можно с помощью жквери. Типа присваиваешь функцию кнопочке, а в функции у тебя аякс.
130 1120212
>>20183

>$randomText = array();


>foreach ($letters as $randomText);


>$randomText = implode($letters);



Во первых учи PSR и юзай скобки!!!
Во вторых, у тебя тут цикл по пустому массиву $randomText, чего ты ожидаешь?
Во третьих, ты украл чей то код?

>/ Выкидываем случайное число (count - число элементов в массиве) /


>/ Точка склеивает 2 строки в одну /


Эти комменты указывают на вещи которые не используются в коде, а должны бы.
131 1120214
>>20212

>Во вторых, у тебя тут цикл по пустому массиву $randomText, чего ты ожидаешь?


Что я несу, совсем обджиэсился.
У тебя цикл по ВСЕМ слогам,
$randomText это переменная цикла - значение каждого слога,
но в цикле ты присваиваешь ей новое значение, что бессмысленно
132 1120216
>>20109
>>20110
с седьмой версии можно указать строгую типизацию с помощью declare(strict_types=1)
133 1120217
Здравствуйте, нулевый болванчик итт.
Есть сайт на одной из страниц которого лежат изображения, нужно их заменить на новые.
Скачал фтп, все залез, нашел где лежат данные картинки.
Но не могу найти файл где они прописаны что они должны находится на именно той странице сайта (не знаю как правильно объяснить но вы поняли)
Т.е на сайте они лежат по адресу www.site/wp-content/uploads/2011/12/filename.jpg
На фтп они там есть. Искал через notepad++ во всех файлах упоминание filename.jpg, его там тупо нету. Что я делаю не так?
134 1120218
>>20216
Я знаю, но это опциональное применение. Товеть ты можешь это применять, а можешь и нет.
135 1120234
>>20168
они там поди генерятся динамически и их названия лежат где-то в бд в отдельной ячейке или генерятся по названию статьи, хз. может кто-то, знающий вп, ответит более конкретно
136 1120235
>>20234
Какое ВП? Какая база, поехавший?
>>20180
Жопой читаешь? Поясню сокращенно: вешаю обработчик на set_exception_handler() можно как-то сделать, чтобы в случае fatal error скрипт не падал, а продолжал выполнение? Повторю: Я НЕ ХОЧУ ОТЛАВЛИВАТЬ КАЖДЫЙ ПУК ЧЕРЕЗ try catch
137 1120236
>>20218
да, просто эта возможность тесно связана с тайп-хинтом аргументов и возврата, о котором спрашивал анон.

алсо, я тут пытаюсь использовать эту строгую типизацию, она конечно прикольная, но какая-то недоделанная по сравнению с джавой. нельзя указать тип переменной например int $count; надо писать обязательно $count = 0; но это хуета в принципе, а вот что нельзя сделать массив строк или массив интов - это недоработка по мне.

плюс есть некоторые функции, которые исторически выдают либо фолс, либо тру, либо число, либо массив. допустим preg_replace возвращает либо массив, либо строку, либо нулл.
138 1120237
>>20214
Это же пример с гайда по обучению,который здесь лежит. Просто поленился комменты тереть.
139 1120238
>>20235
вордпресс

оно на то и фатал еррор, чтобы останавливать программу. можешь свечку поставить, чтобы он не вываливался лол
140 1120240
>>20236

>нельзя указать тип переменной например int $count;


Чел ну это не недоделанность, это другой синтаксис. А ты что думал, что выучишь джаву и всё? Везде так будет?
141 1120241
>>20214
Так я и пытался через выгрузку в пустой массив отдельных слогов запилить склейку имени. Но что-то пошло не так.
142 1120242
>>20240

>выучишь джаву и всё?


вообще было бы круто лол

это понятно, но в джаве можно написать int a, b, c; а у нас как? только через жопу типа $a = $b = $ c = 0;
143 1120243
>>20236
Видимо ты не правильно пользуешься функцией preg_replace. Так как регулярные выражения в php работают очень хорошо и никаких проблем не вызывают
144 1120244
>>20236
preg_replace() возвращает массив, если параметр subject является массивом, иначе возвращается строка.
Если найдены совпадения, возвращается новая версия subject, иначе subject возвращается нетронутым,
в случае ошибки возвращается NULL.
145 1120246
>>20242
Можно написать так:
$a = 0;
$b = 0;
$c = 0;
Нет никакой необходимости объявлять несколько переменных в одной строке.
146 1120250
>>20235

Не стоит так в нашем треде разговаривать. Тебе ведь никто помогать не захочет.

По поводу исключений, у меня есть урок (если он вдруг нужен): https://github.com/codedokode/pasta/blob/master/php/exceptions.md

Так вот, исключения тем и отличаются от ошибок PHP, что в случае их возникновения PHP выходит из функции вверх (в вызвавшую фукнцию), из нее еще вверх и так, пока не наткнется на catch или не выйдет на самый верх. Это поменять нельзя.

В случае обычных ошибок принцип другой - при ошибке вызывается обработчик, и есть выбор, завершить скрипт либо проигнорировать ошибку. Опции "повторить проблемную команду" нет и там.

Тебе придется править код программы и добавлять повтор попыток явно. По моему, проще просто настроить БД нормально (или запускать скрипт у себя, где ничего не отвалится). Иначе надо искать все места в скрипте, где идет обращение к БД и заменять стандартные функции на свои, которые будут ловить исключение и при его возникновении делать повторное соединение к БД. желательно ограничить число попыток.
147 1120251
>>20244
Ну и что в этом такого необычного? В php это обычная практика делать функции, которые возвращают разные типы данных в зависимости от различных параметров.

У ответа ведь все равно всегда можно проверить тип данных при помощи функций is_bool, is_double, is_string, is_array и так далее.
148 1120252
>>20243
это просто пример того, что встроенные функции под возврат нужного типа не приспособлены. таких примеров много. в случае с preg_replace можно возразить "ну шли туда всегда строку и будет возвращаться строка", но тут другой нюанс: допустим, я хочу обернуть логику в свой метод, в других языках для обработки разных типов данных есть перегрузка, а тут ее нет, придется писать replaceString(), replaceArray()

>>20246
убедил лол

я вообще это не к тому, что все плохо, а к тому, что еще есть что допилить в направлении строгой типизации.
149 1120253
>>20183

Суть программирования в том, что тебе надо написать решение задачи в виде набора шагов, которые поймет компьютер. Он твои мысли читать не может и не угадывает, что ты имел в виду, а выполняет программу строго, как она написана.

Ты можешь для начала расписать, что должно делаться внутри цикла, на русском языке? Чтобы было видно, где проблема - ты не понимаешь, какие действия надо сделать, или же ты понимаешь, но не знаешь, как их записать на языке PHP?

По твоему коду, у меня ощущение, что ты просто там писал наугад команды в надежде, что оно как-то заработает. Увы, так это не работает. Нужно понимать, что делает каждая строчка.

Я дам тебе пример, как сгенерировать имя из 2 цифр (согласен, странное имя, но это ради простоты):

$number1 = сгенерировать случайную цифру от 1 до 6;
$number2 = сгенерировать случайную цифру от 1 до 6;
$result = склеить $number1 и $number2 в одну строку;
вывести $result;

И теперь перевод этого кода на PHP:

$number1 = mt_rand(1, 6);
$number2 = mt_rand(1, 6);
$result = $number1 . $number2;
echo $result;
echo "\n";

Заметь, что у меня нет цикла. Это для простоты. Я сначала написал простое решение без цикла и для 2 слогов, а потом могу переделать на цикл с любым числом повторений. Ты можешь сделать так же, сначала без цикла, с 2 слогами, а потом уже сделать нормально.

Попробуй свое решение записать так же. Если ты не понимаешь, какие должны быть шаги, напиши, дадим еще подсказки.
149 1120253
>>20183

Суть программирования в том, что тебе надо написать решение задачи в виде набора шагов, которые поймет компьютер. Он твои мысли читать не может и не угадывает, что ты имел в виду, а выполняет программу строго, как она написана.

Ты можешь для начала расписать, что должно делаться внутри цикла, на русском языке? Чтобы было видно, где проблема - ты не понимаешь, какие действия надо сделать, или же ты понимаешь, но не знаешь, как их записать на языке PHP?

По твоему коду, у меня ощущение, что ты просто там писал наугад команды в надежде, что оно как-то заработает. Увы, так это не работает. Нужно понимать, что делает каждая строчка.

Я дам тебе пример, как сгенерировать имя из 2 цифр (согласен, странное имя, но это ради простоты):

$number1 = сгенерировать случайную цифру от 1 до 6;
$number2 = сгенерировать случайную цифру от 1 до 6;
$result = склеить $number1 и $number2 в одну строку;
вывести $result;

И теперь перевод этого кода на PHP:

$number1 = mt_rand(1, 6);
$number2 = mt_rand(1, 6);
$result = $number1 . $number2;
echo $result;
echo "\n";

Заметь, что у меня нет цикла. Это для простоты. Я сначала написал простое решение без цикла и для 2 слогов, а потом могу переделать на цикл с любым числом повторений. Ты можешь сделать так же, сначала без цикла, с 2 слогами, а потом уже сделать нормально.

Попробуй свое решение записать так же. Если ты не понимаешь, какие должны быть шаги, напиши, дадим еще подсказки.
150 1120257
>>20253
>>20241
Спасибо за развернутый ответ, анон. Мой же пост. Понимаю как это выглядит в русском языке, но знаний в php не хватает для отражения онного же в коде. Немного не ту версию кода засейвил на работе, поэтому так и выглядит. А исходник лежит на домашнем пека.
151 1120261
>>20251
Я к тому, что я смог найти это в доках за 5 секунд. PHP не идеален, но блин вот эта функция по моему работает вполне внятно. Ладно не буду превращать тред в чатик.
152 1120262
В чем отличия и надо ли использовать ссылки?
Например тут
function trim_value(&$value)
{
$value = trim($value);
}
Я бы бы через foreach перебрал. Чем мой вариант хуже кроме того что он длиннее?
153 1120263
>>20252

>в других языках для обработки разных типов данных есть перегрузка



В php конечно же нет перезагрузки функций, т.е. создание функций с одинаковыми названиями, но разными параметрами. Но этого обычно и не требуется, так как во-первых, можно объявить параметры с default-значениями:
function func($int, $string = ''),

а еще можно проверять тип данных параметра:
function func2($var) {
if (is_array($var)) //сделай это
else if (is_string($var)) //сделай что-то другое
else //сгенерируй сообщение об ошибке
}

Обе эти возможности на 100% заменяют перезагрузку функций.
154 1120265
>>20109

PHP называют языком с "добровольной типизацией" - кто хочет, тот и ставит тайп-хинты. Тайп-хинты можно ставить на аргументы и результат функций но, увы, нельзя на поля и переменные. Также, увы, тайп-хинты ограничены в возможностях и пока нет generics.

Как видишь, с тайп-хинтами код становится намного лучше, так что советую ставить их везде.

>>20216

Замечу, что эта опция влияет только на отключение преобразования типа в тайп-хинтах. Мне она не нравится тем, что теперь у нас может быть 2 вида исходников, в одних все совсем строго, в других не совсем. Опять они не смогли выбрать одно решение и решили всем предложить выбор.

>>20236

Для массива строк или интов, или коллекции каких-то объектов нужны generics:

https://wiki.php.net/rfc/generic-arrays
https://wiki.php.net/rfc/generics

Эти предложения пока не приняты, и код, как я понимаю, не написан. Но все еще возможно.

> плюс есть некоторые функции, которые исторически


Это не мешает тебе писать свои функции со строго определенными типами.

> недоделанная по сравнению с джавой


Ну это все таки другой язык. Если ты хочешь как на Джаве, то проще на ней и писать.

>>20244

По моему субъективному мнению, отсутствие единого типа аргументов или результатов ухудшает код и повышает вероятность ошибок. Я бы сделал для массивов отдельную функцию preg_replace_array.

А вот возвращать что-то или null вполне допустимо. null для этого и придуман.

>>20251

По моему субъективному и ничем, кроме моего опыта, не подкрепленному мнению, это плохо. Нельзя же писать нормально код, когда ты не уверен, какого типа результат. Нужно строго определять типы аргументов и результата, если они могут быть разные, лучше сделать несколько разных функций. Иначе легко ошибиться.

Ну и разным анализаторам кода тоже будет легче.
154 1120265
>>20109

PHP называют языком с "добровольной типизацией" - кто хочет, тот и ставит тайп-хинты. Тайп-хинты можно ставить на аргументы и результат функций но, увы, нельзя на поля и переменные. Также, увы, тайп-хинты ограничены в возможностях и пока нет generics.

Как видишь, с тайп-хинтами код становится намного лучше, так что советую ставить их везде.

>>20216

Замечу, что эта опция влияет только на отключение преобразования типа в тайп-хинтах. Мне она не нравится тем, что теперь у нас может быть 2 вида исходников, в одних все совсем строго, в других не совсем. Опять они не смогли выбрать одно решение и решили всем предложить выбор.

>>20236

Для массива строк или интов, или коллекции каких-то объектов нужны generics:

https://wiki.php.net/rfc/generic-arrays
https://wiki.php.net/rfc/generics

Эти предложения пока не приняты, и код, как я понимаю, не написан. Но все еще возможно.

> плюс есть некоторые функции, которые исторически


Это не мешает тебе писать свои функции со строго определенными типами.

> недоделанная по сравнению с джавой


Ну это все таки другой язык. Если ты хочешь как на Джаве, то проще на ней и писать.

>>20244

По моему субъективному мнению, отсутствие единого типа аргументов или результатов ухудшает код и повышает вероятность ошибок. Я бы сделал для массивов отдельную функцию preg_replace_array.

А вот возвращать что-то или null вполне допустимо. null для этого и придуман.

>>20251

По моему субъективному и ничем, кроме моего опыта, не подкрепленному мнению, это плохо. Нельзя же писать нормально код, когда ты не уверен, какого типа результат. Нужно строго определять типы аргументов и результата, если они могут быть разные, лучше сделать несколько разных функций. Иначе легко ошибиться.

Ну и разным анализаторам кода тоже будет легче.
155 1120267
>>20217
ну ладно
156 1120268
>>20262
Ссылки в php нужно использовать как можно реже или лучше даже совсем от них отказаться.
157 1120270
>>20257

А может ты тогда напишешь код (внутри цикла) на русском и на PHP, а я или кто-то еще скажет, где ты ошибся при переносе с русского на PHP?

>>20262

В твоем примере, лучше возвращать результат, а не менять аргумент, так как это выглядит более ожидаемо, что функция вернет что-то.

Насчет ссылок, в мануале описано, что у них много подводных камней, потому лучше не использовать их без надобности: http://php.net/manual/ru/language.references.php

>>20217

Контент (в том числе HTML код статей) может храниться в базе данных. Редактировать их можно в случае вордпресса через админку, в которую тебе должны были выдать доступ.

Но ты можешь заменить файлы картинок, оставив те же самые имена.

>>20268

У нас обучающий тред, желательно писать, почему. А то без аргументов выглядит как чье-то личное мнение.
158 1120271
>>20235

>Какое ВП? Какая база, поехавший?


а, это я не тебе. это я >>20217 анону

алсо, валерианочку попей.

>>20265

>Если ты хочешь как на Джаве, то проще на ней и писать


туда хер вкатишься. сам язык не сильно сложнее пхп, но экосистема просто безумно большая.

плюс если перекатываться, там будет явно меньше зп вначале, но это уже для другого треда разговор.
image.png7 Кб, 199x177
159 1120272
>>20270

>Редактировать их можно в случае вордпресса через админку, в которую тебе должны были выдать доступ.


Не совсем понял, но полный доступ к хостингу, фтп вот к этому всему есть.
Пикрил - список плагинов.
Да, я так уже и сделал - заменил изображения на новые с такими же именами, но одно изображение исчезло (пустое место) но кликабельность и ссылка на него осталась, блин
160 1120273
>>20270
https://ideone.com/IlvuRW
Не понимаю как из $letters перетащить данные последовательно по слогу. Поэтому собственно и спрашивал о переборке через foreach.
161 1120274
>>20273
Бтв. Первые джва дня пытаюсь вкатится, поэтому скорее всего много глупостей говорю.
162 1120275
>>20270

>>У нас обучающий тред, желательно писать, почему. А то без аргументов выглядит как чье-то личное мнение.


>У нас обучающий тред, желательно писать, почему. А то без аргументов выглядит как чье-то личное мнение.



Причина очень проста. Использование ссылок делает код более трудным для понимания и для поддержки, не давая почти ничего взамен
163 1120277
>>20273
Вот, исправил твой код:
https://ideone.com/vKpetZ
164 1120280
>>20272

Странно, что ты никогда не слышал про админки. Там на сайте есть форма входа, вводишь туда логин и пароль и получаешь доступ. Попроси у заказчика "логин и пароль администратора сайта" и адрес страницы, куда его вводить. Они же как-то эти статьи туда добавили.

>>20273

Я напишу, что на самом деле делает код

// Берем случайный элемент массива и сохраняем в random его ключ (не значение, то есть не сам слог)
$random = array_rand($letters);

// Создаем пустой массив и помещаем в переменную
$randomText = array();

// склеиваем все 16 слогов из массива letters в одну длинную строку и помещаем в randomText,
// удаляя хранившийся там ранее массив
$randomText = implode($letters);

Соответственно, тебе надо немного вернуться и повторить такие вещи:

- что массив состоит из элементов, у каждого есть ключ (=индекс) и значение. Ключи уникальны и не повторяются внутри одного массива.
- как, имея массив слогов и ключ одного слога, получить значение этого слога? Подсказка: использовать квадратные скобки. Может, в уроке это плохо описано, но конструкция вида массив[ключ] возвращает значение элемента с данным ключом. Здесь "ключ" может быть переменной, числом, строкой в кавычках, сложным выражением.
- далее, получая на каждом шаге цикла один слог, как их собрать в массив? Надо до цикла создать пустой массив, а в цикле добавлять в него еще один элемент. Добавление элемента в массив (внутри цикла) делается так: массив[] = значение; При этом ключ для нового элемента генерируется автоматически. Ну а после цикла ты уже можешь склеить собранные слоги из массива в одну строку.

То есть, ты плоховато знаешь работу с массивами и отсюда проблемы.

Давай после задачки про слоги решим дополнительную задачку, чтобы лучше в них разобраться. Дано 2 массива с оценками за январь и за февраль вида:

$january = [
'math' => 4,
'physics' => 5,
'literature' => 2
];

$february = [
'math' => 5,
'physics' => 5,
'literature' => 2
];

Напиши программу, которая выведет:

- по каким предметам оценки остались неизменными
- по каким улучшились
- по каким ухудшились

Выводиться данные должны сгруппированно, в таком виде:

Оценки не изменились: physics, literature
Оценки улучшились: math
Оценки ухудшились: (таких нет)
164 1120280
>>20272

Странно, что ты никогда не слышал про админки. Там на сайте есть форма входа, вводишь туда логин и пароль и получаешь доступ. Попроси у заказчика "логин и пароль администратора сайта" и адрес страницы, куда его вводить. Они же как-то эти статьи туда добавили.

>>20273

Я напишу, что на самом деле делает код

// Берем случайный элемент массива и сохраняем в random его ключ (не значение, то есть не сам слог)
$random = array_rand($letters);

// Создаем пустой массив и помещаем в переменную
$randomText = array();

// склеиваем все 16 слогов из массива letters в одну длинную строку и помещаем в randomText,
// удаляя хранившийся там ранее массив
$randomText = implode($letters);

Соответственно, тебе надо немного вернуться и повторить такие вещи:

- что массив состоит из элементов, у каждого есть ключ (=индекс) и значение. Ключи уникальны и не повторяются внутри одного массива.
- как, имея массив слогов и ключ одного слога, получить значение этого слога? Подсказка: использовать квадратные скобки. Может, в уроке это плохо описано, но конструкция вида массив[ключ] возвращает значение элемента с данным ключом. Здесь "ключ" может быть переменной, числом, строкой в кавычках, сложным выражением.
- далее, получая на каждом шаге цикла один слог, как их собрать в массив? Надо до цикла создать пустой массив, а в цикле добавлять в него еще один элемент. Добавление элемента в массив (внутри цикла) делается так: массив[] = значение; При этом ключ для нового элемента генерируется автоматически. Ну а после цикла ты уже можешь склеить собранные слоги из массива в одну строку.

То есть, ты плоховато знаешь работу с массивами и отсюда проблемы.

Давай после задачки про слоги решим дополнительную задачку, чтобы лучше в них разобраться. Дано 2 массива с оценками за январь и за февраль вида:

$january = [
'math' => 4,
'physics' => 5,
'literature' => 2
];

$february = [
'math' => 5,
'physics' => 5,
'literature' => 2
];

Напиши программу, которая выведет:

- по каким предметам оценки остались неизменными
- по каким улучшились
- по каким ухудшились

Выводиться данные должны сгруппированно, в таком виде:

Оценки не изменились: physics, literature
Оценки улучшились: math
Оценки ухудшились: (таких нет)
165 1120282
Привет всем анонам. Всё еще пилю сайт про студентов. Я много слышал про разделение логики приложения и логики представления, но с пагинацией я немного запутался, есть класс, в одном из методов которого я просто через цикл печатаю ссылки на экран, а потом объект пагинации передаю во вью, так нормально делать? Альтернативой будет сделать цикл в отдельном шаблоне, и передавать туда объект, а потом еще и написать тыщу геттеров для полей класса, я ж инкапсулирую.
И еще вопрос по неймспейсам, если у меня например класс вью называется App\View\View , а шаблоны лежат например в App/templates, как лучше всего подключить шаблоны уровнем ниже(выше?) неймспейса? Я пытался как-то изворачиваться с двойными точками, но полное понимание так и не пришло.
166 1120283
Вот все говорят что задачку из учебника на генератор стишков нужно делать через цикл склеивающий строки. Но не будет ли быстрее (по производительности) прост дважды склеить строку, без цикла? (Вопрос из опыта на питоне, где все встроенные функции написаны на С и без цикла обработалось бы быстрее).
На пхп второй день, хз че у него под капотом.
167 1120284
Задача на телефонные номера, на regex101 вроде все работает, теперь же не находит ничего. Где я обосрался?
168 1120286
Как в Symfony сделать форму для свойства, которое хранится как массив, а в БД как json. Для хранения переменного числа характеристик. Использовал пока CollectionType, в котором кастомный keyValueType (key, value поля).
Получается в БД поле такого вида:
[
{"key": "Материал", "value": "металлический каркас"}, {"key": "Цвет подставки", "value": "черный"}
], а хотелось бы такого: [
{"Материал": "металлический каркас"}, {"Цвет подставки": "черный"}
].
Или вообще только массив, без объектов внутри, но теперь, так понимаю, json_array в Doctrine теперь deprecated.
Что можно придумать, чтобы при этом формы редактирования выводились в два поля: название характеристики и ее значение. Data Transformer? Вроде не то.
Пробовал через FormEvents::PRE_SUBMIT, тоже не вышло ключи изменить у коллекции. Возможно, это я неправильно делал.
На крайний случай можно через Event[Subcriber|Listener] Доктрины, но кажется, что это кривые костыли.
169 1120290
>>20284
ебать ты монстра родил, вот моя регулярка, вродь норм отработала
$regexp = '/^ (\\+ 7|8)([ (-][0-9][ )-]){10}$/';
171 1120292
>>20238
Я знаю что вп - это вордпресс причем он тут?

>оно на то и фатал еррор, чтобы останавливать программу


через try catch throwable не останавливает
172 1120296
>>20250
>>20292

>через try catch throwable не останавливает при фатал еррор

Screenshot8.png105 Кб, 1274x923
173 1120308
>>20290
>>20291
Забавно твой код на ideone работает, а на regex101 нет. В чем разница?
174 1120316
>>20308
Также, на regex101 https://regex101.com/r/qF7vT8/3 уже введены номера и можно простестировать свою регулярку. Помни что на этом сайте надо писать бекслеш один раз, например \s, а не \\s. Флаг m там стоит чтобы ^ и $ в регулярке обозначали «начало и конец любой строки», а не «начало и конец всего текста». Флаг g (его нет в PHP, он только на этом сайте) значит что надо искать все совпадения с регуляркой, а не только первое.
Там в уроке все написано, внимательнее будь
175 1120320
кто подскажет?
использую симфони4+доктрину. хочу чтобы доктрина сама обновляла created_at и updated_at для полей. такая возможность была раньше в бандле расширений доктрины https://github.com/Atlantic18/DoctrineExtensions/blob/v2.4.x/doc/timestampable.md
там именно так как я хотел - в аннотации указываешь по какому событию обновлять дату и не паришься. но проблема в том, что оно работает только для симфони2.

есть какое-то более актуальное расширение? понятно, можно вручную добавлять, но вдруг кто-то уже запилил готовое.
176 1120321
>>20280
Нашел эту самую БД, да там что то есть и наверно то что нужно. Но там очень много всего и чот очень сложно. Ладно спасибо все равно.
177 1120326
>>20204

>можешь положить все кнопочки в форму в которой у тебя прописан action='твой скрипт'


>Можно с помощью жквери. Типа присваиваешь функцию кнопочке, а в функции у тебя аякс.


Можешь пожалуйста пример привести?
b3b28d65ce7609ee0e5ebd343aab40e2.jpg214 Кб, 1280x853
178 1120332
Есть данные в двумерном массиве. Необходимо вности в БД. А теперь вопрос. Например есть 10000 строк. То как лучше внести данные? Какой способ быстрее и выгоднее для сервера?
1) Построчно прогоняя массив через форыч вносить в базу каждый раз используя INSERT:

INSERT INTRO <название таблицы> SET <имя столбца1> = <значение1>, <имя столбца2> = <значение2>...

2) Или же сформировать один большой запрос как делается при SQL дампе и использовать INSERT всего 1 раз:

INSERT INTRO <название таблицы> (`имя столбца1`,`имя столбца2`,...) VALUES ('значение11', 'значение12'...), ('значение21', 'значение22'...), ('значение31', 'значение32'...),...
179 1120342
>>20270

>А может ты тогда напишешь код (внутри цикла) на русском и на PHP


Взять случайный элемент из массива и добавить к имеющемуся слову:
$name = $name . $letters[rand(0, 15)];
180 1120344
>>20326
1)
<form method="post" action="имяскрипта.пхп">
<button type=submit>
</form>
2) <button onclick="ajaxfunction">
181 1120345
>>20332
на 10000 строках не будет особо различий.Сделай обоими способами и измерь время
182 1120346
>>20342
Обля, еще проще. Есть готовая функция, возвращающая случайный элемент массива:
$name = $name . array_rand($letters);

Сокращенный синтаксис конкатенации строк опускаю. Новичку проще так.
183 1120350
>>20332
Один большой запрос всегда быстрее, чем много мелких. Однако, у БД есть ограничение на размер запроса, поэтому возможно потребуется разбить его на несколько множественных инсертов. Заметим, что при импорте дампа отключают для ускорения отключают проверку foreign key и удаляют индексы:
SET FOREIGN_KEY_CHECKS=0;
ALTER TABLE mytable DROP INDEX myidx;
По окончании импорта эти параметры восстанавливают.
184 1120355
у тебя в регексе жопа с метлой
([-)( 8]...
круглые скобки получают приоритет перед квадратными. эскейпи их
([-\)\( 8]...
185 1120361
>>20283
Implementation language
C (primarily; some components C++)
186 1120363
>>20282
Пагинация относится исключительно к представлению. Класс, в котором метод печатает ссылки на экран, не должен находится в модели. Только в представлении. Контроллер должен запрашивать у модели данные с двумя параметрами: $number_of_results, $skip_results, где первое - количество результатов на страницу. А второе = $number_of_results х $номер_страницы
187 1120365
>>20282

>Альтернативой будет сделать цикл в отдельном шаблоне, и передавать туда объект, а потом еще и написать тыщу геттеров для полей класса


Цикл в шаблоне - это нормально, если оформлен по канонам

<?php foreach (...) : ?>
хтмл хтмл <?= $viewObject->joba->getNum(); ?>хтмл хтмл
<?php endforeach; ?>
188 1120368
>>20320
не шарю в doctrine, но автоматическое обновление полей с датой - это функция БД. Для этого у поля типа timestamp прописывается дефолтное значение CURRENT_TIMESTAMP.
189 1120373
>>20262
В php по умолчанию всегда неявным образом передает в функцию ссылку на параметр. Переменная создается в памяти только, когда ты внутри функции начинаешь её менять.
190 1120378
>>20365
Да, цикл в шаблоне не представляет никаких проблем в стилистическом плане и модели MVC не противоречит
191 1120379
>>20320
это я напиздел. с 4 все работает нормально, вот: https://packagist.org/packages/stof/doctrine-extensions-bundle
щас буду ебаться с настройкой

>>20368
1. у меня не мускул.
2. это можно делать где угодно (в принципе), но если ты используешь такую жирную абстракцию как ОРМ, то логично всю работу с БД делегировать ей. а как она там технически будет добавлять - мне пока неважно. возможно, она это делает по-разному в зависимости от БД.
192 1120386
>>20379
Возможно, дефолтное значение поля БД должно быть прописано в твоей XML схеме, которую доктрина использовала для генерации БД и классов.
193 1120404
>>20116
Повторюсь. Можно ли свой проект вместо студентов делать? ОП будет помогать тогда? Хочу сделать порезанную версию Anki, что бы дни для spaced repetition считались, а то руками в календаре отмечать я утомился.
194 1120407
>>20386
да нет, вот пример:

/
@var \DateTime $created

@Gedmo\Timestampable(on="create")
@ORM\Column(type="datetime")
/
private $created;

/

@var \DateTime $contentChanged

@ORM\Column(type="datetime", nullable=true)
@Gedmo\Timestampable(on="change", field={"title", "body"})
/
private $contentChanged;

очень удобно.

короче настроил всю хуйню тупо по инструкции https://symfony.com/doc/master/bundles/StofDoctrineExtensionsBundle/index.html
если кому надо, подскажу
195 1120412
>>20407

>@Gedmo\Timestampable(on="create")


>@Gedmo\Timestampable(on="change", field={"title", "body"})


О чем я и говорил. Это функция БД, которую ты включил с схеме базы.
196 1120418
>>20116
>>20404

Можно, но при условии, что ты прочитаешь комментарии к задаче про студентов и будешь стараться делать, как там написано, стараться соблюдать лучшие практики и тд. То есть, если ты собираешься чему-то учиться.
197 1120425
>>20412

Нет, не все так просто. Если бы это делала БД, то после сохранения сущности с такими полями нам надо было бы делать дополнительный запрос на загрузку сгенерированных дат. Потому лучше не гадать, а посмотреть исходник:

- https://github.com/Atlantic18/DoctrineExtensions/blob/v2.4.x/lib/Gedmo/Timestampable/TimestampableListener.php
- https://github.com/Atlantic18/DoctrineExtensions/blob/v2.4.x/lib/Gedmo/AbstractTrackingListener.php
- https://github.com/Atlantic18/DoctrineExtensions/blob/v2.4.x/lib/Gedmo/Timestampable/Mapping/Event/Adapter/ORM.php

Судя по коду, генерируется это в событиях onFlush и prePersist.
198 1120429
Посоветуйте какой-нибудь сервер для ньюфагов.
Где можно аджакс, сикуэл и прочие пхп поднять.

Устанавливал месяца 2 назад, но название забыл.
199 1120430
>>20429
наверное, речь о XAMPP?
Он один из самых популярных вроде?
201 1120439
>>20436

>denwer


>PHP 5.3.13, MySQL 5.1, PostgreSQL 8.4 etc


это говно мамонта. зачем советовать людям говно мамонта?

>>20429
open server. я когда сидел на винде, сравнивал его с xampp, первый намного пизже. больше функционала, удобный доступ к конфигам, удобное переключение, прочие плюшки
202 1120471
Поднял я апач сервер, запустил пхп скрипт.

Можно ссылку на тутор, где показано как это все связать с обычным хтмл? (Хочу использовать бутстрап).
203 1120498
>>19406
так тот цикл в цикле был близок к этому или вообще не то?
204 1120499
>>20344
А я вот ещё не понимаю одной вещи.

Есть у меня какой-то условный index.html и script.php.
Привязываю я скрипт к кнопке в индексе.
Как он будет работать?
Индекс то я могу и в хроме посмотреть, а вот пхп?
Нужно запускать какой-нибудь сервер, чтоб все заработало?
205 1120503
>>20499
правильно мыслишь
206 1120574
Господа! А базы данных сложная вещь? Тот же PDO посильно освоить?
207 1120586
>>20574
Бля, PDO - это прослойка между скриптом пхп и базой данных. Системы управления базами данных это Oracle, MSSQL, MySQL, PostgreSQL - это программы на подобие Excel, только текстовые. Они все управляются одним языком SQL. И если ты хочешь освоить базы данных, то тебе нужно освоить этот язык.
208 1120589
пацаны, еще вопрос по доктрине есть.

у меня короче есть две сущности: Article и Tag. у них будет bidirectional связь manyToMany (у многих статей может быть много тегов, для каждой статьи хочется знать ее теги и наоборот).

я после прочтения мануала http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#many-to-many-bidirectional короч пишу такой (псевдо)код:
//Article.php
@ORM\Table(name="articles")
class Article

@ORM\ManyToMany(targetEntity="Tag", inversedBy="articles")
@ORM\JoinTable(name="articles_tags")
private $tags;

//Tag.php
@ORM\Table(name="tags")
class Tag

@ORM\ManyToMany(targetEntity="Article", mappedBy="tags")
private $articles;

то есть по логике мануала должна создаться промежуточная таблица articles_tags (указана в аннотации JoinTable) и там должны быть два поля с айдишками статью и тега, которые будут образовывать составной первичный ключ. вроде заебись все.

далее делаю php bin/console doctrine:migrations:diff, создается файл миграции, но там ДВЕ промежуточные таблицы:
$this->addSql('CREATE TABLE articles_tags (article_id INT NOT NULL, tag_id INT NOT NULL, PRIMARY KEY(article_id, tag_id))'); // эта моя
$this->addSql('CREATE TABLE tag_article (tag_id INT NOT NULL, article_id INT NOT NULL, PRIMARY KEY(tag_id, article_id))'); // эта такая же, но автоматически сгенерированная

как так-то? почему их две? как сделать так, чтобы создавалась и использовалась только та, которую я указал?
208 1120589
пацаны, еще вопрос по доктрине есть.

у меня короче есть две сущности: Article и Tag. у них будет bidirectional связь manyToMany (у многих статей может быть много тегов, для каждой статьи хочется знать ее теги и наоборот).

я после прочтения мануала http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#many-to-many-bidirectional короч пишу такой (псевдо)код:
//Article.php
@ORM\Table(name="articles")
class Article

@ORM\ManyToMany(targetEntity="Tag", inversedBy="articles")
@ORM\JoinTable(name="articles_tags")
private $tags;

//Tag.php
@ORM\Table(name="tags")
class Tag

@ORM\ManyToMany(targetEntity="Article", mappedBy="tags")
private $articles;

то есть по логике мануала должна создаться промежуточная таблица articles_tags (указана в аннотации JoinTable) и там должны быть два поля с айдишками статью и тега, которые будут образовывать составной первичный ключ. вроде заебись все.

далее делаю php bin/console doctrine:migrations:diff, создается файл миграции, но там ДВЕ промежуточные таблицы:
$this->addSql('CREATE TABLE articles_tags (article_id INT NOT NULL, tag_id INT NOT NULL, PRIMARY KEY(article_id, tag_id))'); // эта моя
$this->addSql('CREATE TABLE tag_article (tag_id INT NOT NULL, article_id INT NOT NULL, PRIMARY KEY(tag_id, article_id))'); // эта такая же, но автоматически сгенерированная

как так-то? почему их две? как сделать так, чтобы создавалась и использовалась только та, которую я указал?
209 1120597
>>20589
нашел свой косяк лол. я оказывается в обоих сущностях писал inversedBy, а надо в одной писать mappedBy.
210 1120604
>>20574
как и везде, на начальном уровне несложная. пдо - это не только про БД, как правильно сказали, сначала надо освоить азы sql, уметь создавать таблицы, выбирать-добавлять-изменять-удалять данные через консоль. пдо - это встроенная библиотека пхп, предоставляющая несколько классов для работы с БД и предполагающая, что ты будешь использовать определенный подход при работе с ней
2Kxudo02GtA.jpg138 Кб, 1501x1058
211 1120618
Привет! Прохожу урок по работе со встроенным в PHP веб-сервером.
Почему-то не работает пример из урока, который должен был посчитать сумму двух чисел. Браузер выводит просто пустую страницу. Хотя hello world из прошлого примера срабатывает нормально.
Подскажите пожалуйста,что я делаю не так?
213 1120620
>>20618
>>20619
Разобрался сам. Ошибка была в том, что я забыл сохранить этот файлик, что пытался запускать ._.
214 1120621
>>20618
укажи в начале страницы (до хедера)
error_reporting(E_ALL);
ini_set("display_errors", 1);

и посмотри, что выводится. по коду должно все ок быть
215 1120622
>>20574
>>20604

>выбирать-добавлять-изменять-удалять данные через консоль.


Лучше через phpmyAdmin или его аналог для других баз. Там наглядно можно видеть текст запроса, манипулируя интерфейсом. Пробовать менять запрос, вводить свои.
216 1120627
>>20620
Вот для таких случаев и придуман дебаггер. Прямо построчно выполняет программу и после каждого шага ты можешь посмотреть значения любой переменной.
217 1120657
Аноны, а кто-нибудь из вас согласился бы поучастовать бесплатно в написании просмотрщика трейсов от xdebug? "Поучаствовать" здесь значит "сделать проект целиком", конечно.

Трейсы позволяют найти, какие функции в коде дольше всего выполнялись, найти проблемные места, из-за которых страница долго рендерится. Вроде в платных IDE есть просмотр трейсов, но хочется бесплатный инструмент.

Трейсы - это не то же, что результат профайлинга. Это именно последовательность вызовов всех функций в коде. Трейсы с реальных сайтов обычно весят десятки или сотни мегабайт, что добавляет интереса. Сами понимаете, расковырять такой лог вручную нереально.

Если есть заинтересованные люди, через пару-другую недель я распишу задачу подробнее.

Есть такой проект: https://habrahabr.ru/post/242275/ - но он вроде не показывает время и вообще, это не то.

Есть такой: https://github.com/tungnguyenson/xdebug-trace-explorer

Есть такой: https://github.com/corretge/xdebug-trace-gui

Есть такой: https://www.splitbrain.org/blog/2016-02/27-visualizing_xdebug_traces - это очень отдаленно напоминает то, что хотелось бы увидеть.

Есть такой http://thomashamba.ch/xdebug-trace-file-parser.html

Есть вопрос на SO: https://stackoverflow.com/questions/1456395/xdebug-trace-gui
218 1120660
Еще в Хроме в отладчике есть мощные средства для просмотра разных трейсов (вроде https://chromedevtools.github.io/timeline-viewer/ ), можно еще рассмотреть вариант конвертировать PHP трейс в JSON, который скушает и отобразит Инспектор.
219 1120661
Вот еще из Хрома: https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/timeline-tool

Было бы неплохо этот прекрасный интерфейс задействовать или сделать аналогичный.
220 1120662
>>20657

> просмотрщика трейсов от xdebug?


Там что-то может быть сложным?
221 1120664
>>20662

Чем ты трейсы просматриваешь/просматривал бы при условии что они начинаются с несколько десятков Мб и соответственно сотен тысяч вызовов?
222 1120667
>>20664
Ну тот же екселевский файлик на гиг ты же парсишь как-то. В чём тут сложности?
223 1120711
>>18555 (OP)
Анон, подскажи, как запилить передачу даты из формы?

У меня затуп, как правильно передать GET.
224 1120805
Какой же у пхп хреновый мануал. это просто невыносимо.
http://php.net/manual/ru/
225 1120840
>>20805
ты бы сначала сравнил с мануалами других языков, что ли
226 1120858
>>20840
у жс нормальный мануал.
227 1120864
Вопрос по вёрстке.
Есть ячейка <td></td> произвольной ширины.
Внутри должен быть <input></input> и <button></button>.
Кнопка строго 23х23 пикселя, прижата вправо. А инпут должен быть резиновым, занимая всё оставшееся место ячейки.
Вроде простая задача, но я не осилил.
228 1120867
Анон, подскажи регулярку для preg_split, чтобы в массив уходили только числа.
229 1120868
>>20864
Шаманить с padding, marning и bottom, не?
230 1120870
>>20868
Шаманю. Результат - либо фиксированная ширина инпута, либо элементы выходят за пределы ячейки и всю таблицу разносит к хренам.
231 1120871
>>20870
Чтобы не было фиксированной нужно задавать не в пикселях значения. Залей пример кода на пастебин или ещё куда
232 1120873
Пожалуйста, подскажите почему это не работает.
Вроде нормально сделал, но INSERT не проходит.
https://ideone.com/EYyhPq
233 1120875
>>20871
Что-то типа такого: https://jsfiddle.net/dj03n8sj/
Только там вообще даже в одну строку всё не умещается. У мен уже голова квадратная, с утра получше сделаю.
234 1120880
>>20498
У тебя не должно было быть цикла for.

>>20867
/[^\d]/

>>20864
Покажи код.
235 1120888
>>20875
Если можно бы было использовать calc()
https://jsfiddle.net/dj03n8sj/1/
236 1120889
>>20028
Первую задачу где?

>>20282

>Я много слышал про разделение логики приложения и логики представления, но с пагинацией я немного запутался, есть класс, в одном из методов которого я просто через цикл печатаю ссылки на экран, а потом объект пагинации передаю во вью, так нормально делать?


Не совсем, ты должен передавать в шаблон переменные с результатом, и уже в нём (шаблоне) выводить циклом

Например

for ($i = 0; $i < $pageCount; $i++) {
<a ...>$i</a>
}

>И еще вопрос по неймспейсам, если у меня например класс вью называется App\View\View , а шаблоны лежат например в App/templates, как лучше всего подключить шаблоны уровнем ниже(выше?) неймспейса? Я пытался как-то изворачиваться с двойными точками, но полное понимание так и не пришло.


__DIR__ . '/../level/up/path'

Вообще, обычно, папка с шаблонам находятся снаружи снаружи папки приложения
237 1120892
>>20864
У td пишешь display: flex у инпута width: 100%;
238 1120902
>>20873
Бамп вопросу, вы что, pdo не знаете? Не стыдно?
239 1120919
>>20902
Не пиши на венде локалхост. Это так, к слову.
По поводу кода: мы тут не обязаны угадывать "у миня там ни праходит ряяя". Пиши четко, какая ошибка. Если пусто ,как у тебя в голове, въеби PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION и оберни скрипт в try—catch, опять же скажешь ошибку сюда, ну пшёл бля нах быстра!
240 1120952
>>20308
Сука уже подумал что это мой скрин. Сталкнулся с точно таким же говном и тоже номера телефонов ебашил. В бэкслеше броблема
241 1120964
>>20919
А как писать если не локалхост? Работает же.
А в коде, в 13 строчке $dbh->execute([NULL,$task,0,$taskDate]) or die ("Problems adding!"); срабатывает or die ("Problems adding!").
242 1120967
>>20873

Тебе надо включить режим выброса исключений в PDO, иначе ты не увидишь сообщение об ошибке. передать этот параметр можно через конструктор или как в коде тут:

http://php.net/manual/ru/pdo.error-handling.php

Ставить try/catch не требуется. Просто включи у себя display_errors= 1 в php.ini и ошибка будет выведена на экран. Если проблема на хостинге, то на экран может и не вывестись, смотри тогда логи ошибок.
243 1120977
>>20964
По крайней мере у меня, по крайней мере на семерке локалхост в майэскуэл работает намного медленнее 127.0.0.1 , попробуй поменять? На хрюше было норм, десятку нахуй родили непонятно.

Экзекьют возвра... ты читал доки а?? Не маневрируй — это тебе не поможет! Ошибку давай сюда але.
244 1120998
>>20711
Форму правильней передать POSTом. Для этого в теге <form .... method=POST>

Параметры в скрипте будут доступны в массивах $_POST и $_REQUEST
245 1121055
>>20998

Метод зависит от вида формы.

GET - для форм, не изменяющих состояние сервера, с небольшим объемом данных, и чтобы можно было поделиться/сохранить ссылку на результат (например: поиск, сортировка, переход к странице)

POST - для форм, меняющих состояние сервера, для форм с закачкой файлов, для больших объемов данных. Ссылкой поделиться нельзя, при обновлении страницы выскочит предупреждение.
Laughter-e1460729421204.jpg32 Кб, 600x439
246 1121079

>New google search design

247 1121098
У меня вопрос по бутсрапу. После добавления php кода из урока с ООП перестал работать hover.
https://ideone.com/ZSKmtw
Что я делаю не так и как отлаживать такие моменты?
248 1121100
>>21098
50 строка, если что.
249 1121122
>>21055
>>20998
Мне говорили, что с ВЕБ формы все уходит строкой и передается только get-ом.

>>20880
https://ideone.com/cNjfkw

У меня какая-то хуйня в массив попадает.
250 1121136
mb_internal_encoding("UTF-8")
не работает на ideone.com?
252 1121146
>>21144
Сорре, в глаза долблюсь, не увидел ideone.
253 1121156
>>21122
Нумерной массив всегда начинается с индекса 0, а ты полагаешь с единицы.
254 1121158
>>21156
Костыль.
При юзанье этого кода https://ideone.com/ZTztnt получается такой результат: -----12------13array(3) { [0]=> string(0) "" [1]=> string(2) "12" [2]=> string(2) "13" } 1213
255 1121159
>>21098
Ты выбрал нелучшее место для php кода. Если пхп покажет warning, то этот текст попадет в код твоей страницы между head и body. Броузер интерпретирует этот текст как начало body, а реальный боди будет игнорировать.
256 1121160
>>21159
Но варнингов не было и отображается всё нормально кроме hover.
Воть - http://just4lulz.tk/oop.php
257 1121164
>>21158
Это точно так задумано что в качестве разделителя строки на массив выступает комбинация 0- ?
258 1121166
>>21164
Я искал любые меры, чтобы выбросить нуль, который забирается в первый индекс массива.
[0]=> string(0) ""
259 1121172
>>21166
В уроке по регуляркам была нужная тебе функция.
260 1121174
>>21172
Я попробовал все 4, но проблема в самом регулярном выражении.
261 1121181
>>21160
Посмотри, вот у меня никакой нолик не закрадывается.
https://ideone.com/tD8Im8
262 1121186
>>21166

>[0]=> string(0) ""


ПОНЯтно. Это потому что твой разделить срабатывает на начало строки.
263 1121197
>>21122

>Мне говорили, что с ВЕБ формы все уходит строкой и передается только get-ом.


задумайся о круге своего общения лол
264 1121233
>>21186
Хз. Я уже и так написал:

$regexp = '/[\s]+/';
$str = preg_replace("/\D/", ' ', $_GET[num]);
echo $str;

$nig= preg_split ($regexp, $str);

Воз и ныне там.

>>21197
Ну я ж хикка!

И как тогда правильно передавать значения с формы в пхп-скрипт?
265 1121241
https://symfony.com/blog/the-end-of-silex
силекс все

>>21233

>И как тогда правильно передавать значения с формы в пхп-скрипт?



смотря какие значения. особенность гета в том, что его параметры можно сохранить как ссылку и добавить в закладки, отправить другу и т.д. поэтому его используют в основном для путей. все остальное идет в пост, т.к. он во-первых защищает переданные данные при наличии https-соединения, а во-вторых, там нет ограничения на размер передаваемых данных.

также тебе никто не мешает передавать пост-запрос вместе с гет-параметрами (просто подставляя их в УРЛ). тогда и в $_POST, и в $_GET прилетят данные. подробнее (в комментах хорошее пояснение про неадекватность названия массива $_GET):
http://grokbase.com/t/php/php-general/112ckcxw97/using-both-get-and-post-in-the-same-page
266 1121243
Ребята, хочу удалить все аудиозаписи в vk. Вручную удалять не вариант. Один анон советовал полгода назад мне этот скрипт:

// ==UserScript==
// @name 2
// @author 1
// @match https://vk.com/audio*
// @require http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js
// ==/UserScript==

var a = $('#delete').click();
location.reload();

Я кидал его в tampermonkey и все работало. А сейчас не получается. Подскажите, что можно сделать?
267 1121244
>>21241
Мне не нужны закладки, но у меня была проблема в том, что через форму поступает тип данные не "дата", а строка.
Пришлось даже массивом разбивать и собирать заново, чтобы привести к формату, который требуется.
268 1121260
>>20892
Блин, точно, флекс. Спасибо.
>>20888
Не знал, что такое есть. Ведёт себя немного по другому, но тоже подходит.

Ещё вопрос по бутстрапу. Какой путь кастомизации бутстрапа в Yii2 наиболее фен-шуйный? Мне нужно убрать padding у ячеек таблицы. В tables.less написано padding: @table-cell-padding;, а сам этот параметр прописан в variables.less. Но его изменение ничего не даёт. Гугл заводит то в перекомпиляцию бутстрапа, требующую NodeJS и ещё чего-то, то в принудительное отключение бутстрапа из зависимостей Yii и ручное подключение бутстрапа, сгенерированного с нужными параметрами на https://getbootstrap.com/docs/3.3/customize
Как это вообще делается правильно?
269 1121280
>>21244
у тебя по-моему нет понимания что за что отвечает. в пхп и нет такого типа "дата". это может быть ты имешь в виду тип поля в html, он не имеет никакого отношения к типу данных, который есть в ЯП.

для пхп (и для других языков) "дата" - это циферки, которыми он манипулирует с помощью функций и классов, описанных у ОПа в уроке
https://github.com/codedokode/pasta/blob/master/php/datetime.md

или озвучь вопрос более конкретно.
270 1121283
>>21260
Раньше лепили float ко всему где только можно, теперь flex и grid. У ячейки таблицы есть свой display, а менять его на flex? А нужна ли тогда таблица вообще? Таблица — для вывода табличных данных. Да, понятно что соблазнительно воспользоваться ей для автоматического выранивания сеточки, но мне лично кажется это неправильным.

Да, при желании содержимым ячейки можно поставить span или div c флексбоксом, внутрь которого запихнуть хоть анус Девы Марии, так чего бы весь сайт не засунуть туда а не только инпут с кнопкой?

>кастомизации бутстрапа


А какие варианты есть?
1) В своем стиле переопределить селекторы и подрубить его поверх.
2)

>ручное подключение бутстрапа, сгенерированного с нужными параметрами


Это когда уже определился со стилями, на финалочку.

>Have an existing configuration? Upload your config.json to import it.


Может быть, у тебя уже есть основное, загрузи и подредактируй что нужно.

3)

>Но его изменение ничего не даёт


Ну как бы ты не должен лезть в папку vendor, если я тебя правильно понимаю. Все изменения должны накатываться в твоем приложении.

А если я неправильно понимаю, может быть ты что-то неправильно сделал, поэтому оно не отобразилось.
271 1121285
>>21280
Окей, тогда опишу целиком систему:
Пользователь вводит дату через форму HTML с type="date"
Дату нужно привести к определенному формату.
После этого, она вставляется в ссылку.
Я кликаю по ссылке и перехожу на сайт, который хавает геты и выдает мне нужное окно.

Как я это сделал:
https://ideone.com/nVbAXT
272 1121289
>>21283

>В своем стиле переопределить селекторы и подрубить его поверх.


Не плучается. Подключаю css, в нём стили для td (к примеру). border почему-то удаётся изменить, а padding и margin нет, как будто они не учитываются вообще. Не понимаю, почему так происходит.

>Это когда уже определился со стилями, на финалочку.


Тоже не совсем понятно. Просто сгенерировать bootstrap на сайте и заменить им потороха папки vendor\bower\bootstrap ? Или отключить дефолтный бутстрап и рядом положить сгенерированный, подключив его в Ассетс?
273 1121301
>>21289

>Не плучается


Твой стиль подключаешь последним в списке? Может фреймворк где-то после тебя сует стили, а ты не видишь.

Если уверен что ты папа:

Тогда открывай инструменты разработчика и смотри:
а) код самой готовой страницы, какие стили идут за какими, убедись все-таки, что ты последний
б) уже скомпилированные значения. Смотри всю историю, кто где padding-и на td менял. (инспектировать элемент)

Бутстрап с помощью js может тебе нагадить уже после загрузки страницы.

Еще раз: ты не должен лезть в вендор! Эти вещи писал не ты, и не тебе их редактировать. Раз ты используешь bower, там должно быть что-то наподобие нашего composer-овского конфига, вот в нем ты можешь переписать пути на папку assets (ну или как там это в твоем фреймворке делается вообще ;))
274 1121302
>>21285
почему такие странные названия переменных? зачем массив - str_replace же есть?
+ валидация где?

я бы так сделал:
$userDate = array_key_exists($_GET['from']) ? strval($_GET['from']) : '';

if (!preg_match('~^(19|20)\d\d[-](0[1-9]|1[012])[-](0[1-9]|[12][0-9]|3[01])$~', $userDate)) {
throw new InvalidArgumentException('Incorrect data format'); // можешь на die() заменить
}

$date = str_replace('-', '/', $userDate);
275 1121305
>>21302
Ему надо поменять местами в дате год месяц число (отформатировать как требует сторонний ресурс).
276 1121306
>>21285
>>21302
>>21305
Алсо просто ору

>With HTML5 support, web designer no longer needs to download fancy Javascript control for basic date input. Exactly what you need to do is just <input type="date"/> Once again HTML5 has made our life easier!

277 1121307
Привет, анончик. Есть два массива.

$names = ['Helen', 'Mike', 'Alice', 'Lena', 'Ana', 'Max', 'Bob'];
$rates = [1, 4, 5, 3, 8, 9, 10];

Можно ли c помощью какой-нибудь команды сделать значения массива $names индексами массива $rates?
Или по любому придется назначать индексы вручную?Как-то не очень удобно.
279 1121336
>>21305
а. ну тогда
$date = date('d/m/Y', strtotime($userDate));
280 1121350
>>21315
Большое спасибо
281 1121464
Решил дописать в урок про студентов раздел про контроль версий и хостинги репозиториев. Естественно, я не хочу всех отправлять на гитхаб, а хочу предложить выбор, и решил добавить битбакет. Замучался искать пример какого-нибудь хорошо оформленного PHP проекта. Вы такого не знаете?
282 1121466
А тут есть фрилансеры?
283 1121468
А в чем отличие жс треда, от этого или фронтэнд треда в воркаче? Надо и вас почитать наверное.
14982082931850.jfif137 Кб, 900x1200
284 1121556
Поясните за такую хуйню в PHP.
Превращаю все варнинги в эксепшены.

function exception_error_handler($severity, $message, $file, $line) {
throw new ErrorException($message, 0, $severity, $file, $line);
}
set_error_handler('exception_error_handler');

Пишу такой код:
try {
$content = file_get_contents($url, false, stream_context_create($request_headers));
} catch (ErrorException $e) { // обрабатываю }

Без превращения варнингов в эксепшены переменная $content всегда определена.
А, сука, если превращать - то при эксепшене undefined variable, сука! Да как так-то?! А как мне вытянуть значение функции, если там незначительный нотис выскочил (а при этом нотисы я хочу тоже кидать исключениями)? На самом деле ясно как - надо писать воркараунд в exception_error_handler для конкретного, сука, варнинга, и не кидать на него исключение.
Это же пиздец. Кто это проектировал?! Почему нельзя запустить exception_error_handler после того, как строка отработала, а не во время работы функции! Процедурный код же не рассчитан на такое поведение, он рассчитан, что он срет ошибками и при этом невозбранно возвращает значение! Ааааааааааааа

Вот что мне делать, если я хочу получать $content и при этом кидать эксепшены? Хуячить собаку на file_get_contents, затем чекать error_get_last()? А как я узнаю, что это ошибка именно с предыдущей строки?
285 1121560
объясните плизки что за параша registerServiceWorker в create-react-app? все на england языке никак понять не могу
286 1121561
>>21556

Надо создать и заполнить переменную $content в catch.
https://github.com/moabit/student-list/ 287 1121562
>>1117075
>>1117974
>>18558

Я там обновил комментарии к задаче, посмотри, может что нового прочтешь.

> https://github.com/moabit/student-list/blob/master/composer.json#L5


> "fzaninotto/faker":"^1.7.1"



Это лучше было бы прописать в require-dev, то есть в зависимости для разработки. На продакшене ведь faker не требуется.

> https://github.com/moabit/student-list/blob/master/config.json


Этот файл используется в git и тут есть проблема: если разработчик склонирует твой проект и пропишет какие-то настройки, то он может закоммитить назад в проект измененный файл. Решение я описал в уроке: https://github.com/codedokode/pasta/blob/master/student-list.md#Скрытие-файлов-из-репозитория

> https://github.com/moabit/student-list/blob/master/public/index.php


> ini_set('display_errors', 1);


Это лучше прописывать в php.ini, а то не хочется, чтобы на продакшене ошибки выводились. Можно конечно прописать настройку в конфиге, но непонятно зачем дублировать функционал php.ini.

> https://github.com/moabit/student-list/blob/master/app/container.php#L20


> SET NAMES utf8mb4,


Вроде в PDO сделали опцию charset в конструкторе или в DSN.

https://github.com/moabit/student-list/blob/master/app/container.php#L35

> $container['pager'] = function ($c) {


Это не имеет смысла, так как у Pager есть конструктор. Также, ты по идее должен не переиспользовать один экземпляр Pager, а создавать каждый раз новый.

Также, мне кажется, в контейнере не стоит хранить классы с состоянием вроде Authorisation, а стоит создавать новую копию при каждом обращении. Представь, что мы обрабатываем 2 HTTP-запроса подряд. Первый запрос изменит состояние авторизации, и оно может повлиять на выполнение второго запроса.

> throw new RouterException('Неправильный путь');


надо назвать класс лучше, так как этот класс генерирует 404 и должен использоваться только в таких ситуациях, когда надо отдать 404. Например, RouteNotFoundException или Http404Exception.

> https://github.com/moabit/student-list/blob/master/app/Controllers/Controller.php#L18


> protected $view;


Эту переменную наверно лучше назвать twig

https://github.com/moabit/student-list/blob/master/app/Controllers/Controller.php#L37
Может, тут лучше было сделать абстрактную функцию index?

https://github.com/moabit/student-list/blob/master/app/Controllers/Controller.php#L42

> protected function getUserData()


Не очень понятно назначение метода. Он точно должен быть в каждом контроллере?

https://github.com/moabit/student-list/blob/master/app/Controllers/ProfileController.php
здесь наверно лучше было бы сделать все же общую функцию для редактирования/регистрации, чтобы не передавать данные через поля. Такая передача данных затрудняет анализ логики кода.

> if (Util::checkCSRFToken() == false) {


Можно писать if (!Util::checkCSRFToken()), почитай про булевы значения.

https://github.com/moabit/student-list/blob/master/app/Controllers/ProfileController.php#L60

> $this->c['authorisation']->signIn($token);


> $student->setToken($token);


вот тут есть тонкий момент. Что, если мы сгенерируем токен, поставим куку, а потом скрипт упадет, не записав данные в БД. Пользователь останется с кривым токеном. Это не проблема? Хотя, если сделать наоборот, может получиться, что мы создадим пользователя в БД, а куку не выдадим - будет еще хуже.

https://github.com/moabit/student-list/blob/master/app/Controllers/ProfileController.php#L97

> $student->setName(ucfirst(trim(strval($_POST['name']))));


ucfirst не работает: https://github.com/codedokode/pasta/blob/master/php/strings-utf8.md

https://github.com/moabit/student-list/blob/master/app/Controllers/ProfileController.php#L93

> $student = new Student;


> if ($this->user) {


> $student->setID($this->user->getID());


> }


При обновлении данных лучше сделать так: загрузить студента из БД и затем обновить ему поля из POST. А то в твоем случае, если добавить какие-то новые поля, которые не редактируются через форму, но хранятся в БД и есть в объекте, то они могут потеряться при редактировании.

> private function editUser($token): void


Для $token можно поставить тайп-хинт

https://github.com/moabit/student-list/blob/master/app/Database/StudentDataGateway.php#L36

> if ($search != null) {


> $search = trim($search);


Если передать строку из одних пробелов, найдутся все студенты.

https://github.com/moabit/student-list/blob/master/app/Database/StudentDataGateway.php#L54

> @return array


> public function getStudents


лучше писать @return Student[] - это несет больше информации - смотри мануал https://docs.phpdoc.org/guides/types.html

> public function getStudents($orderField, $direction, $limit, $offset, $search = null):


Тайп-хинтов бы сюда завезти...

> throw new \PDOException('Неверный параметр сортировки');


В сообщение можно добавить значение ошибочных параметров для упрощения отладки.

Также, в коде маловато комментариев. Я бы советовал тебе взять за правило писать сначала комментарий к классу, а только потом сам класс.

https://github.com/moabit/student-list/blob/master/app/Helpers/Authorisation.php#L75

> return $this->isAuth;


тут не return null должно быть?

https://github.com/moabit/student-list/blob/master/app/Helpers/ErrorHandler.php#L33

> header("HTTP/1.0 404 Not Found");


> echo "Страница с таким адресом не существует";


без указания кодировки кириллица может не отобразиться. Добавь либо Content-Type либо тег meta charset. Также, на мобильных надпись будет выводиться очень мелко, можно добавить meta viewport.

https://github.com/moabit/student-list/blob/master/app/Helpers/Util.php#L27

> throw new ConfigException('Ошибка в файле конфигурации');


Стоит тут добавить текст JSON ошибки.

https://github.com/moabit/student-list/blob/master/app/Helpers/Util.php#L58

> $_COOKIE['CSRFToken'] != $_POST['CSRFToken']


Тут надо использовать строгое сравнение. Также, надо проверить случай, когда оба значения пусты.

https://github.com/moabit/student-list/blob/master/app/Validators/StudentValidator.php
Тайп-хинтов бы побольше.

https://github.com/moabit/student-list/blob/master/app/addStudents.php
Это лучше было наверно сделать в виде cli скрипта.

> $student->setSurname($faker->lastName.'а');


Faker не умеет в женские фамилии? Не хочешь исправить этот баг и законтрибутить исправление в Faker на благо всех? Сначала, конечно, надо повнимательнее изучить Faker, может там уже есть решение.

https://github.com/moabit/student-list/tree/master/app/views/templates
Может, стоит эту папку вынести на верхний уровень?

https://github.com/moabit/student-list/blob/master/app/views/templates/studentlist.twig

> {% if students is not empty %}


> много строк


> {% else %}


> <h4 class="text-center m-4 text-muted">По вашему запросу ничего не найдено</h4>


> {% endif %}


Лучше может быть короткий блок ставить сверху. Для читабельности.

> >{{ pager.search|e }}


В твиге автоэкранирование.

> {% elseif pager.notify=='registered' %}


Это как-то неправильно, что pager используется для хранения нотификаций, согласись? Это не его задача.

> <a href="?{{ pager.getSortingLink('name') }}"


Лучше возвращать ссылку уже с вопросом, а не собирать ее так по кускам.

Для twig надо бы включать strict_variables. Иначе он не скажет об отсутствующей переменной.

Вообще, код выглядит очень неплохо. Ты ведь наверно не начинающий? Может тогда автоматические тесты сделаешь? Урок есть: https://gist.github.com/codedokode/a455bde7d0748c0a351a
https://github.com/moabit/student-list/ 287 1121562
>>1117075
>>1117974
>>18558

Я там обновил комментарии к задаче, посмотри, может что нового прочтешь.

> https://github.com/moabit/student-list/blob/master/composer.json#L5


> "fzaninotto/faker":"^1.7.1"



Это лучше было бы прописать в require-dev, то есть в зависимости для разработки. На продакшене ведь faker не требуется.

> https://github.com/moabit/student-list/blob/master/config.json


Этот файл используется в git и тут есть проблема: если разработчик склонирует твой проект и пропишет какие-то настройки, то он может закоммитить назад в проект измененный файл. Решение я описал в уроке: https://github.com/codedokode/pasta/blob/master/student-list.md#Скрытие-файлов-из-репозитория

> https://github.com/moabit/student-list/blob/master/public/index.php


> ini_set('display_errors', 1);


Это лучше прописывать в php.ini, а то не хочется, чтобы на продакшене ошибки выводились. Можно конечно прописать настройку в конфиге, но непонятно зачем дублировать функционал php.ini.

> https://github.com/moabit/student-list/blob/master/app/container.php#L20


> SET NAMES utf8mb4,


Вроде в PDO сделали опцию charset в конструкторе или в DSN.

https://github.com/moabit/student-list/blob/master/app/container.php#L35

> $container['pager'] = function ($c) {


Это не имеет смысла, так как у Pager есть конструктор. Также, ты по идее должен не переиспользовать один экземпляр Pager, а создавать каждый раз новый.

Также, мне кажется, в контейнере не стоит хранить классы с состоянием вроде Authorisation, а стоит создавать новую копию при каждом обращении. Представь, что мы обрабатываем 2 HTTP-запроса подряд. Первый запрос изменит состояние авторизации, и оно может повлиять на выполнение второго запроса.

> throw new RouterException('Неправильный путь');


надо назвать класс лучше, так как этот класс генерирует 404 и должен использоваться только в таких ситуациях, когда надо отдать 404. Например, RouteNotFoundException или Http404Exception.

> https://github.com/moabit/student-list/blob/master/app/Controllers/Controller.php#L18


> protected $view;


Эту переменную наверно лучше назвать twig

https://github.com/moabit/student-list/blob/master/app/Controllers/Controller.php#L37
Может, тут лучше было сделать абстрактную функцию index?

https://github.com/moabit/student-list/blob/master/app/Controllers/Controller.php#L42

> protected function getUserData()


Не очень понятно назначение метода. Он точно должен быть в каждом контроллере?

https://github.com/moabit/student-list/blob/master/app/Controllers/ProfileController.php
здесь наверно лучше было бы сделать все же общую функцию для редактирования/регистрации, чтобы не передавать данные через поля. Такая передача данных затрудняет анализ логики кода.

> if (Util::checkCSRFToken() == false) {


Можно писать if (!Util::checkCSRFToken()), почитай про булевы значения.

https://github.com/moabit/student-list/blob/master/app/Controllers/ProfileController.php#L60

> $this->c['authorisation']->signIn($token);


> $student->setToken($token);


вот тут есть тонкий момент. Что, если мы сгенерируем токен, поставим куку, а потом скрипт упадет, не записав данные в БД. Пользователь останется с кривым токеном. Это не проблема? Хотя, если сделать наоборот, может получиться, что мы создадим пользователя в БД, а куку не выдадим - будет еще хуже.

https://github.com/moabit/student-list/blob/master/app/Controllers/ProfileController.php#L97

> $student->setName(ucfirst(trim(strval($_POST['name']))));


ucfirst не работает: https://github.com/codedokode/pasta/blob/master/php/strings-utf8.md

https://github.com/moabit/student-list/blob/master/app/Controllers/ProfileController.php#L93

> $student = new Student;


> if ($this->user) {


> $student->setID($this->user->getID());


> }


При обновлении данных лучше сделать так: загрузить студента из БД и затем обновить ему поля из POST. А то в твоем случае, если добавить какие-то новые поля, которые не редактируются через форму, но хранятся в БД и есть в объекте, то они могут потеряться при редактировании.

> private function editUser($token): void


Для $token можно поставить тайп-хинт

https://github.com/moabit/student-list/blob/master/app/Database/StudentDataGateway.php#L36

> if ($search != null) {


> $search = trim($search);


Если передать строку из одних пробелов, найдутся все студенты.

https://github.com/moabit/student-list/blob/master/app/Database/StudentDataGateway.php#L54

> @return array


> public function getStudents


лучше писать @return Student[] - это несет больше информации - смотри мануал https://docs.phpdoc.org/guides/types.html

> public function getStudents($orderField, $direction, $limit, $offset, $search = null):


Тайп-хинтов бы сюда завезти...

> throw new \PDOException('Неверный параметр сортировки');


В сообщение можно добавить значение ошибочных параметров для упрощения отладки.

Также, в коде маловато комментариев. Я бы советовал тебе взять за правило писать сначала комментарий к классу, а только потом сам класс.

https://github.com/moabit/student-list/blob/master/app/Helpers/Authorisation.php#L75

> return $this->isAuth;


тут не return null должно быть?

https://github.com/moabit/student-list/blob/master/app/Helpers/ErrorHandler.php#L33

> header("HTTP/1.0 404 Not Found");


> echo "Страница с таким адресом не существует";


без указания кодировки кириллица может не отобразиться. Добавь либо Content-Type либо тег meta charset. Также, на мобильных надпись будет выводиться очень мелко, можно добавить meta viewport.

https://github.com/moabit/student-list/blob/master/app/Helpers/Util.php#L27

> throw new ConfigException('Ошибка в файле конфигурации');


Стоит тут добавить текст JSON ошибки.

https://github.com/moabit/student-list/blob/master/app/Helpers/Util.php#L58

> $_COOKIE['CSRFToken'] != $_POST['CSRFToken']


Тут надо использовать строгое сравнение. Также, надо проверить случай, когда оба значения пусты.

https://github.com/moabit/student-list/blob/master/app/Validators/StudentValidator.php
Тайп-хинтов бы побольше.

https://github.com/moabit/student-list/blob/master/app/addStudents.php
Это лучше было наверно сделать в виде cli скрипта.

> $student->setSurname($faker->lastName.'а');


Faker не умеет в женские фамилии? Не хочешь исправить этот баг и законтрибутить исправление в Faker на благо всех? Сначала, конечно, надо повнимательнее изучить Faker, может там уже есть решение.

https://github.com/moabit/student-list/tree/master/app/views/templates
Может, стоит эту папку вынести на верхний уровень?

https://github.com/moabit/student-list/blob/master/app/views/templates/studentlist.twig

> {% if students is not empty %}


> много строк


> {% else %}


> <h4 class="text-center m-4 text-muted">По вашему запросу ничего не найдено</h4>


> {% endif %}


Лучше может быть короткий блок ставить сверху. Для читабельности.

> >{{ pager.search|e }}


В твиге автоэкранирование.

> {% elseif pager.notify=='registered' %}


Это как-то неправильно, что pager используется для хранения нотификаций, согласись? Это не его задача.

> <a href="?{{ pager.getSortingLink('name') }}"


Лучше возвращать ссылку уже с вопросом, а не собирать ее так по кускам.

Для twig надо бы включать strict_variables. Иначе он не скажет об отсутствующей переменной.

Вообще, код выглядит очень неплохо. Ты ведь наверно не начинающий? Может тогда автоматические тесты сделаешь? Урок есть: https://gist.github.com/codedokode/a455bde7d0748c0a351a
288 1121611
>>21302

>почему такие странные названия переменных?


Это лишь часть кода.

>зачем массив - str_replace же есть?


Нужно поменять местами.

>+ валидация где?


На самом деле, переменные будут приходить от другого приложения и нужно просто запилить прослойку.

>$userDate = array_key_exists($_GET['from']) ? strval($_GET['from']) : '';


Сорян, такой код для меня сложен. Можешь объяснить?

>>21336
Т.е. это создаст переменную date из формата 'd/m/Y' и переменной strtotime($userDate) ?
289 1121636
>>21611
UPD разобрался.

Премного благодарен, анон!
290 1121639
>>21611

>Сорян, такой код для меня сложен. Можешь объяснить?



мы не можем просто так взять из гета элемент массива, т.к. если этот параметр (from) не передадут, мы получим нотис от пхп undefined array index 'from'. чтобы этого не было, мы сначала должны убедиться, что элемент с таким ключом существует. мы это делаем внезапно функцией array_key_exists. strval нам приводит значение к типу "строка", как часть валидации опять же.

а тернарный оператор - это такой сахар для задания значения переменной в зависимости от условия. пример:
$foo = isset($bar) ? $bar : $somethingElse;
значит тоже самое, что
if ($isset($bar) {
$foo = $bar;
} else {
$foo = $somethingElse;
}

важно знать, что тернарный оператор - не замена if, то есть нельзя использовать его для реализации логики. только для задания значения переменной.

>Т.е. это создаст переменную date из формата 'd/m/Y' и переменной strtotime($userDate) ?


да
291 1121641
>>21468
в том, что этот про пхп.

>>21464
https://github.com/symfony/demo не? по каким критериям хорошо оформленного?
292 1121644
>>21639

>мы не можем просто так взять из гета элемент массива


Погоди.. что? Я просто написал $datefrom = date('d/m/Y', strtotime($_GET[from])); и все сработало.

>т.к. если этот параметр (from) не передадут


Я просто указал value="2018-01-01" . Я так понял, это костыль был?

Черт! Я только сейчас понял. У меня там ещё одно значение из get бралось и пустое значение дальше передавалось для обработки.
Чтобы этого избежать я написал:

if (empty($country)){
} else{

ну и дальше весь оставшийся код.
293 1121645
>>21641

Нет, мне интересен пример хорошо оформленного проекта на битбакете, а не на гитхабе. У них раньше была ссылочка /explore, но сейчас она убрана, подозреваю, из-за того, что на нем мало публичных известных проектов.
294 1121655
>>21644
ну я не знаю, какой у тебя код и поэтому говорю в общем случае.

если ты запросишь $_GET[blahblah], а его не передадут, то ты получишь php notice в процессе выполнения своего кода. поэтому данную ситуацию надо предусмотреть.

>if (empty($country)){


>} else{



тут два пути. если ты работаешь менеджером или в ТП, а тебя начальник загрузил какой-то временной задачей, то делай как работает и забей. а если ты планируешь дальше работать с пхп для себя или перекатиться, то имеет смысл изучить какой-то минимум основ. иначе будет постоянная боль и непонимание где сломалось, а каждая задача будет отнимать кучу времени.
295 1121691
>>21655

>если ты запросишь $_GET[blahblah], а его не передадут, то ты получишь php notice в процессе выполнения своего кода. поэтому данную ситуацию надо предусмотреть.


Дай угадаю: если у меня там дальше SQL-запрос (сам скрипт для внутреннего пользования и можно не бояться инъекций), то у меня вылезет целая куча говна?

>если ты работаешь менеджером или в ТП,


Этот случай.
НО!

>а если ты планируешь дальше работать с пхп для себя или перекатиться


Посему, воспользуюсь тем, что написал ты.
296 1121703
>>21655
По поводу это строчки:
$userDate = array_key_exists($_GET['from']) ? strval($_GET['from']) : '';

есть ощущение, что я что-то недопонимаю.

array_key_exists - это функция для проверки существует ли что-то в массиве.
1.Для переменных сгодится isset?
Вот так, например.
$userDate = isset($_GET['from']) ? strval($_GET['from']) : '';
2.А разве можно передать массив через форму?

strval - функция для превращения числа в строку. Как итог ты используешь логику "если есть что-то в массиве (у меня "в переменной"), то преврати полученное из гета в строку. в противном случае - пусть будет пустота.
297 1121719
>>21703

> 2.А разве можно передать массив через форму?


Легко:

script.php?a[]=1&a[]=2

В скрипте сделай var_dump($_GET) и посмотри что в 'a'.

Мануал http://php.net/manual/ru/faq.html.php#faq.html.arrays
298 1121723
>>21719
А. Ну через JS. Через html, как я понимаю, нельзя или как-то совсем изъебисто?
299 1121736
>>21703

>А разве можно передать массив через форму?


Форма это и есть массив. У элементов формы есть name и value. И если не ошибаюсь, multiple select может прислать однотипный массив из всех выбранных option value.

$_POST("select") / ["option 1","option 2", ...]

Еще (поправьте меня если нет) можно через URL передать массив:

my.dot.com/?somearray=[eat,my,shorts]&somethingelse=1488

>strval - функция для превращения числа в строку


Не только числа, а всех типов. Приведение к строке (если это возможно). Можно даже объекты в строку превращать и массивы.

>в противном случае - пусть будет пустота


Вернется пустая строка. Именно строка! (пустая, да)

До кучи про тернарный:
(условие) ? (инструкция если условие вернуло true) : (инструкция если условие вернуло false)
giphy.gif2,8 Мб, 480x327
300 1121747
>>21736
Стопэ, посан! Т.е. все это время, когда я брал данные из формы, я брал их из ассоциативного массива?!
301 1121783
>>21691

>вылезет целая куча говна?


она может не вылезти, если у тебя на продакшн-сервере не проставлено error_reporting E_ALL (а оно на проде не проставлено), но в любом случае надо это предусмотреть, т.к. на дев сервере обычно стоит максимально многословный вывод ошибок (если там не легаси) и намеренно генерировать нотисы - это говнокод.

>1.Для переменных сгодится isset?


для простых типов данных годится isset или !empty, в зависимости от того, что нужно (см таблицу сравнения типов в пхп https://secure.php.net/manual/en/types.comparisons.php)

для проверки наличия элемента массива принято использовать array_key_exists. в мануале написано почему https://secure.php.net/manual/ru/function.array-key-exists.php (смотри пример 2).

там некий комментатор писал, что иссет работает быстрее, но возможно в новых версиях пхп это уже не так.

>2.А разве можно передать массив через форму?


можно <input name="arrayname[item1]">
302 1121787
блядь, в доктрине сделал var_dump($entity) и комп подвис на 15 минут, прежде чем я смог его перезагрузить. а у меня на нем крузис запускался лол

заменил его на https://symfony.com/doc/current/components/var_dumper.html
все ок заработало
303 1121818
Посоны поставил php сервер, но он жалуется на mb_ функции Uncaught Error: Call to undefined function mb_internal_encoding(), такой вопрос, а вообще на php7 multibyte string работает?
304 1121835
<?php
error_reporting (-1);
mb_internal_encoding('utf-8');
$a = "Добра тебе \n Выпей чаю";
$b = mb_strlen($a);
echo $b;
Вот код из задачи, при исполнении в браузере выдает следущее
Fatal error: Uncaught Error: Call to undefined function mb_internal_encoding()
hqdefault.jpg8 Кб, 480x360
305 1121844
Библиотека сама есть, кавычки в конфигурационном файле удалил, памагити111
307 1121863
>>21835

>вообще на php7 multibyte string работает


нет, блядь, решили удалить. она же нахуй никому не нужна.

какой смысл спрашивать то, что можно найти в гугле на первой строчке?
308 1121870
>>21844
а, сорян, не увидел. ну php --ini напиши для начала. посмотри, должно быть что-то типа
Configuration File (php.ini) Path: /etc/php/7.2/cli
Loaded Configuration File: /etc/php/7.2/cli/php.ini
Scan for additional .ini files in: /etc/php/7.2/cli/conf.d
Additional .ini files parsed: /etc/php/7.2/cli/conf.d/10-mysqlnd.ini,
/etc/php/7.2/cli/conf.d/10-opcache.ini,
...
/etc/php/7.2/cli/conf.d/20-mbstring.ini,

если такой конфиг есть, посмотри php -m, выдаст установленные расширения

потом попробуй в cli запустить свой код (php -a) и если работает, скопируй конфиг в fpm или cgi, чем ты там пользуешься
309 1121874
>>21783
Не, тут такая ситуация: у меня значение из гет передается в preg_split, чтобы разбить вводимую строку на значения.
Потом эти значения втупую скармливаются sql-запросу и далее, после переработки результата, запиливаются ссылки.
310 1121878
>>21870

Configuration File (php.ini) Path: C:\WINDOWS
Loaded Configuration File: (none)
Scan for additional .ini files in: (none)
Additional .ini files parsed: (none)
311 1121880
Кароче, я понял, что проще апач накатить, чем с этой хуйней ебаться.
312 1121887
помогите с PDO,нихуя не работает. и какой в xammpe пароль?
313 1121898
>>21878

>


>Configuration File (php.ini) Path: C:\WINDOWS


>Loaded Configuration File: (none)


>Scan for additional .ini files in: (no


хуита какая-то. на винде поставь опен сервер, там все из коробки работает
image.png1,3 Мб, 1128x2908
314 1121908
Не понятно что там с php на картинке, какие будут варианты?
315 1121988
>>21908
Индеец стоит на бубнах над С, перепутав голову с задом
316 1121989
>>21723
Нет. JS нахуй. Вот чистый HTML:

<form action="" method=GET>

<input name="yoba[1]" value="23">

<input name="yoba[2]" value="24">

</form>

В пхп скрипте будет доступно по
$_GET['yoba'][1]; // тут 23
$_GET['yoba'][2]; // тут 24

А на самом деле в форме индекс в скобочках можно не указывать. Тогда в скрипте будешь обходить массив
foreach ($_GET['yoba'] as $item) {
echo "$item \n";
}

Вывод:
22
23
317 1121993
>>21878
Файл php.ini положи в одном месте - в директории с php.exe. В файле php.ini расскомменти строку, где подключается mbstring. Убедись, что эта библиотека присутствует у тебя на диске. В файле php.ini также должна быть правильно указана директория extensions. После всех изменений перезагрузи вебсервер.
318 1122003
>>21874

>эти значения втупую скармливаются sql-запросу


enjoy your SQL injection
319 1122007
Крч, есть сайт и надо, чтобы он выглядел как архив, кидаю файл через программу на C#, а она идёт туда и пишет дату, название и его можно открыть (тхт файлы)
Часть на шарпе я то напишу, но вот с пхп не знаю, что делать ;d

отправка ftp
320 1122012
>>22007
Тебе нужен Apache а не php. Даже писать ничего не придется. Программа кидает, а он показывает сразу с датой закидки и его можно октрыть.
321 1122021
>>21787
Нужно документацию читать, а не туториалы от васянов. В первых страницах документации есть объяснение, почему вариант с var_dump работать не будет.

>>21641
Читал обновления в уроке, мне кажется автор переборщил с выбором. Зачем новичку знать про Mercurial, когда от джуна почти 100% будут требовать Git? Зачем другие хостинги кода, если аккаунт на GitHub всё равно рано или поздно появится, ведь без него не создашь issue и не отправишь патч в популярную библиотеку. А тот же BitBucket лежит регулярно, у нас он на работе и я думаю склонять людей к GitLab после этого: https://www.theregister.co.uk/2018/01/10/bitbucket_outage/

Особенности работы с pg-функциями без PDO, ИМХО, стоит вынести в отдельный урок, уж слишком специфично, у новичка глаза разбегутся от обилия информации. Есть ещё такой анти-паттерн - soft coding, его можно применить не только к программированию: идея в том, что человек потерятеся, если дать ему слишком большой выбор. Хорошо, что выбор есть, но тут, как мне кажется, он только усложнит жизнь.

>>21560
https://habrahabr.ru/post/279291/
Мне кажется, что по дефолту добавлять это в CRA это не стоило. Тут до сих пор обсуждают целесообразность этого решения: https://github.com/facebookincubator/create-react-app/issues/2554
322 1122056
Посоветуйте, как сделать drag and drop загрузку файлов. Может уже есть какие-то хорошие готовые решения или мне самому ее писать? Я в жс не очень, поэтому такой вопрос задаю.
323 1122064
>>22056
название файлов в php будут в массиве $_FILES, оттуда их можно переместить в нужную директорию.
324 1122065
>>22021

>Нужно документацию читать, а не туториалы от васянов


о, профессионалы с ценными советами в треде
325 1122073
>>22021

>Мне кажется, что по дефолту добавлять это в CRA это не стоило. Тут до сих пор обсуждают целесообразность этого решения: https://github.com/facebookincubator/create-react-app/issues/2554



чем это от обычного листенера ноды отличается?
326 1122199
>>22073
Тем что листенер деды использовали, а это модное нововведение которое решает множество проблем (тоесть ничем).
327 1122227
>>22199
можешь пожалуйста объяснить как эта штука вообще работает?
до менять что-то совсем не доходит
328 1122230
Аноны, лучей добра если кто-то укажет как улучшить решение задачки про зарплаты из раздела про основы ООП
https://repl.it/repls/NippyGraciousCrayfish
329 1122272
Аноны, помогите кто знает, как можно в php проиграть несколько wav файлов подряд, один за другим?
330 1122276
>>21988

>Индеец стоит на бубнах


Апач стоит на базе данных

>над С


пропасть это С?

>перепутав голову с задом


очень сложно
331 1122279
>>22003
Погодь, но sql-инъекция - это только вид взлома БД. Какое это может иметь отношение к багам?
332 1122346
>>21989
Подожди, я не совсем понимаю твои действия.

То что ты описал - это же простое обращение к форме.

<input name="yoba[1]" value="23">
$_GET['yoba'][1]; // тут 23

<form action="" method="get">
<p><b>Введите название страны:</b><br>
<input type="text" name="country"></p>
$first= preg_split ($regexp, $_GET[country]);

-----------------------------------

Вопрос знатокам: а можно как-то в html-форме задать дате всегда актуальный день?

<p><b>Выберите дату:</b><br>
<input type="date" name="from" value="2018-01-01">

Пока что я вижу путь только через JS.
333 1122352
>>21989
UPD.
Я перечитал твой пост 20 раз, заглянул в предыдущие и все понял.
Проще говоря, ты задаешь поля, как индексы массива, а он уже "собирается" в php скрипте.

Да, из-за своей невнимательности я запутался.

Короч, через форму мне нужно передать только отдельные значения, а не элементы массива. Тот вопрос был больше теоретическим.
334 1122366
Вопрос по SPA задаче. В подсказках написано что нужно сохранять состояние приложения если у клиента оборвалась связь. Окей, если он не закрыл вкладку. А как можно сделать, чтобы он мог в оффлайне открыть это приложение, или если он закрыл уже вкладку с нашим сайтом или вообще браузер/телефон/компьютер перезагрузил?

Когда он в первый раз заходит - у него сохраняется костяк приложения (кешируется джаваскрипт, стили), но как быть с html страничками, они же не кешируются сами по себе?

Допустим я могу и темплейты страниц закешировать (в джаваскрипт).

Но как потом запустить этот джаваскрипт прямо во вкладке, когда нет доступа к сайту? Чтобы можно было работать и потом закоммитить изменения.

Этого я не понимат.
335 1122375
>>22366
PWA, Service Workers
336 1122411
кто vps использует для хостинга сайтов клиентов? вопросики есть:

1. как вы расчитываете мощности? по наитию (тормозит - докупили) или какими-то инструментами/методиками?

2. насколько сильное значение для задержки имеет физическое расположение сервера? допустим, vps в амстердаме, а сайт русский. по идее задержка минимальная, но почему-то все используют русские vps для таких целей.
337 1122413
Подскажите, какая цель таких вот запросов?
SELECT CHAR(113)+CHAR(107)+CHAR(113)+CHAR(107)+CHAR(113)+(SELECT (CASE WHEN (4622=4622) THEN CHAR(49) ELSE CHAR(48) END))+CHAR(113)+CHAR(107)+CHAR(107)+CHAR(106)+CHAR(113))
Да, это sql-инъекции, но какая их роль? В данном случае это просто текст 'qkqkq1qkkjq0', у меня залогированно несколько подобных запросов которые получают текст 'qkqkq1qkkjq0' разными запросами.
338 1122446
>>22413
Посмотреть проходит ли инъекция и какая БД установлена. Скорее всего запросы спамит робот.
339 1122455
>>22366

Там есть варианты (да, какие-то сервис-вокеры), но если ты почитаешь описание, то увидишь, что это самая кривая и неудачная архитектура из всех, что можно было придумать. Поэтому предлагаю не делать такой функционал. Если у клиента постоянно нет связи, для него лучше сделать оффлайн приложение.
340 1122457
>>22411

Русские впс используют, потому что они дешевые (poiskvps). У хостеров часто можно попросить тестовый период и протестировать сайт под нагрузкой. Можно также предложить оплатить эти несколько дней. Также, можно читать отзывы.
341 1122460
>>22375
>>22455
Да уже почитал, выглядит как костыли, не удивительно, что я даже не слышал про такое.

Может быть есть еще варианты? Если сайт ну никак не доступен, взять хоть что-нибудь из кеша (например памятку или инструкцию) и показать?
342 1122462
Изучаю ООП, и параллельно курю MVC. Верно ли суждение, что при создании экземпляра класса, у которого отсутствует конструктор, будет вызываться конструктор родительского класса?
343 1122472
>>22446
Да, робот спамил, так как там порядка 5-6 запросов в секунду приходило. Я тоже подумал, что скорее всего проверка чисто на получение ошибки БД. Нагуглить похожих запросов не вышло и само слово вроде как рандомное, но тогда не ясно, зачем именно это слово впихивалось разными способами в запросы
344 1122473
>>22462
Да но только в случае если у родительского класса конструктор не private метод, так как дочерний класс наследует все public/protected методы от своих родителей
345 1122476
>>22457
спасибо. потестирую

>>22462
верно
346 1122477
>>22462

Да. А если этот конструктор приватный/защищенный, то будет выдана ошибка. Такие конструкторы используют, чтобы запретить создание объекта через new снаружи класса.
350x700px-LL-0cbb0016tumblrmkx6sdtJg91qgime3o.gif981 Кб, 245x245
347 1122497
котаны, где искать пхп макак? смотрю на апворке цены по 50 баксов в час, они там ебанулись вообще?
348 1122500
>>22497

> Ареал макак простирается от Афганистана до Юго-Восточной Азии, а также до Японии. Особенным разнообразием видов отличается остров Сулавеси, где проживают шесть эндемичных видов макак. Единственным представителем семейства, встречающимся за пределами Азии, является магот, живущий в Северной Африке и в Гибралтаре.

349 1122586
>>22500
изящно, лол

>>22497
так это ж ПРОГРАММИРОВАНИЕ. профессия будущего.

если хочешь дешевле, ищи школьников, правда возможно потом будешь с ошпаренной жопой искать кого-нибудь, кто выправит их говнокод, и тебе 50 баксов в час покажутся выгодной сделкой. но ты видать предприниматель, поди любишь риск, азарт, адреналин
350 1122603
кто на vps ставил vestaCP или другие панели? ответьте на вопрос, зачем они нужны, если можно ручками в консоли все поставить самому? особенно учитывая, что они жрут ресурсы, которых на vps мало
15161183136400.jpg4,6 Мб, 3035x2035
351 1122771
Решил зайти поблагодарить ОПа за всю его работу, что он делает и отчитаться об успехах. Не уверен на 100%, что нынешний ОП - тот самый, но, надеюсь, что это так. В любом случае рапортую: в конце 2015 - в начале 2016 года каждый день сидел в этих тредах, изучая погромрование по сайту опа и слушая его советы. На прошлой неделе повысили до миддла бекендщика, компания одна из топовых в рашке. Стек - symfony3, doctrine, redis. Всё пока складывается охуeнно, то ли ещё будет.
Cпасибо, опушка, за всё.
352 1122782
>>1116765

> Чтобы вывести ссылку, ты пишешь в шаблоне {{ path(...) }} . Вместо этого можно сделать класс UrlGenerator, в нем методы вроде getTestsByTagUrl(Tag $tag): string. И использовать их. Выгоды:



Я тебя правильно понял? https://github.com/TheSidSpears/test_hub/commit/48de6c290d05ca63a48a5aa7bf8fbf67fb67fb5f

>> По переменным окружения - не стоит ли добавить им уникальный префикс вроде TH_..., чтобы они были гарантированно уникальными?


> И тут тоже не понял, о каких переменных ты говоришь


Переменные окружения в env.dist - больше их вроде нигде нету.
В этом файле стандартные переменные APP_ENV и DATABASE_URL. Зачем их переименовывать и как их система прочтет? (в этом разобраться самому)

>У Симфони есть куцая статья https://symfony.com/doc/current/testing/database.html и первый вариант (mock entity manager) я не советую делать, это будут очень некачественные и хрупкие тесты



Нужно тестировать репозитории на копии основной БД? А как держать эту БД актуальной? Это ж нужно миграции и там и там проводить. Как-то не удобным это кажется

> Set number of failed attempts for instantly created item


> public function setFailedAttempts($failedAttempts)


Вот такого лучше избегать. Увеличивать число попыток в тесте лучше тем же способом, каким это будет делать приложение, а не делать костыли там, где без них легко обойтись.

> Более того, смотри, ты добавил метод setFailedAttempts для тестов, а затем еще и написал тест для него. Ты тесты ради тестов пишешь, получается? Так делать не надо, это просто трата времени. Тестировать надо тот код, который будет использовать приложение.



Нет, эти 2 ф-ии используются исключительно для заполнения Fixtures. Вот тут https://goo.gl/FB1ikp Собственно, я и тестирую, что они отрабатывают первый раз и больше не срабатывают

>> public function findByTag(Tag $tag){


> Вообще, Доктрина генерирует методы finxByXXX, findOneByXXX, они тут не подошли бы?


Я попытался разобраться https://drive.google.com/file/d/1Gvt38WwASpFcdFU3z9ZDuvrZ3pfaWbun/view?usp=sharing
Видимо, не подойдёт

> Я тут еще хотел посоветовать использовать faker в fixtures, но погуглил, и увидел, что он там уже используется (через alice), интересно. не знал про такую штуку. Ну прекрасно, если вдруг не знаком с ним, изучи faker, пригодится.



Ага, именно их я и использую. Правда до конца разобраться не могу, т.к. я учился на Alice 2, а уже давно существует 3-я версия, её я и поставил. Но в ней много чего поменялось. Долгое чтение документации и дебаг исходников результатов не дал. Позже вернусь к этому

https://github.com/TheSidSpears/test_hub/blob/master/templates/base.html.twig#L22

>> {% if isMainRoute is defined and isMainRoute == true %}



> Вот это мне не нравится. У тебя переменная может быть передана, а может не быть. Как писать надежный код в такой ситуации?



А как быть то? Передавать isMainRoute во всех контроллерах избыточно, а как-то определять, что "вид вызван из MainController" надо

https://github.com/TheSidSpears/test_hub/blob/master/templates/tests/list.html.twig#L34

>Это костыли, нужна нормальная функция-хелпер для склонения чисел, а еще лучше сразу использовать синтаксис для переводимых (локализумых) строк, так как в разных языках правила выбора формы слов разные.



использовать синтаксис для переводимых строк? Это как?

>> public function tagList(Request $request, PaginatorInterface $paginator)


> Почему пагинатор передается в аргументы метода контроллера? Это такой DI?



Как я понял, нужно в конструкторе его определять?

> if ($form->isSubmitted() && $form->isValid()) {


> $searchString = $form->getData()['text'];


> } else {


> $searchString = $request->query->get('text');


> }



> А зачем else?


При переходе на следующую страницу, условие $form->isSubmitted() уже не выполняется, поэтому я беру $searchString из get-параметра

https://github.com/TheSidSpears/test_hub/blob/master/templates/tests/by_tag_list.html.twig
Проверь, соответствует ли имя шаблона гайдлайнам Симфони (я сам не помню).

>Я такого не нашел. Но вот в исходниках имена разделяются нижним подчеркиванием

352 1122782
>>1116765

> Чтобы вывести ссылку, ты пишешь в шаблоне {{ path(...) }} . Вместо этого можно сделать класс UrlGenerator, в нем методы вроде getTestsByTagUrl(Tag $tag): string. И использовать их. Выгоды:



Я тебя правильно понял? https://github.com/TheSidSpears/test_hub/commit/48de6c290d05ca63a48a5aa7bf8fbf67fb67fb5f

>> По переменным окружения - не стоит ли добавить им уникальный префикс вроде TH_..., чтобы они были гарантированно уникальными?


> И тут тоже не понял, о каких переменных ты говоришь


Переменные окружения в env.dist - больше их вроде нигде нету.
В этом файле стандартные переменные APP_ENV и DATABASE_URL. Зачем их переименовывать и как их система прочтет? (в этом разобраться самому)

>У Симфони есть куцая статья https://symfony.com/doc/current/testing/database.html и первый вариант (mock entity manager) я не советую делать, это будут очень некачественные и хрупкие тесты



Нужно тестировать репозитории на копии основной БД? А как держать эту БД актуальной? Это ж нужно миграции и там и там проводить. Как-то не удобным это кажется

> Set number of failed attempts for instantly created item


> public function setFailedAttempts($failedAttempts)


Вот такого лучше избегать. Увеличивать число попыток в тесте лучше тем же способом, каким это будет делать приложение, а не делать костыли там, где без них легко обойтись.

> Более того, смотри, ты добавил метод setFailedAttempts для тестов, а затем еще и написал тест для него. Ты тесты ради тестов пишешь, получается? Так делать не надо, это просто трата времени. Тестировать надо тот код, который будет использовать приложение.



Нет, эти 2 ф-ии используются исключительно для заполнения Fixtures. Вот тут https://goo.gl/FB1ikp Собственно, я и тестирую, что они отрабатывают первый раз и больше не срабатывают

>> public function findByTag(Tag $tag){


> Вообще, Доктрина генерирует методы finxByXXX, findOneByXXX, они тут не подошли бы?


Я попытался разобраться https://drive.google.com/file/d/1Gvt38WwASpFcdFU3z9ZDuvrZ3pfaWbun/view?usp=sharing
Видимо, не подойдёт

> Я тут еще хотел посоветовать использовать faker в fixtures, но погуглил, и увидел, что он там уже используется (через alice), интересно. не знал про такую штуку. Ну прекрасно, если вдруг не знаком с ним, изучи faker, пригодится.



Ага, именно их я и использую. Правда до конца разобраться не могу, т.к. я учился на Alice 2, а уже давно существует 3-я версия, её я и поставил. Но в ней много чего поменялось. Долгое чтение документации и дебаг исходников результатов не дал. Позже вернусь к этому

https://github.com/TheSidSpears/test_hub/blob/master/templates/base.html.twig#L22

>> {% if isMainRoute is defined and isMainRoute == true %}



> Вот это мне не нравится. У тебя переменная может быть передана, а может не быть. Как писать надежный код в такой ситуации?



А как быть то? Передавать isMainRoute во всех контроллерах избыточно, а как-то определять, что "вид вызван из MainController" надо

https://github.com/TheSidSpears/test_hub/blob/master/templates/tests/list.html.twig#L34

>Это костыли, нужна нормальная функция-хелпер для склонения чисел, а еще лучше сразу использовать синтаксис для переводимых (локализумых) строк, так как в разных языках правила выбора формы слов разные.



использовать синтаксис для переводимых строк? Это как?

>> public function tagList(Request $request, PaginatorInterface $paginator)


> Почему пагинатор передается в аргументы метода контроллера? Это такой DI?



Как я понял, нужно в конструкторе его определять?

> if ($form->isSubmitted() && $form->isValid()) {


> $searchString = $form->getData()['text'];


> } else {


> $searchString = $request->query->get('text');


> }



> А зачем else?


При переходе на следующую страницу, условие $form->isSubmitted() уже не выполняется, поэтому я беру $searchString из get-параметра

https://github.com/TheSidSpears/test_hub/blob/master/templates/tests/by_tag_list.html.twig
Проверь, соответствует ли имя шаблона гайдлайнам Симфони (я сам не помню).

>Я такого не нашел. Но вот в исходниках имена разделяются нижним подчеркиванием

353 1122787
>>22771
Кстати, у меня тоже повышение. Спрыгнул с bitrix'а на symfony в другую компанию. Скоро выхожу, думаю, эти полгода-год будут насыщенными.

Спасибо ОПу!
354 1122794
>>22787

>Спрыгнул с bitrix'а на symfony


Поздравляю, братишка. Привыкай к ООП-парадигме, и никогда не возвращайся в битрикс, ни за какие деньги, иначе умрёшь в душе как специалист
355 1122799
>>22787
не представляю, как у тебя хватило сил работать с битриксом.
356 1122830
>>22787
тот же стул но без пик
Kazakheydzh.png388 Кб, 307x848
357 1122831
Программач, ищу подработку от 10-20к в неделю, т.к зп на ништяки не хватает. PHP, неплохо знаю Yii2 и хотелось именно на ней работать, js/jquery разумеется. Ещё могу парсеры писать на selenium+python, покрайней мере один для себя написал. Телеграм @hysdop.
358 1122833
>>22497
>>22831
наши друг друга
359 1122835
>>22833

>пхп макак


Обидно, но правда
github.png10 Кб, 400x256
github 360 1122855
сосоны, на гитхабе можно как-то отсортировать свои репы по категориям? Типа: Мусор, Работа, Хуёта и т.д.?
Add files to Git.jpg29 Кб, 340x176
361 1122869
В новых проектах постоянно предлагает добавить под гит кэш и вендор. Раньше такой фигни не было. Они автоматом былы подсвечены серым и содержимое игнорилось. В .gitignre строки нужные есть
/var/
/vendor/

Кто-нибудь в курсе, как фиксить?
362 1122873
>>21562
ОП, добра тебе, что посмотрел!

>вот тут есть тонкий момент. Что, если мы сгенерируем токен, поставим куку, а потом скрипт упадет, не записав данные в БД. Пользователь останется с кривым токеном. Это не проблема? Хотя, если сделать наоборот, может получиться, что мы создадим пользователя в БД, а куку не выдадим - будет еще хуже.


Я подумал, может лучше через транзакцию в бд добавление/редактирование студента сделать? Или после редиректа проверять куку, и если она кривая, то ее удалять?

>Faker не умеет в женские фамилии?


Фейкер умеет только в женское имя и ФИО. Метод lastName не примает параметр $gender как, например, метод для генерации ФИО. Можно было бы генерировать женское ФИО, и затем выдерать из строки имя и фамилию, но я подумал, что проще просто сделать фамилию и добавить 'а'.
363 1122901
>>22855

Там есть теги, не подойдут?
364 1122903
>>22869

Если в консоли сделать git status, он эти папки показывает? Если да, то гитигнор настроен неправильно, если нет, то проблема в phpstorm и стоит начать с гугления по словам phpstorm gitignore not working.
365 1122906
>>22901
Что-то более классическое бы. Нет такого?
366 1122910
какой фреймворк самый простой для изучения?
367 1122911
>>22869
скриншот .gitignore лучше бы сделал
368 1122912
>>22910
я симфони4 учу, мне кажется достаточно легко все.
369 1122953
>>22869
var/
vendor/
370 1122955
>>22953
+ .gitignore
371 1122959
372 1122962
Пилю файлообменник на Слиме и вот возник вопрос.

Во всяких гайдах добавление модели в базу выглядит вот так.

File::create(['name' => $filename,
'size' => $size,
'created_at' => $created_at,
'comment' => $comment]);
Класс файл наследует Illuminate\Database\Eloquent\Model

И вот я решил посмотреть что за метод такой create. В моделе Eloquent'a такого метода нет. Но есть функция
public static function __callStatic($method, $parameters)
{
return (new static)->$method(...$parameters);
}
Я так понимаю что функция создает инстанс модели и запускает статический метод, как обычный. Но метода create нет в модели и нет в интерфейсах которые она реализует и нет в трейтах которые она наследует. Ну собственно вопрос что за метод такой и откуда он берется.
373 1122963
>>22959
Но изучать все же симфони, уй, ларавел. Вкатывальшик => конкуренция => работа
image.png35 Кб, 371x561
374 1122967
>>22903
>>22911
git status эти папки не показывает. Ща буду гуглить

>>22910
А зачем тебе самый простой? самый простой - это какой-нибудь недофреймворк 10-летней давности Учи самый полезный, например >>22912

ОП, ты советовал использовать роутинг в yaml файлах вместо аннотаций. Но я тут столкнулся с проблемой и покопался в доках. Есть такая магическая вещь, как @ParamConverter (https://symfony.com/doc/master/bundles/SensioFrameworkExtraBundle/annotations/converters.html)

Она определяет что в
/
@Route('/tests/tag/{name}')
/
public function testsByTag(Tag $tag){
...
}

{name} это $tag->getName()
И как я понял, это фишка аннотаций.

Получается при использовании yaml-роутинга нужно будет писать типа
public function testsByTag(string $name){
$tag = $tagRepository()->findByName($name);
...
}

По-моему, это только усложнения. Или есть еще варианты?
image.png35 Кб, 371x561
374 1122967
>>22903
>>22911
git status эти папки не показывает. Ща буду гуглить

>>22910
А зачем тебе самый простой? самый простой - это какой-нибудь недофреймворк 10-летней давности Учи самый полезный, например >>22912

ОП, ты советовал использовать роутинг в yaml файлах вместо аннотаций. Но я тут столкнулся с проблемой и покопался в доках. Есть такая магическая вещь, как @ParamConverter (https://symfony.com/doc/master/bundles/SensioFrameworkExtraBundle/annotations/converters.html)

Она определяет что в
/
@Route('/tests/tag/{name}')
/
public function testsByTag(Tag $tag){
...
}

{name} это $tag->getName()
И как я понял, это фишка аннотаций.

Получается при использовании yaml-роутинга нужно будет писать типа
public function testsByTag(string $name){
$tag = $tagRepository()->findByName($name);
...
}

По-моему, это только усложнения. Или есть еще варианты?
375 1122978
>>22962

> Я так понимаю что функция создает инстанс модели и запускает статический метод, как обычный.


__callStatic создаёт инстанс модели и обращается к нестатическому методу create. Этого метода в сущности нет, поэтому срабатывает __call: https://github.com/laravel/framework/blob/5.5/src/Illuminate/Database/Eloquent/Model.php#L1470
Там видно, что создаётся Builder (построитель запросов, метод newQuery) и уже у этого билдера вызывается метод create, который находится тут: https://github.com/laravel/framework/blob/5.5/src/Illuminate/Database/Eloquent/Builder.php#L750

Это очень специфичная для Laravel магия, не уверен, что тебе нужны эти кишки. И не знаю, что там у тебя за васян-гайд, но created_at самому ставить не нужно, он и так сгенерируется благодаря трейту HasTimestamps. Лучше почитай: https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md
376 1122987
>>22967
зато точно можно сказать, что не в .gitignore проблема лол
377 1122993
>>22978
Спасибо большое!
Опа мануалы прочитал уже все.
Просто хотелось использовать именно готовое решение. Изначально делал свой класс работы с бд.
378 1123094
Как можно phpstorm ускорить? Пека старый, долго загружается, иногда зависает.
379 1123110
>>23094
там power saving mode есть, можешь попробовать. но вообще, если он тормозит даже когда все проиндексировал, это повод проапгрейдиться.
380 1123113
>>22978
если ты тот анон, про которого я думаю, то у тебя паранойя: тебе мерещится, что все кругом читают "васян-туториалы", а один ты в мире знаешь о существовании мануала
381 1123152
>>22787
>>22771
У меня пока рост с "саппорт по коду, умеющий только читать иногда правильно мычать", к "недо-джуниор, который боится JS как тней и делает весь код процедурами", но тоже благодарен этому треду за существование!
382 1123228
>>23094

>Как можно phpstorm ускорить?


Подсказки отключи.
383 1123251
Возможно ли применение TDD в верстке под вордпресс или нет?
384 1123273
>>18555 (OP)
Посоны, допустим на сайте вам нужно выбирать данные из базы для формирования странички. Допустим же, что для этого нужно больше, чем один или даже два запроса к базе. Вы что их последовательно делаете что ли? Или, всё-таки, параллельно? Если параллельно, то кто как это делает? Я пришёл к вам из питона и немного охуел что нет одного хорошего простого решения, которым бы все пользовались. Помогите понять и определиться.
385 1123276
>>23273
Запросы делаются последовательно. Про параллельные запросы на пхп впервые слышу, хотя, наверное можно форкнуться в пхп и сделать их. Нормальная практика делать по 50-100 запросов на страничку. Кто крут в SQL может все данные достать за один запрос с подзапросами и хранимыми функциями.
386 1123281
>>23276

>Нормальная практика делать по 50-100 запросов на страничку


shiiiiiii~

>Кто крут в SQL может все данные достать за один запрос с подзапросами и хранимыми функциями.


Это-то как раз несложно. Вот только потом обрабатывать это в контроллере ебанёшься.

Мда, видимо в пхп-мирке свои понятия нормальности. Придётся приспосабливаться. Хотя вот я нагуглил php-icicle и там есть вот такое
https://github.com/amphp/mysql
387 1123290
Анон, я делал простенький код для генерации ссылок с использованием БД, но вот мое задание изменили и мне теперь нужно вместо обращений к БД использовать обращение к массивам.

Т.е.: у меня есть две таблицы из базы данных. Нужно сделать из них многомерные массивы, а потом научить код их обрабатывать.

Как это можно сделать?
388 1123296
>>23281
есть разные варианты, погугли по теме "асинхронный php" или "php pthreads". разные запросы К СКРИПТУ выполняются параллельно и так. если тебе требуется ускорять обращения к бд в рамках одного запроса к скрипту, то это наверное надо делать не распараллеливанием, а оптимизацией запроса.

другое дело, если у тебя один запрос выполняется 10 секунд, второй 10, они никак не зависят друг от друга и оба нужны для вывода данных, то можно заморочиться с асинхронностью или multithreading. но это история для каких-то внутрисерверных cli-ситуаций, а не для формирования страничек пользователям.
389 1123311
>>22771

> одна из самых


> год от макаки до мидла


кому ты пытаешься пиздеть
390 1123316
>>23311
тонко.

но если пришел уже мидлоджуном с опытом, то почему нет.
391 1123317
>>23311
хорошо работая в одной и той же компании макакой ровно год и не получить повышения - надо быть дебичем
392 1123321
>>23316
Этот прав, пришёл в компанию джуном-обосрышем с полугодичным опытом макакинга
393 1123325
Тоже хочу поблагодарить ОПа из этого треда и ОПа из версткотреда. Работаю щас фуллстаком под вордпресс.
Изучал где-то с 2012 по 2016. В 2017 переехал в дс и нашел работу. Всем спасибо. До миддла пока не повысили, но получаю довольно таки миддловскую зарплату судя по рынку
394 1123352
>>23325

>довольно таки миддловскую зарплату


сколько?
395 1123399
>>23352
120к
396 1123400
>>23352
300к в наносекунду
398 1123407
>>23404
Сейчас набегут дебилы которые "Да я как только Hello World" написал сразу за 100к работу нашол. А потом получил опыт 7 дней и сразу синьюр помидор 300к релокейт релокейт в гугол. Я вот даже не знаю откуда столько желчи в людях.
399 1123438
>>23404
Так понимаю, что это настоящий ответ автора поста >>23325, что ж, неплохо. Через год уже на 100+ выйдешь. Посоветовал бы только уходить от вордпресса.
400 1123445
>>23438
>>23325
Пару лет как обучился у опа, нахватался всяких гайдов с интернета, даже 2 месячный курс купил по PHP. Но дальше фриланса так и не вкатился, причём получаю с него тыщ 15 в месяц(имею основную работу). Не ххватает уверенности в силах хоть убей. всё кажется что возьмусь сейчас за работу, а там 9000 подводных камней, подведу работодателя. Больше всего мешает то, что не знаю досконально Wordpress, laravell, а от симфони я вообще в обморок падаю. Столько то там наворотов.
Я наверное один такой неудачник.
401 1123468
Аноны, у меня базовый вопрос.

Как правильно вызывать php-скрипты из html?

Вот есть у меня html страница и php скрипт, где я там должен прописать что-то типа execute main.php?
Или это как-то по другому работает?

Пол дня гуглил, но не могу понять такую базовую вещь.
402 1123474
>>23468
Никак.
403 1123480
>>23468
Ты что-то делаешь не так. PHP создан для того чтобы из него создавать HTML, а не наоборот.
404 1123501
>>23468
В любом отображаемом месте хтмл страницы нужно прописать специальный тег
<?php echo "пхп рабоатет"; ?>
405 1123502
>>23445
Не расстраивайся. Сидя в своей Мухосрани я даже фриланс за 15к не смог найти, поэтому пришлось рвануть в дс.
Тоже был дикий страх подвести, моментами в начале работы хотелось просто послать все, менеджеров, тестеров, всех.
И было такое, что поначалу сильно говнокодил.
В одной конторе даже сайт положил без восстановления XD. Но они и сами виноваты, там не было ни гита, ни других кодеров.
Свалил оттуда на следующий день, оформление не по ТК было.
Но ничего, вытянул, с вордпрессом немного помог удаленный кодер, который давно на нем сидит. Постепенно дали нормального лида, который ведет все переговоры по срокам и ТЗ и вообще сильно помогает. Помогает то, что многие чуваки в айти натурально сидят на бордах, т.е. с ними проще на одной волне быть.
406 1123529
>>23502
Спасибо за стори анон, прямо мёд для моего сердца (или как-то так). Буду пытаться вкатываться. Всю жизнь мечтал быть программистом, да только в моём мухосранске платят больше не программистам. Буду дальше искать работу мечты.
407 1123531
>>23273

>Я пришёл к вам из питона


Где вместо FastCGI используется WSGI, такой же синхронный интерфейс вебсервера.
408 1123540
>>23290
В reference manual почитай array functions. Их много и под все нужды. Советую ограничиться двумерными массивами. Пхп очень много памяти на многомерные тратит, ему может не хватить, упрется в ограничение в настроке.
409 1123541
>>23273
Мне вот просто интересно а параллельное выполнение вопроса, какую задачу решает? Ну так, просто чтобы в курсе быть.
410 1123553
>>23501
вообще-то fwrite(STDOUT, "hello");
411 1123554
>>23529
какой лвл?
412 1123556
>>23553
Ты тред с питоном не перепутал?
413 1123559
832795504025760259449-1.jpg70 Кб, 400x472
414 1123576
Как настроить PHP, так, чтобы через функции, которые лезут в сеть, можно было достучаться только до одного доменного имени, либо до нескольких из белого списка?
На всякий случай. А то нашел небольшой баг у себя, при некорректном ответе внешнего API можно исказить URL для следующего запроса.
415 1123581
Сделал задачу по проверке текста на палиндром, дайте ваше экспертное мнение.
https://repl.it/@Uzas/WorthlessUnusualArthropods
416 1123584
Нужен ли pixel perfect, или достаточно примерного (ну, скажем, расхождения есть, но на глаз не отличить) соответствия дизайну? Что большее зло: расхождение с pp, или всякие магические margin-top: 3px, потому что расходится с дизайном?
417 1123585
А если мне сейчас 26 лет, учу несколько месяцев язык, до этого пробовал си шарп немного, есть ли смысл в таком возрасте вообще учить кодинг, или на работу все равно потом хуй устроишься?
418 1123586
>>23556

>питоном


Тогда уж с С. Но на самом деле в php это тоже рабочий код.
fwrite - функция вывода в resource-первый-аргумент строки второго-аргемента
первый аргумент - константа стандартного потока-вывода STDOUT, второй - строка.

По сути так и работает под капотом echo или print. Я, например, люблю все эти fwrite, fputs, fgets и тп
419 1123587
>>23585

>сейчас 26 лет,


имеет, устроишься.

мимо-вылезатор в 30
420 1123591
>>23587
Спасибо, успокоил, а вообще пойдет ли в плюс при трудоустройстве, что я в сфере ИТ работаю и образование инженера?
421 1123605
>>23541
Ээ... ну как бы сокращение общего времени запросов к базе. Что быстрее:
- 10 последовательных запросов к базе
- 10 параллельных запросов к базе

В первом случае общее время запросов будет равно сложению времени каждого из них. Во втором - длине самого долгого запроса.

>>23531
Я про запросы к базе из скрипта. Допустим, у тебя есть контроллер, где ты вызываешь несколько методов, которые возвращают тебе из базы результат.
422 1123613
>>23591
Будут на собесы приглашать чаще, чем вкатывальщика из другой области.
А на практике не поможет, будет столько же страгглинга на первых порах, как и у всех. Разве только если ты не пм какой, тогда тех процессы тебе понятней будут, но они и так не сложные.
423 1123617
А можно как-то указать, что мне нужно именно 10 цифр, а не 10 символов?
424 1123619
>>23581
Проверти код плес.
425 1123621
>>23619

>Проверьте


фикс
426 1123624
>>23617
Через if else и так десять раз.
427 1123627
>>23624

> десять раз.


Но ведь количество символов между цифрами может быть любым.
428 1123633
>>23617
\d{10}
429 1123674
>>23480
>>23501
А можно пример как это должно работать?
989.PNG20 Кб, 650x329
430 1123692
>>23617
Я разобрался, надо было сделать вот так.
431 1123771
>>23674
https://primes.utm.edu/primes/home.php
Как видишь, для каждого пункта меню создана отдельная страница.
432 1123809
>>23468

>Вот есть у меня html страница и php скрипт, где я там должен прописать


Переименуй файл с html страницей в .php и напиши в началит файла <?php include "script.php"; ?> имя и путь к скрипту свои.
image.png19 Кб, 940x608
433 1123840
>>23809
Не получается в .php
434 1123853
>>23468

На твой вопрос так просто не ответить. Это ведь зависит от конфигурации сервера. Обычно сервер настраивают так:

- если идет обращение к файлу с расширением .php, то выполнить код из него
- если идет обращение к файлу с другими расширениями, вроде .html, то просто отдать его клиенту

В этом случае описанное тобой никак не реализовать без изменения настроек сервера.

> где я там должен прописать что-то типа execute main.php?


Надо настроить сервер, чтобы он файлы html выполнял бы как PHP код. Как именно, зависит от используемого веб-сервера. Но я не очень понимаю, зачем и что тебе мешает назвать файл .php или использовать ЧПУ.

>>23605
>>23273

Ты в своем расчете кое-что не учел:

- одни запросы могут зависеть от других и их нельзя выполнить параллельно
- база данных обладает неограниченным резервом производительности и выполняет запрос за одно и то же время независимо от нагрузки

На практике, второй пункт может выполняться, если сервер мощный и посетителей немного, но в других случаях запросы могут начать выполняться медленнее, когда их много.

Также, чтобы использовать параллельные запросы, надо, как я понимаю, использовать асинхронное программирование, и это та еще боль. Надо переписывать код из последовательного скрипта в более сложную конструкцию. И как там с обработкой ошибок? В питоне невыполненные обещания умеют бросать исключения? Я не знаю, я имел дело только с промисами из JS и PHP, там они не умеют это.

Ну и я плохо представляю, как можно распараллелить ORM, с наличием там "ленивых" запросов. Это все функции в сущностях надо переделывать на асинхроонную модель.

Так что сомневаюсь, что это так просто и всегда оправданно.

Не забывай также, что программисты часто стремятся оптимизировать технические характеристики, как память или потребление CPU, но бизнесу еще может быть интересно, чтобы разработка шла быстро и не стоила как космический корабль. Параллельный код может быть дороже и сложнее.

Ну и ты еще исходишь из предположения, что запросы к БД это самая долгая часть выполнения скрипта. Я смотрел трейсы в PHP-приложениях, и могу сказать, что это далеко не всегда так. Оптимизированный запрос с индексами на хорошем сервере может выполняться меньше 1 мс. Нужно ли его распараллеливать?

На Питоне все SQL запросы выполняют параллельно? Теперь уже я удивлен, первый раз про такое слышу. Покажи-ка ссылочку.

Если тебе все равно хочется отправлять параллельные запросы, я бы начал с изучения фреймворка ReactPHP и поиска асинхронного драйвера для БД. По моему, mysqli что-то такое может уметь, но я не уверен.
434 1123853
>>23468

На твой вопрос так просто не ответить. Это ведь зависит от конфигурации сервера. Обычно сервер настраивают так:

- если идет обращение к файлу с расширением .php, то выполнить код из него
- если идет обращение к файлу с другими расширениями, вроде .html, то просто отдать его клиенту

В этом случае описанное тобой никак не реализовать без изменения настроек сервера.

> где я там должен прописать что-то типа execute main.php?


Надо настроить сервер, чтобы он файлы html выполнял бы как PHP код. Как именно, зависит от используемого веб-сервера. Но я не очень понимаю, зачем и что тебе мешает назвать файл .php или использовать ЧПУ.

>>23605
>>23273

Ты в своем расчете кое-что не учел:

- одни запросы могут зависеть от других и их нельзя выполнить параллельно
- база данных обладает неограниченным резервом производительности и выполняет запрос за одно и то же время независимо от нагрузки

На практике, второй пункт может выполняться, если сервер мощный и посетителей немного, но в других случаях запросы могут начать выполняться медленнее, когда их много.

Также, чтобы использовать параллельные запросы, надо, как я понимаю, использовать асинхронное программирование, и это та еще боль. Надо переписывать код из последовательного скрипта в более сложную конструкцию. И как там с обработкой ошибок? В питоне невыполненные обещания умеют бросать исключения? Я не знаю, я имел дело только с промисами из JS и PHP, там они не умеют это.

Ну и я плохо представляю, как можно распараллелить ORM, с наличием там "ленивых" запросов. Это все функции в сущностях надо переделывать на асинхроонную модель.

Так что сомневаюсь, что это так просто и всегда оправданно.

Не забывай также, что программисты часто стремятся оптимизировать технические характеристики, как память или потребление CPU, но бизнесу еще может быть интересно, чтобы разработка шла быстро и не стоила как космический корабль. Параллельный код может быть дороже и сложнее.

Ну и ты еще исходишь из предположения, что запросы к БД это самая долгая часть выполнения скрипта. Я смотрел трейсы в PHP-приложениях, и могу сказать, что это далеко не всегда так. Оптимизированный запрос с индексами на хорошем сервере может выполняться меньше 1 мс. Нужно ли его распараллеливать?

На Питоне все SQL запросы выполняют параллельно? Теперь уже я удивлен, первый раз про такое слышу. Покажи-ка ссылочку.

Если тебе все равно хочется отправлять параллельные запросы, я бы начал с изучения фреймворка ReactPHP и поиска асинхронного драйвера для БД. По моему, mysqli что-то такое может уметь, но я не уверен.
435 1123856
>>23584

Зависит от ситуации и заказчика. Если ты учишься, то я бы советовал хоть раз сделать идеально. А так, конечно, важно, чтобы выглядело так, как задумал дизайнер, чтобы все было выровнено (частая проблема - выравнивание иконок относительно кнопок или текста). Иногда бывает, что на макете дизайнер поленился все до конца выровнять и приходится выравнивать за него.

А что мешает делать, как на макете?

>>23581

> $text = str_ireplace(" ", null, $text);


Заменять на null нелогично, так как в строку можно вставить только другую строку (например, пустую). Также, ireplace тут использовать нелогично, так как тут не нужна проверка регистра символов. Ну, и наконец, хочу сообщить, что эта функция в принципе нерабочая (в том, что касается регистра символов): https://github.com/codedokode/pasta/blob/master/php/strings-utf8.md

> $perebor1


можно было назвать char1

> };


Точка с запятой после такой скобки не нужна

А так, сделано верно.

>>23576

В PHP был так называемый safe mode, где ставились разные ограничения, но это все работало плохо и всегда находились какие-то обходные пути. Глупо пытаться ограничивать программу, работая на том же уровне привилегии, то есть имея равные с ней возможности. Для твоей задачи больше подойдет такой подход:

- сделать в linux отдельного пользователя
- запускать приложения из-под него
- с помощью iptables настроить список IP, с которыми он может соединяться. Чтобы он не сливал данные через DNS, вместо доступа к настоящему DNS даем ему доступ только к своему DNS-серверу, который резолвит только жестко прописанные в конфиге имена доменов (это умеет делать dnsmasq, я такое делал для того, чтобы телефон не мог сливать данные через DNS запросы).
- как альтернатива, можно вообще не давать прямого доступа в сеть, а перенаправлять трафик на squid (как прозрачный прокси, прозрачный тут значит, что клиент о нем не подозревает), в котором настроить правила фильтрации

Также, ты можешь подключить сервер со своим приложением через фаерволл и фильтровать трафик на нем, если ты богат.

Я так фильтровал трафик с андроид-телефона: все DNS-запросы шли на dnsmasq, все HTTP-соединения перехватывались и отправлялись в squid, все остально резалось. Возни, конечно, много, пока во всем этом разберешься и отладишь, сразу скажу, что чтением документации вряд ли обойдешься. Мне пришлось даже немного пропатчить сквид ради такого перехвата HTTPS, который мне был нужен, с подменой сертификатов.

Если все равно хочется сделать по-простому, то возьми расширение runkit и перехвати с его помощью функции, работающие с DNS, но конечно, это можно будет обойти.
435 1123856
>>23584

Зависит от ситуации и заказчика. Если ты учишься, то я бы советовал хоть раз сделать идеально. А так, конечно, важно, чтобы выглядело так, как задумал дизайнер, чтобы все было выровнено (частая проблема - выравнивание иконок относительно кнопок или текста). Иногда бывает, что на макете дизайнер поленился все до конца выровнять и приходится выравнивать за него.

А что мешает делать, как на макете?

>>23581

> $text = str_ireplace(" ", null, $text);


Заменять на null нелогично, так как в строку можно вставить только другую строку (например, пустую). Также, ireplace тут использовать нелогично, так как тут не нужна проверка регистра символов. Ну, и наконец, хочу сообщить, что эта функция в принципе нерабочая (в том, что касается регистра символов): https://github.com/codedokode/pasta/blob/master/php/strings-utf8.md

> $perebor1


можно было назвать char1

> };


Точка с запятой после такой скобки не нужна

А так, сделано верно.

>>23576

В PHP был так называемый safe mode, где ставились разные ограничения, но это все работало плохо и всегда находились какие-то обходные пути. Глупо пытаться ограничивать программу, работая на том же уровне привилегии, то есть имея равные с ней возможности. Для твоей задачи больше подойдет такой подход:

- сделать в linux отдельного пользователя
- запускать приложения из-под него
- с помощью iptables настроить список IP, с которыми он может соединяться. Чтобы он не сливал данные через DNS, вместо доступа к настоящему DNS даем ему доступ только к своему DNS-серверу, который резолвит только жестко прописанные в конфиге имена доменов (это умеет делать dnsmasq, я такое делал для того, чтобы телефон не мог сливать данные через DNS запросы).
- как альтернатива, можно вообще не давать прямого доступа в сеть, а перенаправлять трафик на squid (как прозрачный прокси, прозрачный тут значит, что клиент о нем не подозревает), в котором настроить правила фильтрации

Также, ты можешь подключить сервер со своим приложением через фаерволл и фильтровать трафик на нем, если ты богат.

Я так фильтровал трафик с андроид-телефона: все DNS-запросы шли на dnsmasq, все HTTP-соединения перехватывались и отправлялись в squid, все остально резалось. Возни, конечно, много, пока во всем этом разберешься и отладишь, сразу скажу, что чтением документации вряд ли обойдешься. Мне пришлось даже немного пропатчить сквид ради такого перехвата HTTPS, который мне был нужен, с подменой сертификатов.

Если все равно хочется сделать по-простому, то возьми расширение runkit и перехвати с его помощью функции, работающие с DNS, но конечно, это можно будет обойти.
436 1123861
>>23445

Ну вот, жаль, что так получается, что человек, который в нашем треде учился - и не может найти нормальную работу. Если у тебя есть возможность, я советую попробовать все же изучать технологии более глубоко - в ОП посте, например, есть задача на TestHub, которую можно делать на Симфони, ну и конечно, подучить то, что плохо знаешь - ООП там, HTTP, linux, тестирование. Может, изучить современные сложные JS фреймворки. Развиваться, расширять кругозор. А то иначе, если изучить только основы, то ты будешь конкурировать с тысячами таких же начинающих.

Если же ты все это знаешь, то может, ты подаешь себя как-то не так. Не представляю, чтобы человек с такими знаниями не мог найти работу.

> не знаю досконально Wordpress,


Поставь его себе на локалхост, изучи админку, прочитай пяток статей в стиле "лучшие плагины для вордпресс в 2017", поставь себе эти плагины. Этого уже хватит, чтобы какие-то простые задачи делать. Дальше, почитай документацию, сделай какой-нибудь простой плагин, сделай тему для ВП и в общем-то это и все, что обычно требуется от ВП разработчика.

Но конечно, в некоторых задачах требуется знать гораздо больше. Вот например, тебе скажут "сайт тормозит" - и тут надо будет смотреть его разными инструментами (htop, strace), профайлить, может, оптимизировать SQL запросы, настраивать кеширование - то есть тут уже нужен другой уровень, нужно знание линукса, индексов в SQL итд. Обычный "разработчик ВП" не справится (я с такой ситуацией сталкивался).

Мы, кстати, этому всему можем помочь научиться, по крайней мере, ссылками, задачками и ответами на вопросы.

>>23325

Я обычно не комментирую такие сообщения, но всегда приятно их читать. И можно будет, если что, показывать их новичкам для мотивации или даже повесить на сайт в раздел "отзывы" (не знаю, впрочем, будут ли они вызывать доверие).

>>22771

Вот, вот, такой отзыв я и ждал. Смотрите все, аноны, как важно изучать linux, ООП, фреймворки и автоматизированное тестирование, а не ограничиваться основами. А то что-то редко я тут вижу вопросы по этим темам. Наш тред этому тоже вас научит, если будет желание с вашей стороны.

Не надо конкурировать с настройщиками вордпресса, вы по цене их не перебьете.
436 1123861
>>23445

Ну вот, жаль, что так получается, что человек, который в нашем треде учился - и не может найти нормальную работу. Если у тебя есть возможность, я советую попробовать все же изучать технологии более глубоко - в ОП посте, например, есть задача на TestHub, которую можно делать на Симфони, ну и конечно, подучить то, что плохо знаешь - ООП там, HTTP, linux, тестирование. Может, изучить современные сложные JS фреймворки. Развиваться, расширять кругозор. А то иначе, если изучить только основы, то ты будешь конкурировать с тысячами таких же начинающих.

Если же ты все это знаешь, то может, ты подаешь себя как-то не так. Не представляю, чтобы человек с такими знаниями не мог найти работу.

> не знаю досконально Wordpress,


Поставь его себе на локалхост, изучи админку, прочитай пяток статей в стиле "лучшие плагины для вордпресс в 2017", поставь себе эти плагины. Этого уже хватит, чтобы какие-то простые задачи делать. Дальше, почитай документацию, сделай какой-нибудь простой плагин, сделай тему для ВП и в общем-то это и все, что обычно требуется от ВП разработчика.

Но конечно, в некоторых задачах требуется знать гораздо больше. Вот например, тебе скажут "сайт тормозит" - и тут надо будет смотреть его разными инструментами (htop, strace), профайлить, может, оптимизировать SQL запросы, настраивать кеширование - то есть тут уже нужен другой уровень, нужно знание линукса, индексов в SQL итд. Обычный "разработчик ВП" не справится (я с такой ситуацией сталкивался).

Мы, кстати, этому всему можем помочь научиться, по крайней мере, ссылками, задачками и ответами на вопросы.

>>23325

Я обычно не комментирую такие сообщения, но всегда приятно их читать. И можно будет, если что, показывать их новичкам для мотивации или даже повесить на сайт в раздел "отзывы" (не знаю, впрочем, будут ли они вызывать доверие).

>>22771

Вот, вот, такой отзыв я и ждал. Смотрите все, аноны, как важно изучать linux, ООП, фреймворки и автоматизированное тестирование, а не ограничиваться основами. А то что-то редко я тут вижу вопросы по этим темам. Наш тред этому тоже вас научит, если будет желание с вашей стороны.

Не надо конкурировать с настройщиками вордпресса, вы по цене их не перебьете.
437 1123864
>>23251

Прежде чем говорить про ТДД, мы должны поговорить про экономическое обоснование автоматического тестирования. Написание и настройка тестов требует времени (=денег), и нам надо понять, как эти расходы окупаются.

Считается, что выгода тестов в том, что при многократном запуске мы тратим время на их написание только первый раз, а второй и далее запуски нам бесплатны (в отличие от ручного тестирование, где каждый прогон стоит денег). Плюс, автоматические тесты выполняются быстрее. Следовательно, автоматические тесты могут окупаться там, где их многократно запускают.

Использование тестов также позволяет разработчикам более смело делать большие рефакторинги и изменения в коде. Тесты позволяют "защитить" однажды написанный функционал от повреждения, позволяют раньше находить ошибки и повысить качество кода.

Оправданно ли это в верстке, если ты делаешь ее один раз, проверяешь визуально и сдаешь заказчику? Оправданно ли это, если ты поддерживаешь и дорабатываешь верстку в течение долгого времени?

----

Теперь поговорим, как именно можно применить ТДД к верстке. Я не большой знаток ТДД, потому пролистал википедию по этой теме и первый вопрос, который у меня возник, а какие мы будем писать сценарии и что можно тестировать в верстке? Какие требования мы к ней хотим предъявить и проверить их соблюдение? Что мы будем считать критерием "хорошей" верстки?

- "заголовок должен быть черного цвета, крупнее основного текста и прижат влево"?
- "картинка должна быть отцентрирована в блоке вертикально"?
- "карточка отеля не должна разваливаться, даже если у отеля очень длинное название"? (это, кстати, мне уже нравится)
- "карточка отеля должна отображаться корректно, на какую бы страницу мы ее не вставили"?
- "карточка отеля на мобильной версии с узким экраном не должна вылезать за его пределы"?
- "карточка отеля должна выглядеть в ИЕ9 аналогично виду в Хроме"?

Так, боюсь, нам придется очень долго и подробно описывать макет в виде кода, и это сомнительная затея. Представь сам, сколько в макете независимых элементов, и сколько надо для них написать правил.

Я, кстати, советовал бы использовать методологию вроде БЭМ и разбивать верстку на независимые блоки - это здорово упростит проверку, облегчит поддержку и повысит пуленепробиваемость верстки.

Вместо того, чтобы описывать ожидаемый результат кодом, мы можем сделать что-то другое. Мы можем сверстать элемент, проверить на глаз, что он выглядит корректно, и сохранить его внешний вид - может быть, в виде скриншота, может быть в виде куска DOM с проставленным размерами и координатам элементов (скриншоты могут немного различаться в разных ОС и браузерах из-за особенностей рендеринга шрифтов, видеокарт и тд). И после этого мы можем написать тест, проверяющий, что после изменений в верстке данный блок не поменял внешний вид.

Но это будет не совсем TDD, боюсь. Там ведь мы пишем тесты сначала. Хотя, может, можно придумать какой-то текстовый формат описания внешнего вида блока и сделать на его основе тест (в идеале - вообще генерировать из макета, но тут может понадобиться машинное зрение и искуственный интеллект). Но не уверен, что это будет быстро.

Также, можно попробовать подключить инструменты для валидации кода - они тоже могут что-нибудь находить.

Еще можно придумать какие-то простые тесты в стиле "вставляем данные в БД, загружаем страницу, проверяем их наличие" или "загружаем страницу, проверяем, что в логе пхп нет ошибок". Может, тут надо только часть задач автоматизировать.

Могу дать еще ссылки про тестирование верстки:

- https://habrahabr.ru/company/yandex/blog/200968/
- https://habrahabr.ru/company/2gis/blog/277457/ (тут вроде ручные тесты)
- https://habrahabr.ru/post/114256/ (ручные)
- https://events.yandex.ru/lib/talks/?audience=testirovschiki
- https://readymag.com/tehnovedro/488569/5/
- https://habrahabr.ru/post/271379/
- https://toster.ru/q/373556

Если у тебя есть каике-то интересные идеи, и тем более, ты готов их испробовать, мне было бы очент интересно почитать, и я может быть могу где-то помочь советом. Мне это интересно, так как у нас есть задачи на CSS и мне было бы пригодилась возможность автоматически проверять их решения.
437 1123864
>>23251

Прежде чем говорить про ТДД, мы должны поговорить про экономическое обоснование автоматического тестирования. Написание и настройка тестов требует времени (=денег), и нам надо понять, как эти расходы окупаются.

Считается, что выгода тестов в том, что при многократном запуске мы тратим время на их написание только первый раз, а второй и далее запуски нам бесплатны (в отличие от ручного тестирование, где каждый прогон стоит денег). Плюс, автоматические тесты выполняются быстрее. Следовательно, автоматические тесты могут окупаться там, где их многократно запускают.

Использование тестов также позволяет разработчикам более смело делать большие рефакторинги и изменения в коде. Тесты позволяют "защитить" однажды написанный функционал от повреждения, позволяют раньше находить ошибки и повысить качество кода.

Оправданно ли это в верстке, если ты делаешь ее один раз, проверяешь визуально и сдаешь заказчику? Оправданно ли это, если ты поддерживаешь и дорабатываешь верстку в течение долгого времени?

----

Теперь поговорим, как именно можно применить ТДД к верстке. Я не большой знаток ТДД, потому пролистал википедию по этой теме и первый вопрос, который у меня возник, а какие мы будем писать сценарии и что можно тестировать в верстке? Какие требования мы к ней хотим предъявить и проверить их соблюдение? Что мы будем считать критерием "хорошей" верстки?

- "заголовок должен быть черного цвета, крупнее основного текста и прижат влево"?
- "картинка должна быть отцентрирована в блоке вертикально"?
- "карточка отеля не должна разваливаться, даже если у отеля очень длинное название"? (это, кстати, мне уже нравится)
- "карточка отеля должна отображаться корректно, на какую бы страницу мы ее не вставили"?
- "карточка отеля на мобильной версии с узким экраном не должна вылезать за его пределы"?
- "карточка отеля должна выглядеть в ИЕ9 аналогично виду в Хроме"?

Так, боюсь, нам придется очень долго и подробно описывать макет в виде кода, и это сомнительная затея. Представь сам, сколько в макете независимых элементов, и сколько надо для них написать правил.

Я, кстати, советовал бы использовать методологию вроде БЭМ и разбивать верстку на независимые блоки - это здорово упростит проверку, облегчит поддержку и повысит пуленепробиваемость верстки.

Вместо того, чтобы описывать ожидаемый результат кодом, мы можем сделать что-то другое. Мы можем сверстать элемент, проверить на глаз, что он выглядит корректно, и сохранить его внешний вид - может быть, в виде скриншота, может быть в виде куска DOM с проставленным размерами и координатам элементов (скриншоты могут немного различаться в разных ОС и браузерах из-за особенностей рендеринга шрифтов, видеокарт и тд). И после этого мы можем написать тест, проверяющий, что после изменений в верстке данный блок не поменял внешний вид.

Но это будет не совсем TDD, боюсь. Там ведь мы пишем тесты сначала. Хотя, может, можно придумать какой-то текстовый формат описания внешнего вида блока и сделать на его основе тест (в идеале - вообще генерировать из макета, но тут может понадобиться машинное зрение и искуственный интеллект). Но не уверен, что это будет быстро.

Также, можно попробовать подключить инструменты для валидации кода - они тоже могут что-нибудь находить.

Еще можно придумать какие-то простые тесты в стиле "вставляем данные в БД, загружаем страницу, проверяем их наличие" или "загружаем страницу, проверяем, что в логе пхп нет ошибок". Может, тут надо только часть задач автоматизировать.

Могу дать еще ссылки про тестирование верстки:

- https://habrahabr.ru/company/yandex/blog/200968/
- https://habrahabr.ru/company/2gis/blog/277457/ (тут вроде ручные тесты)
- https://habrahabr.ru/post/114256/ (ручные)
- https://events.yandex.ru/lib/talks/?audience=testirovschiki
- https://readymag.com/tehnovedro/488569/5/
- https://habrahabr.ru/post/271379/
- https://toster.ru/q/373556

Если у тебя есть каике-то интересные идеи, и тем более, ты готов их испробовать, мне было бы очент интересно почитать, и я может быть могу где-то помочь советом. Мне это интересно, так как у нас есть задачи на CSS и мне было бы пригодилась возможность автоматически проверять их решения.
438 1123867
>>23094

Памяти достаточно? В своп не выпадает? Смотри диспетчером задач хотя бы.

>>22962

Вот, кстати, с точки зрения ООП, это очень странный код. Если ты хочешь вызвать обычный метод, то ествественно, нужно иметь экземпляр объекта. Если ты создаешь объект и тут же выкидываешь, то не очень понятно, а не проще ли метод сделать статическим. И если это обычный метод, то не проще ли его вызывать как обычный. Вот такое отношение к ООП мне в ларавеле не нравится.

Также, узнать, какие функции вызываются в ходе работы программы, можно, освоив xdebug и сделав трейс, и да!!!, я все еще интересуюсь, не хочет ли кто сделать визуализатор логов трассировки? Ссылка: https://xdebug.org/docs/execution_trace

>>22993

Конечно, стоит изучить готовые решения.

>>22967

Насчет роутов в YAML - это очень помогает, когда, например, у тебя много роутов, и ты можешь посмотреть, как добавить новый, чтобы он не конфликтовал со старыми и можешь даже настроить их порядок вручную. А что делать в случае аннотаций? Также, к роутам можно писать регулярки для параметров, опять же, наверно, неудобно писать их в аннотациях. Ну и наконец, при желании к роутам можно писать дополнительные опции (права доступа, правила переключения на другую страну, настройки кеширования - но учти, что они в Симфони вроде не кешируются и надо это исправить сначала) и тут YAML файл очень удобен.

Также, в конфиге роутинга несколько роутов могут вести на одно действие, но с разными параметрами.

Я не представляю, как со всем этим работать в аннотациях. Придется постоянно вызывать команду, дампящую роуты и смотреть результат. неудобно же, когда 200 роутов раскиданы где-то по коду. Единственный плюс - при удалении контроллера роут удаляется вместе с ним.

Но это мое субъективное мнение.

Что касается @ParamConverter, это же часть контроллера, его можно наверно оставить в аннотации. Нельзя? Предложи исправить это.
439 1123868
>>22869

Смотри настройки гит-плагина, а также погугли, не баг ли это.

>>22873

Транзакции нужны, если запросов больше одного. Если у тебя один INSERT, он и так идет как одна транзакция.

Проще наверно просто игнорировать кривые куки. А то вдруг админ удалит студента, а он пытается зайти на сайт.

> Фейкер умеет только в женское имя и ФИО.


Не хочешь допилить и поделиться решением со всеми? Придется расковырять фейкер, понять, как он рабоатет, и может обсудить это с его разработчиками.
440 1123880
>>23585
как вы заебали, реально. вот тебе на дваче скажут "нет смысла, иди таксистом рабоать" и что дальше? пойдешь?

если хочешь чем-то заниматься, должно быть похуй на чужие мнения. иначе будешь вяло подрачивать и "вкатываться" пять лет. а потом не вкатишься и скажешь "ну да, меня не берут потому что мне 26".

короче иди учи
441 1123899
>>23840
сделай что говорит
442 1123914
кто занимается версткой на линуксе или маке, вы как тестируете сайты в IE? стоит ли доверять таким сервисам? https://www.browserling.com/internet-explorer-testing

сам бэкендом занимаюсь, верстку умею на уровне потыкать бутстрап, поэтому нихуя не шарю в тонкостях
443 1123920
>>23914
Виртуальные машины.
444 1123925
Решил эту задачу вот так, но ведь это очевидно не самый оптимальный вариант. Как можно поменять части элементов массива без перевода массива в строку? Нашел только array_replace, но это вроде не то. Либо я не разобрался.
445 1123928
>>23920
эх.
ну так-то вайн есть, но заебно.

перекатывался на линукс, чтобы запускать там ИЕ лол
446 1123930
>>23928
Кроме IE есть еще Edge и Safari
447 1123932
>>23928
И у самого IE несколько версий
448 1123935
>>23928
А вообще зуй щнает, я не могу заниматься версткой без фотошопа. Мне все макеты так или иначе приходят в psd
449 1123984
Я не люблю всякие гайды и туториалы, так как они часто ничего толком не объясняют и заключаются в просто выкладывании готовых кусков кода с краткими объяснениями. Вот пример правильного туториала, который мне нравится: https://vulkan-tutorial.com/
450 1124033
>>18555 (OP)
Впервые тут у вас. Заглянул в первый гайд для новичков в шапке и охуел.
Кто и зачем так постарася?
Гайд правда толковый или только выглядит так?
451 1124035
>>24033

>Гайд правда толковый или только выглядит так?


Это лучший гайд, на мой взгляд. Книжек нормальных по пхп нет, только мануал очень хороший.
452 1124040
>>23605
Я вот просто на физическом уровне пытаюсь представить распаралеленный запрос к бд и что-то не могу. Просто потому-что знаю как устроены запросы внутри большинства бд. Ну тоесть допустим у тебя есть "Select from users" и "Select from questions" (это гипотетические запросы выдуманные для примера, не надо до синтаксиса докапываться).
И обычная скажем MSSQL смотрит когда был подан запрос и тупо выполняет сначала тот который был раньше, а потом тот который был позже.
А тут как ты себе представляешь это? Сначала БД выбирает первую запись первого запроса, потом первую запись второго, и так пока до конца не дойдёт? Что-то тут не так мне кажется.
453 1124077
>>24033

Вот выше люди, которые учились в треде, отзывы пишут: >>22771 >>23325 >>22787
454 1124078
>>24040

С микросервисами так можно, если у тебя данные для разных частей страницы формируют разные микросервисы, работающие на разных серверах, то можно параллельно им запросы отправить.
455 1124213
>>23935
ну там не то чтобы прямо верстка по макету, просто у друга условный автосервис, он заказал сайт "шоб читалось легко". и главное не объебаться с тем, что везде все нормально, а в
ИЕ все пополам складывается.
456 1124222
посоны, у кого свой ВПС или кто работает близко к эксплуатации, вы что думаете про это http://www.phpinternalsbook.com/php7/build_system/building_php.html#why-not-use-packages ?

я для себя выделил такие аргументы против использования готовых пакетов:
1. сложно дебажить
2. нет предупреждений об утечках памяти
3. нельзя использовать thread safety
4. возможная несовместимость патчей внутри одного пакета

я на своем опыте сталкивался только с проблемой того, что нельзя использовать pthreads. но там ясно в мануале написано мол хотите использовтаь - перекомпилируйте с каким-то там ключом.

кто-то реально заморачивается с самостоятельной пересборкой? допустим, есть некий хостинг, они когда обновляют версию, они сами ее компилируют из исходников?
457 1124343
Вопрос по проектированию базы данных. Задача файлообменник. У меня получается три базы данных:
1. files (
id
name
size
linkaname
created_at
updated_at
lifetime
user_id
public
comment
status)
2.comments (
id
user_id
parent_id
child_id
comment)
//Вообще для комментариев будет две базы данных для реализации древовидных комментариев. Здесь просто указаны поля
3.users (
id
name
email
avatar?
hash)
Ну и собственно вопрос. Нормально ли что у меня в таблице files столько столбцов? Есть ли какое-то ограничение на колличество? Ну и вообще правильно ли спроектировал?
457 1124343
Вопрос по проектированию базы данных. Задача файлообменник. У меня получается три базы данных:
1. files (
id
name
size
linkaname
created_at
updated_at
lifetime
user_id
public
comment
status)
2.comments (
id
user_id
parent_id
child_id
comment)
//Вообще для комментариев будет две базы данных для реализации древовидных комментариев. Здесь просто указаны поля
3.users (
id
name
email
avatar?
hash)
Ну и собственно вопрос. Нормально ли что у меня в таблице files столько столбцов? Есть ли какое-то ограничение на колличество? Ну и вообще правильно ли спроектировал?
458 1124346
>>24343
сколько столбцов надо, столько и нормально. вроде нормально, но приложи еще внешние ключи для того, чтобы удостовериться.

также по поводу вложенных комментариев, у ОПа есть урок https://github.com/codedokode/pasta/blob/master/db/trees.md

где он предлагает для реализации closure table (которую ты, судя по всему, вырбал) использовать дополнительную таблицу связей. ты же кладешь parent_id и child_id в ту же таблицу комментов, а поле указания глубины не используешь. в итоге как ты собираешься строить структуру комментариев?

от себя добавлю, я бы использовал nested_sets, они быстры на выборку, а для манипуляций с перемещением-удалением есть библиотеки для той же Доктрины (наверняка еще миллион standalone). если конечно не стоит задачи написать все самому.
459 1124371
>>24346
Древовидные комментарии уже реализовывал отдельно. Все получилось, как раз клоужер тейбл использовал.

Внешние ключи.
files id, user_id
comments user_id, id
users id
460 1124403
значение по умолчанию функциях,это типа резервное значение,на случай,если не будет других параметров?
передача аргументов по ссылке устарело?
461 1124409
>>24403
на случай, если ты не передашь этот конкретный параметр. значение по умолчанию в качестве аргумента значит, что этот аргумент необязательный.

что значит устарело? deprecated? нет, оно не депрекейтед, если ты имеешь в виду указание ссылки в определении функции типа
function foo(&$number) {...}

а вот указание ссылки при ВЫЗОВЕ функции с 5.4 (кажется, точно не помню) запрещено:
function foo($number) {...}
$a = 5;
echo foo(&a); // это вызовет ошибку
462 1124432
Мой очередной нубский вопрос: есть один объект, он передается через конструктор в качестве свойства в другой объект. Как туда передается первый объект - по ссылке или он клонируется? То есть, если я изменю через второй объект, какое то свойство первого объекта-свойства, то измениться ли оно в первом глобальном объекте?
463 1124435
>>24432
Объекты всегда передаются по ссылке.
Что бы их склонировать, надо делать это явно.
464 1124446
У меня не совсем типичный вопрос.

Как отрефакторить пхп так, чтоб нельзя было уличить в плагиаторстве?

Помимо очевидного переименовывания переменных и функций
465 1124457
>>24222

> сложно дебажить


На продакшен сервере не дебажат. На память просто поебать. Тем не менее, у нас он скомпилирован админом вместе с использованными нами библиотеками. Дополнительно он там какие-то заплатки прикомпилил, чтобы не похакали. Из минусов только то, что при необходимости добавить или поменять библиотеку приходится дергать админа, чтобы он все заново перекомпилил.
466 1124458
>>24040

Вообще, это возможно. Обычно да, в рамках одного соединения запросы выполняются последовательно. Но базы данных обычно многопоточные/многопроцессные и можно открыть несколько соединений и выполнять несколько запросов.

Но важно понимать, что тот же дисковый трафик и число процессоров ограничены и нужно подобрать такие параметры распараллеливания, которые смогут задействовать имеющиеся ресурсы максимально.

Если тебе интересно про то, как с точки зрения архитектуры устроены серверы, в том числе СУБД, есть паста: https://gist.github.com/codedokode/ffd520440a970c07c1c6

>>23273

Вот кстати в mysqli есть асинхронные запросы, можно еще в эту сторону копать: http://php.net/manual/ru/mysqli.poll.php

>>24222

Я стараюсь у себя локально использовать готовые пакеты, так как это быстрее. Расширения тоже ставлю через apt-get, а если их там нет, то под линуксом они легко компилируются одной командой через pecl install.

Я думаю, что сборка из исходников нужна тем, кто разрабаитывает интерпретатор PHP или исследует баги в нем.

Также, есть набор скриптов phpenv, который позволяет автоматизировать установку версий PHP, и даже ставить их несколько на один компьютер.

> 1. сложно дебажить


Ну, мне это и не требуется и я не силен в gdb

Вообще, по поводу отладочных данных, мне нравится, как это сделано у майкрософт: у них отладочные данные идут в отдельном pdb-файле, а не встраиваются в exe-шник.

> 2. нет предупреждений об утечках памяти


Это да. Но я не сталкивался с проблемами из-за них.

> 3. нельзя использовать thread safety


Версия PHP под винду, кстати, thread-safe.

> кто-то реально заморачивается с самостоятельной пересборкой? допустим, есть некий хостинг, они когда обновляют версию, они сами ее компилируют из исходников?



Думаю, они используют phpenv или что-то аналогичное. Хотя, собрать PHP не так и сложно. Я, например, собирал PHP7 под XP (пришлось чуть-чуть пропатчить), а под линуксом это вообще стандартно делается, configure + make + make install.
466 1124458
>>24040

Вообще, это возможно. Обычно да, в рамках одного соединения запросы выполняются последовательно. Но базы данных обычно многопоточные/многопроцессные и можно открыть несколько соединений и выполнять несколько запросов.

Но важно понимать, что тот же дисковый трафик и число процессоров ограничены и нужно подобрать такие параметры распараллеливания, которые смогут задействовать имеющиеся ресурсы максимально.

Если тебе интересно про то, как с точки зрения архитектуры устроены серверы, в том числе СУБД, есть паста: https://gist.github.com/codedokode/ffd520440a970c07c1c6

>>23273

Вот кстати в mysqli есть асинхронные запросы, можно еще в эту сторону копать: http://php.net/manual/ru/mysqli.poll.php

>>24222

Я стараюсь у себя локально использовать готовые пакеты, так как это быстрее. Расширения тоже ставлю через apt-get, а если их там нет, то под линуксом они легко компилируются одной командой через pecl install.

Я думаю, что сборка из исходников нужна тем, кто разрабаитывает интерпретатор PHP или исследует баги в нем.

Также, есть набор скриптов phpenv, который позволяет автоматизировать установку версий PHP, и даже ставить их несколько на один компьютер.

> 1. сложно дебажить


Ну, мне это и не требуется и я не силен в gdb

Вообще, по поводу отладочных данных, мне нравится, как это сделано у майкрософт: у них отладочные данные идут в отдельном pdb-файле, а не встраиваются в exe-шник.

> 2. нет предупреждений об утечках памяти


Это да. Но я не сталкивался с проблемами из-за них.

> 3. нельзя использовать thread safety


Версия PHP под винду, кстати, thread-safe.

> кто-то реально заморачивается с самостоятельной пересборкой? допустим, есть некий хостинг, они когда обновляют версию, они сами ее компилируют из исходников?



Думаю, они используют phpenv или что-то аналогичное. Хотя, собрать PHP не так и сложно. Я, например, собирал PHP7 под XP (пришлось чуть-чуть пропатчить), а под линуксом это вообще стандартно делается, configure + make + make install.
467 1124460
>>24343

> linkaname


> created_at


Надо писать названия в едином стиле, по умолчанию можно использовать SQL style guide http://www.sqlstyle.guide/ru/

Не забудь также комментарии к неочевидным колонкам ( https://github.com/codedokode/pasta/blob/master/db/comments.md )

Не забудь внешние ключи, ограничения уникальности полей. Если твоя БД поддерживает ограничение CHECK (например: postgres и sqlite), используй его там, где это уместно.

comment лучше наверно заменить на description.

Про древовидные данные в БД есть урок, если что: https://github.com/codedokode/pasta/blob/master/db/trees.md

> Нормально ли что у меня в таблице files столько столбцов?


Да

> Есть ли какое-то ограничение на колличество?


да, изучи документацию по твоей БД или набери в Гугл <db> columns limit.

> Ну и вообще правильно ли спроектировал?


Выглядит верно.

>>24346

Я бы советовал сравнить плюсы и минусы разных вариантов реализации деревьев и попробовать выбрать наиболее подходящий ответ. А потом сравнить с тем, что я написал ниже:

Для комментариев чаще всего применяют (не заглядывайте раньше времени) material path material path material path

>>24371

> Все получилось, как раз клоужер тейбл использовал


Попробуй оценить ее размер в зависимости от числа файлов, средненго числа комментариев, средней глубины ответов. Попробуй оценить число SQL запросов (выборок, вставок) при добавлении нового комментария.

>>24432

Объект передается как будто по ссылке. Если быть точным, то в PHP объекты хранятся в отдельной области памяти, а в переменной хранится лишь идентификатор (указатель) объекта. И ты передаешь в функцию не копию объекта, а просто его идентификатор. Чтобы сделать копию, используется оператор clone.
467 1124460
>>24343

> linkaname


> created_at


Надо писать названия в едином стиле, по умолчанию можно использовать SQL style guide http://www.sqlstyle.guide/ru/

Не забудь также комментарии к неочевидным колонкам ( https://github.com/codedokode/pasta/blob/master/db/comments.md )

Не забудь внешние ключи, ограничения уникальности полей. Если твоя БД поддерживает ограничение CHECK (например: postgres и sqlite), используй его там, где это уместно.

comment лучше наверно заменить на description.

Про древовидные данные в БД есть урок, если что: https://github.com/codedokode/pasta/blob/master/db/trees.md

> Нормально ли что у меня в таблице files столько столбцов?


Да

> Есть ли какое-то ограничение на колличество?


да, изучи документацию по твоей БД или набери в Гугл <db> columns limit.

> Ну и вообще правильно ли спроектировал?


Выглядит верно.

>>24346

Я бы советовал сравнить плюсы и минусы разных вариантов реализации деревьев и попробовать выбрать наиболее подходящий ответ. А потом сравнить с тем, что я написал ниже:

Для комментариев чаще всего применяют (не заглядывайте раньше времени) material path material path material path

>>24371

> Все получилось, как раз клоужер тейбл использовал


Попробуй оценить ее размер в зависимости от числа файлов, средненго числа комментариев, средней глубины ответов. Попробуй оценить число SQL запросов (выборок, вставок) при добавлении нового комментария.

>>24432

Объект передается как будто по ссылке. Если быть точным, то в PHP объекты хранятся в отдельной области памяти, а в переменной хранится лишь идентификатор (указатель) объекта. И ты передаешь в функцию не копию объекта, а просто его идентификатор. Чтобы сделать копию, используется оператор clone.
468 1124466
>>24343

>Вообще для комментариев будет две базы данных для реализации древовидных комментариев.


1. Прекрати называть таблицу базой данных. У тебя три таблицы в одной базе.

2. На вскидку, я не вижу повода создавать две таблицы для древовидных комментов. Просто каждая запись комментария будет содержать поле со ссылкой на предыдущий комментарий.
Untitled.jpg323 Кб, 2656x1762
469 1124496
Есть простая страница, которая выводит несколько изображений на экран с текстом справа.
Получилось сделать так, чтоб выводил элементы в столбик.

Как сделать в виде таблицы (по 2-3 элемента в строку)?

В теге <style> прописал такой вот код для вывода в столбик:

#results .result .image {height: 200px;width: 300px;float: left;padding: 2px;overflow: hidden;position:relative;}
#results .result .image img {width:300px;}
#results .result .image p {position: absolute;top: 85px;margin: 5px;padding: 0px;color: white;text-rendering:optimizelegibility;text-shadow: 0 0 3px rgba(0, 0, 0, .8);}
#results .result .stats {width:260px;float:right;}
470 1124539
>>24466

Это не позволяет эффективно выбирать комментарии. Почитай урок https://github.com/codedokode/pasta/blob/master/db/trees.md
471 1124649
Вопросо по юнит тестам. Вот, допустим, у меня файл пдо в контейнере. Как лучше сделать тест класса, который работает с БД - подключать весь контейнер во время тестов, или в тесте в методе setUp создавать тестовое подключение к БД?
472 1124655
ребятки, есть вопрос один.

я тут впс поднял и на нем захуярил гит-сервер (gogs.io). не хочу, чтобы туда всякие левые чуваки регистрировались и вообще он только для меня и полутора коллег. а он там по умолчанию открыт для всех и пиздец. можно прямо из интернета зайти, зарегить сто аккаунтов и пожрать мне все ресурсы.

какие есть варианты вменяемо ограничить доступ ко всему домену? знаю вариант поднимать vpn сервер и пускать к гиту только через тоннель, но это чуток заебно, т.к. во-первых, vpn пожрет и так ограниченные ресурсы впс, а во-вторых, надо впн поднимать на клиенте, отсылать ему файл с конфигом и прочее. не хочется заморачиваться.

в идеале на уровне конфига нжинкса повесить какую-то авторизацию по ключу, например. есть какой-то такой вариант?
473 1124661
>>24655
Вот ты жмотяра, пиздец. Нахуй так жить вообще. Уууу, чтоб ты сдох нахуй и семья твоя вся сдохла. Пидор, уебок, жлобяра.
1.png11 Кб, 362x185
474 1124725
Как средствами PHP преобразовать текст пикрелейтед в читаемый вид? Может уже есть стандартные функции. Вообще, забыл, как называется это кодирование? (аналогично преобразуются русские символы в адресной строке браузера)
reminder-data-base.png84 Кб, 997x533
475 1124744
Привет, делаю базуданых для birthday-remider, посмотрите пожалуйста пикрил, все ли ок.
Пример записей, которые должно показывать приложение:
1. "23 января 1905 г. день рождение Антона Голубцова, напомнить 22 января 2018 г."
2. "01 июля 2018 г. свадьба Антона Голубцова и Тани Яотиной, напомнить 25 июня 2018 г. (купить подарок), 30 июля 2018 г. (помыться)"

Записи можно сортировать по датам, по событиям, по участникам. Напоминаний и участников у события может быть несколько. Типы событий можно добавлять.
476 1124745
>>24744
Представил как одним запросом СУБД захватывает аж 6 таблиц и немного погрустнел. И ведь целая система нормализации есть. Только непонять в чём профит, столько данных тащить. На ум приходит только тотальная и маниакальная экономия дискового пространства.
477 1124748
>>24745

>Представил как одним запросом СУБД захватывает аж 6 таблиц и немного погрустнел



хуяк-хуяк подобрал индексы шоб ниормазило и в продакшон. Чо ты как нипацан.
478 1124762
>>24745
>>24748
ок, можно избавиться от таблицы Event-types, пускай названия событий будут в таблице Events, но как совместить Events + Participants + Reminders в одной таблице, учитывая что там отношения один к многим?

>>Только непонять в чём профит, столько данных тащить


А как по другому сделать?
479 1124771
>>24655

>в идеале на уровне конфига нжинкса повесить какую-то авторизацию по ключу, например. есть какой-то такой вариант?


Ну естественно так и надо делать. Это для доступа по ssh. И не забудь после отключить доступ по паролю.
А если у тебя есть веб-морда к серверу, то очевидно нужно закрыть доступ для незарегистрированных в системе юзеров - проще говоря страницу логина добавь, если таковой по умолчанию нет.
480 1124773
>>24725
urldecode
urlencode
481 1124797
>>24771
про доступ по ssh это да. но у меня грубо говоря есть сайт, к которому я хочу ограничить доступ. есть возможность в https логиниться по ключу?
482 1124814
>>24797
Нет, такой возможности нет. Зачем тебе это нужно вообще? Настрой ssh доступ и делай пулы/пуши через ssh. Ну либо по https - но нужен будет пароль.
Тебе нужно ограничить доступ к веб-морде? Используй страницу логина либо, если известны адреса клиентов, добавь их в белый список веб-сервера, а остальным айпи просто заблокируй доступ.
image.png32 Кб, 1017x239
483 1124816
>>24460

>Надо писать названия в едином стиле, по умолчанию можно использовать SQL style guide http://www.sqlstyle.guide/ru/



Поясните, пожалуйста, с чем связана такая рекомендация?
484 1124824
>>18555 (OP)
Посоны, у меня вопрос по базам данных. Какие ключи лучше использовать - автоинкрементальные или генерируемые? Какие недостатки/преимущества есть у тех и других?
Я вижу серьёзное преимущество генерируемых в том, что при добавлении записи во множество таблиц, мне не нужно сначала вставлять данные в основную таблицу, получать автоинкрементальный айди и потом только делать вставку с этим айди в дочерние таблицы. Я просто генерирую айди и распихиваю связанные по этому айди данные в нужные таблицы без лишних телодвижений.
Единственный серьёзный недостаток, который я вижу в генерации, это возможность коллизий. Но всегда можно подобрать алгоритм генерации, который сведёт такие случаи к нулю.
485 1124839
>>24816
вот эти рекомендации тоже особо никто не выполняет:

>Всегда используйте ключевое слово AS для лучшей читаемости.


>По возможности избегайте объединения названий двух таблиц для построения таблицы отношений. Например, вместо названия cars_mechanics лучше подойдёт services.

486 1124850
>>23867

> Что касается @ParamConverter, это же часть контроллера, его можно наверно оставить в аннотации. Нельзя? Предложи исправить это.



До такого я не додумался. Попробую, посмотрю, как юудет
487 1124853
>>24824
вопрос-то хороший. вот мои возражения:

1. в мускуле надо делать два запроса, а в постресе есть RETURNING.
2. по инкрементному айди можно отсортировать, а по сгенерированному нет.
3. генерация по-настоящему уникального значения - более дорогая операция.
4. он займет больше места для хранения и в теории поиск по индексу будет чуть медленнее.

по мне оно того не стоит
488 1124858
>>24655

HTTP авторизация + используй HTTPS чтобы пароли было не подглядеть.

https://developer.mozilla.org/ru/docs/Web/HTTP/Авторизация
https://nginx.ru/ru/docs/http/ngx_http_auth_basic_module.html
489 1124860
>>24824

>2. по инкрементному айди можно отсортировать, а по сгенерированному нет.



то есть, тебе надо заводить дополнительное поле для сортировки по нему. created_at не подойдет - в одну секунду может прилететь 10 записей. только если хранить microtime.

короче, для каких-то случаев может и проканает
490 1124889
>>24655

Также есть более серьезная мера защиты - клиентские SSL сертификаты: https://habrahabr.ru/post/213741/

>>24744

role - не лучше ли сделать ENUM или foreign key на другую таблицу?

А у тебя предусмотрены ли периодические ивенты, например, день рождения по идее каждый год происходит.

Ключом в event_type наверно лучше сделать id. Он меньше места занимает.

Меня конечно беспокоит наличие похожих сущностей (users - participants, events - reminders), тут явно просится наследование или еще какое-то обобщение, но не станет ли из-за этого схема БД сложнее...

>>24745

Профит в том, что данные хранятся в единственном экземпляре и не может быть противоречий. Также, их легко редактировать, так как не надо искать все копии данных. Выгоды/недостатки нормализации давно изучены.

Насчет скорости выполнения запроса, джойны не проблема, если там джойнится например 1 запись и все это по индексам. Джойны - проблема, когда у тебя 2 больших таблицы и надо искать по обеим сразу и по каждой таблице поиск дает много результатов (например: найти компании с отделением в городе X, работающие в сфере Y, где связи компания-город и компания-сфера это многие-ко-многим).

Если номализованные данные работают медленно, всегда можно сделать денормализованную копию, в каком-нибудь отдельном хранилище, заточенном под поиск, вроде сфинкса или кеша. Но там свои подвохи.
491 1124890
>>24824

Профит генерируемых ключей - возможность генерации на клиенте. Это годится в таких ситуациях: в моб. приложении при отсутствии связи с сервером, при отсутствии прямого доступа к БД (приложение генерирует сущность и связанные с ней, кладет в локальное хранилище, позже синхронизирует с центральной БД).

> Я вижу серьёзное преимущество генерируемых в том, что при добавлении записи во множество таблиц, мне не нужно сначала вставлять данные в основную таблицу, получать автоинкрементальный айди и потом только делать вставку с этим айди в дочерние таблицы. Я просто генерирую айди и распихиваю связанные по этому айди данные в нужные таблицы без лишних телодвижений.



Не очень понятно, а в чем тут выгода? Что мешает вставить сначала запись, а потом связанные с ней?

> Единственный серьёзный недостаток, который я вижу в генерации, это возможность коллизий. Но всегда можно подобрать алгоритм генерации, который сведёт такие случаи к нулю.



Да, и они давно уже придуманы.

>>24853

> по инкрементному айди можно отсортировать, а по сгенерированному нет.


Можно добавить дату вставки и сортировать по ней.

> генерация по-настоящему уникального значения - более дорогая операция


не думаю, есть алгоритмы.

>>24816

Я прочитал это предложение в англ. версии и там добавлено слово simply:

> Where possible avoid simply using id as the primary identifier for the table.



Также, в английской версии внизу есть ссылки на обсуждения: http://www.sqlstyle.guide/ и пояснения автора https://www.simonholywell.com/post/2016/12/sql-style-guide-misconceptions/?utm_source=sqlstyle.guide-sqlstyle.guide&utm_medium=link&utm_campaign=footer-link

> id columns and surrogate keys


> You do not need them [surrogate keys] in most cases as better keys often exist in the data already.



Также, можно попросить пояснений в issues: https://github.com/treffynnon/sqlstyle.guide/issues

Я думаю, речь о том, что если в данных есть естественный ключ, то рекомендуется использовать его, а не создавать искуственный. Но должен заметить, что у искуственных ключей есть преимущества, например:

- он останется ключом даже при смене условий задачи (ты сделал номер паспорта ключом, а потом узнал, что паспорта можно менять и в каких-то случаях иметь несколько)
- он мало весит, а размер полей влияет на размер индекса и объем требуемой под них памяти в больших таблицах. Индексы с 100-символьным колонками работают совсем не так хорошо, как индекс из интов (желательно подтвердить это тестом).
491 1124890
>>24824

Профит генерируемых ключей - возможность генерации на клиенте. Это годится в таких ситуациях: в моб. приложении при отсутствии связи с сервером, при отсутствии прямого доступа к БД (приложение генерирует сущность и связанные с ней, кладет в локальное хранилище, позже синхронизирует с центральной БД).

> Я вижу серьёзное преимущество генерируемых в том, что при добавлении записи во множество таблиц, мне не нужно сначала вставлять данные в основную таблицу, получать автоинкрементальный айди и потом только делать вставку с этим айди в дочерние таблицы. Я просто генерирую айди и распихиваю связанные по этому айди данные в нужные таблицы без лишних телодвижений.



Не очень понятно, а в чем тут выгода? Что мешает вставить сначала запись, а потом связанные с ней?

> Единственный серьёзный недостаток, который я вижу в генерации, это возможность коллизий. Но всегда можно подобрать алгоритм генерации, который сведёт такие случаи к нулю.



Да, и они давно уже придуманы.

>>24853

> по инкрементному айди можно отсортировать, а по сгенерированному нет.


Можно добавить дату вставки и сортировать по ней.

> генерация по-настоящему уникального значения - более дорогая операция


не думаю, есть алгоритмы.

>>24816

Я прочитал это предложение в англ. версии и там добавлено слово simply:

> Where possible avoid simply using id as the primary identifier for the table.



Также, в английской версии внизу есть ссылки на обсуждения: http://www.sqlstyle.guide/ и пояснения автора https://www.simonholywell.com/post/2016/12/sql-style-guide-misconceptions/?utm_source=sqlstyle.guide-sqlstyle.guide&utm_medium=link&utm_campaign=footer-link

> id columns and surrogate keys


> You do not need them [surrogate keys] in most cases as better keys often exist in the data already.



Также, можно попросить пояснений в issues: https://github.com/treffynnon/sqlstyle.guide/issues

Я думаю, речь о том, что если в данных есть естественный ключ, то рекомендуется использовать его, а не создавать искуственный. Но должен заметить, что у искуственных ключей есть преимущества, например:

- он останется ключом даже при смене условий задачи (ты сделал номер паспорта ключом, а потом узнал, что паспорта можно менять и в каких-то случаях иметь несколько)
- он мало весит, а размер полей влияет на размер индекса и объем требуемой под них памяти в больших таблицах. Индексы с 100-символьным колонками работают совсем не так хорошо, как индекс из интов (желательно подтвердить это тестом).
492 1124891
>>24839

Я иногда пишу AS. Насчет второго - да, редко.

>>24649

Обычно для тестов используют отдельный конфиг и в нем указывается отдельное соединение с тестовой БД. Насчет контейнера, тут можно выбирать - брать сервисы из контейнера или создавать самостоятельно.

>>24860

> created_at не подойдет - в одну секунду может прилететь 10 записей


А когда может понадобиться такая сортировка, с точностью до микросекунд? В высокочастотной торговле? В списке комментариев или статей она точно не нужна.
493 1124903
Блядь, я прошел самый первый гайд по основам основ, за пару недель. Но я даже и представить не могу, как можно связать то что я прошел с чем то на сайтах. Мне дурно становиться, когда я осознаю что для того что бы потом зарабатывать хотя бы 15-20к надо еще года 2 учить и читать, пиздееееец.
494 1124904
>>24903
станвится*
495 1124918
>>24903
1. лучше полюбить процесс изучения и чтения, т.к. это придется делать всю жизнь.
2. для начала работы полгода за глаза хватит
496 1124920
>>24918
Ты имеешь ввиду полгода для начала чтоб меня взяли в какую нибудь контору? Но что делать, если я школьник 16 лвл? Я даже если выучу сейчас то, с чем меня возьмут на какую никакую работу, то из за возраста все пойдет нахуй.
497 1124922
>>24889

>Также есть более серьезная мера защиты - клиентские SSL сертификаты


спасибо. это в принципе то, что я и хотел
498 1124925
>>24920
изучай, пили свои проекты, чтобы в 18 тебя с руками оторвали. в айти нет дискриминации по возрасту, как многие вкатывальщики думают, но есть особая любовь многих компаний к молодым "перспективны" студентикам. также на фрилансе можешь работать без ограничений по возрасту.

плюс когда я учился в школе, у меня не было вопросов "но что делать". я помню тусил с друзьями, пытался поебаться, гулял.
499 1124926
>>24925

>чтобы в 18 тебя с руками оторвали


ты хочешь сказать, что если я буду до 18 изучать php и пилить проекты(сайты, как я понял?), то меня могут просто взять в какую нибудь компанию, без вышки и прочего?
500 1124929
Тяжело ли освоить AJAX, если практически не можешь в жс? Пилю задачу от ОПа на файлообменник, хочу, чтобы комменты на странице после отправки сразу отображались. Как вообще такое реализуется, через фреймворк? Или на чистом жс тоже можно?
501 1124948
>>24889

>role - не лучше ли сделать ENUM или foreign key на другую таблицу?



пожалуй ENUM норм, т.к. пока будет только одна роль user.

>>24889

>А у тебя предусмотрены ли периодические ивенты, например, день рождения по идее каждый год происходит.



да, в таблице Event_types, поле is_annual, например тип "день рождения" is_annual: true. Но можно его перенести в таблицу Events. Я не стал этого делать, потому что хотел избежать при создании нового события необходимость выставлять периодичность, когда выбрал один из типов событий, который ее предполагает.
Если периодичность перенести в таблицу Events, то это поле будет или дублироваться или придется каждый раз указывать периодичность. Насколько приемлемо дублирование, нужно выбрать то, которое будет приоритетное?
Можно еще сделать два события "ежегодное событие без названия" и "разовое событие без названия", которые будут присваиваться событию, если не выбран тип но периодичность.

Только сейчас понял, что события получились общие для всех. Наверное, нужно сделать, чтобы часть типов событий была общая - предустановленные типы (др, свадьба и тд.), а часть приватными, те что юзер создаст сам, были видны только ему. Добавить еще одно поле "owner_user_id" в таблице Event_types, в которое вписывать создателя.

>>24889

>Ключом в event_type наверно лучше сделать id. Он меньше места занимает.


А если в таблице появится поле owner_user_id, то ключом можно сделать сочетание type и owner_user_id? Или id будет удобнее?

>>24889

>Меня конечно беспокоит наличие похожих сущностей (users - participants, events - reminders), тут явно просится наследование или еще какое-то обобщение, но не станет ли из-за этого схема БД сложнее...


Пойду полистаю аниме про базы данных, там наверняка есть про наследование.
502 1124964
Аноны, все тот же долбоеб 16 лвл , стоит ли вообще поступать в вуз, если есть возможность? Насчет армии похуй, я уже вроде не годен из за сколиоза 2 степени и бронхиальной астмы. Если я буду сейчас вкатываться, то к 18-19 я наверное смогу найти днищеработку макакой за 15-20к? А там уже по нарастающей.
503 1124966
>>24929
Это можно сделать на жс без фреймворков. В оп посте есть задачи по js.

Еще есть фрейморк Jquery, который несколько упрощает запросы к элементам на странице и работу с Ajax. Но использование его без знания основ js - это путь на темную сторону.
504 1124975
>>24964

>стоит ли вообще поступать в вуз


да, стоит, даже если не возможности. Не факт, что ты в конечном итоге свяжешь свою жизнь с программированием, и при трудоустройстве на любую другую работу наличие диплома о во будет играть если не решающую роль, то наверняка скажется на твоей зарплате. Многим приходится заканчивать заочку в 30+ лет, чтобы получить повышение или определенную должность. И чем старше ты будешь, тем более значимым будет диплом или его отсутствие. Устроиться в днищеконтору ты всегда успеешь, а если тебе придется выбирать, на что потратить свою молодость, то универ будет лучшим выбором. Если ты будешь заниматься, то сможешь подрабатывать, главное не соглашайся на полную ставку, пока не закончишь универ.
505 1124976
>>24975
спасибо за совет, анон
506 1125021
пиздец,сел за изучение лаварела,а там сука хуева куча команд,и где он сука легче чистого пхп?
507 1125023
ideone не работает :с
508 1125034
>>24975

>будет играть если не решающую роль, то наверняка скажется на твоей зарплате


скажется на зарплате, серьезно? ты в каком мире живешь? я в дс работаю, тут все хуй клали на дипломы.

>Многим приходится заканчивать заочку в 30+ лет


а может ты просто в россельхознанотехнологиях работаешь?

>>25021
для изучения фреймворков нужно знать сам язык, чтобы понимать, что к чему. он не легче и не тяжелее, а избавляет тебя от рутинных операций. допустим, орм тебе дает возможнсть не писать запросы самому, но для того чтобы ее использовать, нужно сначала пописать их вручную, построить связи между таблицами и т.д.
509 1125043
>>24926
пхп многогранен, на нем можно пилить большие проекты, не только сайты. тебя могут легко взять в компанию, если ты будешь обладать хорошими навыками и знать фундамент. если ты будешь еще параллельно студентом, это дополнительный плюс, не более.

>>24964
если есть возможность, поступай, главное не думай что диплом "скажется на зарплате" и прочую хуйню. для зарплаты полезнее будет решить задачу ОПа про список студентов.

но сам по себе вуз (нормальный) - это заебись. я когда учился, было весело.
510 1125075
задам нубский вопрос-можно ли связать пхп и жабаскрипт?
511 1125109
>>24446
google obfuscate
512 1125113
>>24744
У тебя все связи реализованы через промежуточные таблицые. Такое используют используют только для реализации связей многие-ко-многим. Ты уверен что оно тебе надо. Как минимум, в случае reminder-to-event мне не приходит в голову сценария когда на один reminder будет несколько событий.
513 1125114
>>25075
также как пхп и хтмл. или конкретнее задай вопрос
514 1125119
>>25075

>пхп и жабаскрипт?


Да, раньше для этого была библиотека xajax, но сейчас достаточно json на стороне php и jquery на клиенте.
515 1125121
Давайте вспомним величайшие веб-проекты, работающие на php.

Facebook
PornHub
516 1125254
>>23868

>Не хочешь допилить и поделиться решением со всеми? Придется расковырять фейкер, понять, как он рабоатет, и может обсудить это с его разработчиками.


Посмотрел исходники фейкера, по ходу это надо на уровне ядра библиотеки менять, чтобы такую возможность добавить. Я пока что наверное слишком ньюфаг для такого, но мб потом, когда опыта наберусь.
517 1125265
Приветствую анонов. У меня вопрос про класс валидации. Я смотрел несколько разных вариантов его реализации, но так и не пришел к единому решению. В одном варианте есть один класс валидации, и работает он образно в духе isValid = validator->validate(['username' => 'required']), в самом классе много методов и переменных, сообщения об ошибке могут храниться как в нем, так и во вспомогательном классе, но в целом много разных циклов работы с массивами, их ключами и т.д. То есть в целом сам класс выглядит как большая обёртка функций скорее, ну или мне так просто кажется. Другой подход это делать очень много громоздких классов валидаторов, где каждый класс отвечает за определенное правило, например EmailValidator или LenghtValidator, они могут наследовать абстрактный валидатор, это выглядит более "правильно", каждый класс делает только то, что от него нужно, но кода получается значительно больше, еще и объекты "лишние" нужно создавать, при том что в задаче про студентов довольно много инпутов у формы. Я не знаю насколько сильно нужно заморачиваться по этому поводу, и насколько одно работает быстрее другого.
518 1125338
Кто пробовал HHVM? Говорят годнота, хоть и толком на нём ничего не написано.
519 1125343
>>25338
Был актуален лет 5-7 назад. Сейчас PHP7 из коробки делает его по производительности раза в два.
520 1125351
>>25034

>скажется на зарплате, серьезно? ты в каком мире живешь? я в дс работаю, тут все хуй клали на дипломы.


Твой опыт не показателен, т.к. вероятно тебе меньше 30 и ты работаешь в ойти. Мало информации, чтобы сделать достоверный вывод о том, насколько скажется диплом на зп или нет.

>>25034

>а может ты просто в россельхознанотехнологиях работаешь?


Именно. Гос сектор и обслуживающий его бизнес самый крупный работодатель в РФ. А трактористом дают дополнительные балы за диплом. И если он будет учиться не только для корочки, то это только прибавит возможностей для последующего трудоустройства. Хорошие специалисты нужны всегда и везде.
521 1125355
>>25351
Хорошие спецы и без корочки нужны, поверь. Знакомый 3 фирмы держит, постоянно ищет спецов, ибо именно спецов в России очень сильно не хватает.
522 1125356
>>23856
Ого, как сложно. Я остановился на том, что сделал обертку для file_get_contents, кидающую эксепшн на домен не из вайт-листа, а саму fgc для интернета не использую.
Без названия (1).jpg50 Кб, 604x402
523 1125360
Поясните за полиморфизм.
Есть объект А, он реализует метод lol(int $digit). Есть объект B extends A, который реализует lol по-своему, а именно ему для работы нужно два параметра - lol(int $digit, bool $flag). Флаг мне этот жизненно необходим, он участвует в переопределнной реализации. Задать через конструктор я его не могу, потому что флаг может быть разным при каждом вызове метода. Метод может вызываться много раз за жизнь объекта. Хуячить по объекту каждый раз, чтобы вызвать lol, мне кажется хреновой идеей.
Что делать? Можно так ломать сигнатуру метода, если очень надо?
524 1125362
>>25360
А, только что в голову шибануло. Если я сделаю lol(int $digit, bool $flag = false), то, значит, полиморфизм я не нарушу.
525 1125364
>>25113

>Как минимум, в случае reminder-to-event мне не приходит в голову сценария когда на один reminder будет несколько событий.


На один event может быть несколько reminder. Reminder это дата+время когда должно сработать напоминание. Т.e. связь один-к-многим. Например, когда нужно сделать несколько дел заранее, найти подарок - на это потребуется неделя, и погладить носки - это можно сделать накануне события. Думаю, что этот функционал нужно реализовать. Но можно обойтись без промежуточной таблицы, добавив в reminder поле event_id. Поскольку я нубас, не сразу понял, что можно сделать проще. Какого отношение выгоды к геморрою обоих решений?
15165518738940.jpg671 Кб, 2560x1920
526 1125392
PDO или mysqli?
первый более современый,но меньше разжеваной инфы,второй старый
нубяра кун
527 1125397
>>25392

>PDO


Конечно это, потому что универсальный. В смысле мало инфы? С чем у тебя конкретная проблема?
528 1125398
>>25397
инфа есть,но вот хорошо разжеваной,почти нет.приходиться скакать по сайтам и собирать инфу на каждое действие
529 1125399
>>25397
и все?ну как бы мне другие БД не нужны
530 1125417
Подскажите пожалуйста как вставить функцию в строку, чтобы работало :

$predl=preg_replace('регулярка', 'функция от $0', 'текст');
531 1125422
>>25399

>и все?


Во-первых, одно это уже должно быть определяющим фактором в выборе, во-вторых, mysqli не поддерживает именованные параметры, в-третьих, pdo - уже давно стандарт в разработке, в-четвёртых, гугл ит pdo vs mysqli
532 1125423
>>25422
окей.щас я подошел к теме регистрации на сайте,так что в течении дня я буду задавать вопросы по этой теме
нубяра кун
533 1125428
>>25351

>Именно. Гос сектор и обслуживающий его бизнес самый крупный работодатель в РФ


ну все, вопросов нет тогда. у вас-то реально тимлидом без диплома не станешь. а так поучиться в хорошем вузе - это не то чтобы плохо, я и не агитировал против этого. главное - работать параллельно. а то я на одной работе видел много выпускников, которые свои дипломные проекты делали про машинное обучение, а в офисе два дня не могли понять как послать апи-запрос.
534 1125431
Есть один nginx на дебиане со следующим конфигом:

location ~ \. {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
fastcgi_pass ...;
}

tcpdump показывает, что параметр script_filename каждый раз "/". Если в конфиге прописать путь к скрипту, работает.
Это ведь не нормально?
535 1125433
>>25431
Docker-образ NGINXа по умолчанию делает envsubst, чтобы было удобнее менять host etc. Теперь надо все $ эскейпить. Мда.
536 1125441
Пытаюсь в могильную верстку.

Понравилась данная полоска у гугла. Попробовал сделать своими силами, получилось только через костыль "width: max-content; display: flexbox;", ползает. Полез проверить себя в код страницы гугла, а там нет флексбокса и ширина нигде не затрагивается вообще (блоки в блоках в блоках...) и офк работает у них. Пытался проследить стили, не могу понять как они такого эффекта добились с использованием базовых параметров только.

У моего решения недостаток:
https://caniuse.com/#search=max-content

(Еще блоки, содержащие картинку на 4 пикселя выше и оставляют прозрачную полосу внизу, хотя должны бы тютелька в тютельку облегать картинку, этому я ответа пока не нашел тоже)

Может заглядывают фанаты верстки, поднаправьте пожалуйста в нужное русло.
537 1125443
а я могу арендоавть свой впс и самостоятельно разбить его еще на несколько виртуалок?
538 1125451
>>25443
Неправильная постановка вопроса. Для чего тебе это нужно? Какую задачу тебе нужно решить?
539 1125456
>>25451
допустим, почтовую рассылку вынести в отдельный виртуальный сервер внутри моего впс. ну или вообще проект поделить на микросервисы.

тут главный вопрос - можно ли тенхически сделать виртуалку внутри виртуалки и насколько это будет костыльное решение.
540 1125457
код подключения к БД нужно вынести в отдельный файл,или писать и в коде регистрации на сайте и в коде входа на сайте?
541 1125476
Анон, скажи, как сделать условие с успешным выполнением функции?

Есть простенький код:
542 1125477
>>25476
Преждевременное отправление.

$zip = new ZipArchive;
$zip->open($_GET[name]);
$zip->extractTo('./');
$zip->close();
echo "Ok!";

Я хочу, чтобы было так:

if (функция ебашит){
echo 'Ok!';
}else{
echo 'haha, faggot!';
}
543 1125482
БД тред молчит, поэтому попробую здесь.
Помогите пожалуйста спроектировать оптимальную архитектуру в mysql для хранения примерно таких поступающих данных:
{
mark: 4.77,
timestamp: 1516785655,
[{
question_text: 'some text',
answers_text: ['some', 'array', 'with', 'text', 'values'],
selected_answers: [0, 2],
},
{
question_text: 'some other text',
answers_text: ['some', 'other', 'array', 'with', 'text', 'values'],
selected_answers: [1, 2],
}]
}
Сам бы сделал что-то вроде такого:
sessions(id: unsigned_bigint, mark: decimal[1,2], timestamp: timestamp),
questions(id: unsigned_bigint, session_id: unsigned_bigint, text: text),
answers(id: unsigned_bigint, question_id: unsigned_bigint, text: text),
selected_answers(id: unsigned_bigint, question_id: unsigned_bigint, value: unsigned_smallint).
Насколько пригодна в реальном мире предложенная мной структура?
544 1125487
>>25477
Твоя функция должна возвратить некое значение, которое в общем случае можно привести к true/false

тогда

if (функция ебашит === TRUE){
echo 'Ok!';
}else{
echo 'haha, faggot!';
}

(Только у тебя не функция, а объект с методами)
545 1125490
>>25487

>Твоя функция должна возвратить некое значение, которое в общем случае можно привести к true/false



Т.е. по факту выполнения действия логику построить нельзя?

>(Только у тебя не функция, а объект с методами)


Я немножко гомонитарий3
546 1125493
>>25490
Если есть документация к этому ZipArchive, посмотри, как там выбрасываются наружу ошибки (а может быть он сам с ними что-то делает?), вот эти ошибки (или исключения) тебе и нужно ловить.

В целом каждый этап может возвращать какие-то результаты, тебе может понадобиться проверять их все, а может ни одного, надо смотреть в класс объекта.
547 1125519
За пять месяцев я переписал сервис по автоматизации отслеживания грузов охранниками с голого php на Yii2 и добавил некоторую функциональность. А именно "Постовую ведомость" - журнал выданного охранникам оружия. Плюс отдельную таблицу для оружия и таблицу связей "многие ко многим" между таблицами охранников и оружия, чтобы в постовой ведомости можно было выбрать охранника и далее выбирать только те стволы, которые принадлежат именно ему. Писал это в качестве хобби, в свободное время, для текущей работы (работаю не программистом).

Посмотрите пожалуйста код на кривости, которые бросаются в глаза (в недра лучше не лазить, просто проглядеть по верхам). Знаю, что написанное можно номинировать на говнокод.ру, но всё же сервис работает.

https://github.com/tsubaku/flights.yii
548 1125542
>>25519

Конфиг подключения к бд не стоит хранить в системе контроля версий.

Контроллер SiteController слишком жирный, потому что ты свалил туда в кучу вообще всё. Надо разделить логически на меньшие контроллеры, примерно как у тебя сделано с моделями.
549 1125546
>>25542

>Конфиг подключения к бд не стоит хранить в системе контроля версий.


Блин, не заметил. Выпилить весь файл config/db.php через .gitignore?

>Контроллер SiteController слишком жирный


Сам подумывал, но как-то не собрался. Разобью. Так же, по отдельному контроллеру для каждой модели/странице, или делить по другим признакам?
550 1125560
>>25546

>Блин, не заметил. Выпилить весь файл config/db.php через .gitignore?


Ну да. И добавить туда пример конфига.

>Так же, по отдельному контроллеру для каждой модели/странице, или делить по другим признакам?


Нужно руководствоваться логикой приложения и удобством последующей разработки-рефакторинга. Когда вся логика загрузки файлов, например, у тебя в отдельном контроллере, то это удобно, например.
551 1125571
>>25519

Я пока еще не проверил код, с удовольствием проверю позже, а пока дам совет не использовать размытие для скрытия приватных данных, а использовать черные или серые плашки. А еще лучше - вбить у себя на локалхосте фейковые данные и сделать скриншоты с ними. Статья про восстановление размытых картинок: https://habrahabr.ru/post/152885/
552 1125572
>>25351

>Гос сектор и обслуживающий его бизнес самый крупный работодатель в РФ


но не самый привлекательный
553 1125576
>>18584
Самый простой способ это XAMPP
554 1125583
как сделать простую систему авторизации c PDO?
555 1125754
test
https://github.com/tsubaku/flights.yii 556 1125755
>>25546

Контроллеры не обязаны соответствовать моделям. Они соответствуют разделам и страницам сайта. На каждый раздел обычно делается свой контроллер. У тебя есть меню, на каждый пункт стоит сделать свой контроллер.

Ну например, контроллер GuardController с методами actionList, actionEdit, actionDelete может отвечать за вывод списка охранников и его редактирование. Но не за все сразу.

Если ты сомневаешься, то лучше выбирать вариант, при котором будет больше маленьких контроллеров. Я например иногда подумываю над идеей вообще делать каждое действие отдельным классом.

Название SiteController ничего не значит - Site тут ничего не знаичт и остается просто "контроллер" непонятно чего.

Верстка кривовата - если есть желание разобраться, в ОП посте есть задания на HTML/CSS.

Папку с тестами надо почистить, раз они не используются. Зачем держать неактуальный код? А еще лучше - прочесть урок по тестированию из ОП-поста и сделать их нормально.

https://github.com/tsubaku/flights.yii/blob/master/models/Client.php
тут надо почистить код, отформатировать по стандартам (phpformatter.com) и сделать красиво.

Перед классом надо бы написать, чему он соответствует. А то не очень понятно. Понятно, что клиент, но что за клиент - непонятно. Это организация-клиент, или клиент в смысле HTTP клиент?

Формы и модели БД - не лучше ли хранить в 2 отдельных папках?

https://github.com/tsubaku/flights.yii/blob/master/views/site/manager.php
В шаблонах не надо использовать echo, надо использовать <?= ?>. для вывода HTML вообще не надо писать echo. Почитай урок про шаблоны: https://github.com/codedokode/pasta/blob/master/php/templates.md

При выводе данных нужно использовать экранирование (Html::escape или как-то так).

> echo "<td><div class='$container'>$fio</div></td>"; //



Тут может быть XSS. Урок https://github.com/codedokode/pasta/blob/master/security/xss.md

В общем, шаблоны надо тоже почистить и привести в порядок.

> public function actionManager()


> if ( Yii::$app->request->post('add-button') ) {


Добавление надо бы сделать отдельным действием.

В контроллере не должно быть SQL запросов. Вместо этого должно быть обращение к методу модели. То есть разделение таке: модель отвечает за получение/исправление данных в БД, а контроллер - за прием параметров запроса (GET/POST) и вывод результатов. Не так:

> $query = "SELECT * FROM flight WHERE data_vyezda between :date1 and :date2";


> $listFlight = flight::findBySql($query, [':date1' => $date1, ':date2' => $date2])->with('photo')->asArray()->all();



А так:

$flights = $flightsModel->getFlightList($date1, $date2);

И в таком варианте мы например можем повторно использовать код модели, вызывая getFlightList где-то еще.

Урок про MVC, посмотри, как там это сделано: https://github.com/codedokode/pasta/blob/master/arch/mvc.md

> $cellColumn = Yii::$app->request->post('column_in_db');


> $model = Flight::findOne($cellId); //Выбрать из таблицы Flight первую запись с id=$cellId


> $model->$cellColumn = $cellValue; //Выбрать из этой записи ячейку в столбце $cellColumn и записать туда $cellValue


В таком подходе есть недостаток: ты не проверяешь, какие поля можно редактирвать, а какие нельзя. Должен быть белый список разрешенных к редактированию полей. Удобно описать его где-то в модели.

По поводу аякса - проверь сам, выполняются ли рекомендации из этого урока: https://github.com/codedokode/pasta/blob/master/js/ajax.md
https://github.com/tsubaku/flights.yii 556 1125755
>>25546

Контроллеры не обязаны соответствовать моделям. Они соответствуют разделам и страницам сайта. На каждый раздел обычно делается свой контроллер. У тебя есть меню, на каждый пункт стоит сделать свой контроллер.

Ну например, контроллер GuardController с методами actionList, actionEdit, actionDelete может отвечать за вывод списка охранников и его редактирование. Но не за все сразу.

Если ты сомневаешься, то лучше выбирать вариант, при котором будет больше маленьких контроллеров. Я например иногда подумываю над идеей вообще делать каждое действие отдельным классом.

Название SiteController ничего не значит - Site тут ничего не знаичт и остается просто "контроллер" непонятно чего.

Верстка кривовата - если есть желание разобраться, в ОП посте есть задания на HTML/CSS.

Папку с тестами надо почистить, раз они не используются. Зачем держать неактуальный код? А еще лучше - прочесть урок по тестированию из ОП-поста и сделать их нормально.

https://github.com/tsubaku/flights.yii/blob/master/models/Client.php
тут надо почистить код, отформатировать по стандартам (phpformatter.com) и сделать красиво.

Перед классом надо бы написать, чему он соответствует. А то не очень понятно. Понятно, что клиент, но что за клиент - непонятно. Это организация-клиент, или клиент в смысле HTTP клиент?

Формы и модели БД - не лучше ли хранить в 2 отдельных папках?

https://github.com/tsubaku/flights.yii/blob/master/views/site/manager.php
В шаблонах не надо использовать echo, надо использовать <?= ?>. для вывода HTML вообще не надо писать echo. Почитай урок про шаблоны: https://github.com/codedokode/pasta/blob/master/php/templates.md

При выводе данных нужно использовать экранирование (Html::escape или как-то так).

> echo "<td><div class='$container'>$fio</div></td>"; //



Тут может быть XSS. Урок https://github.com/codedokode/pasta/blob/master/security/xss.md

В общем, шаблоны надо тоже почистить и привести в порядок.

> public function actionManager()


> if ( Yii::$app->request->post('add-button') ) {


Добавление надо бы сделать отдельным действием.

В контроллере не должно быть SQL запросов. Вместо этого должно быть обращение к методу модели. То есть разделение таке: модель отвечает за получение/исправление данных в БД, а контроллер - за прием параметров запроса (GET/POST) и вывод результатов. Не так:

> $query = "SELECT * FROM flight WHERE data_vyezda between :date1 and :date2";


> $listFlight = flight::findBySql($query, [':date1' => $date1, ':date2' => $date2])->with('photo')->asArray()->all();



А так:

$flights = $flightsModel->getFlightList($date1, $date2);

И в таком варианте мы например можем повторно использовать код модели, вызывая getFlightList где-то еще.

Урок про MVC, посмотри, как там это сделано: https://github.com/codedokode/pasta/blob/master/arch/mvc.md

> $cellColumn = Yii::$app->request->post('column_in_db');


> $model = Flight::findOne($cellId); //Выбрать из таблицы Flight первую запись с id=$cellId


> $model->$cellColumn = $cellValue; //Выбрать из этой записи ячейку в столбце $cellColumn и записать туда $cellValue


В таком подходе есть недостаток: ты не проверяешь, какие поля можно редактирвать, а какие нельзя. Должен быть белый список разрешенных к редактированию полей. Удобно описать его где-то в модели.

По поводу аякса - проверь сам, выполняются ли рекомендации из этого урока: https://github.com/codedokode/pasta/blob/master/js/ajax.md
557 1125756
Аноны, если вдруг у кого-то не работает отправка сообщений, и не показывается капча, то очистите куки, и оно может починиться.

>>25482

Я не вижу, где sessions во входных данных.

>>25477

Надо читать мануал и смотреть, как каждая функция сигнализирует об ошибке. Ну например:

> $zip->open($_GET[name]);



Читаем мануал: http://php.net/manual/ru/ziparchive.open.php

> Возвращаемые значения


> Возвращает TRUE при успешном завершении или код ошибки.


> ZipArchive::ER_EXISTS


> Файл уже существует.


...

Вот и ставь проверку, что open вернула true, а если не true, то анализируешь код ошибки и выводишь сообщение. Там ниже есть пример кода.

И так по каждой использованной функции. Некоторые IDE умеют показывать такие подсказки прямо не выходя из редактора.

Также, у тебя довольно опасный код: ты позволяет открывать вообще любой архив на компьютере. надо сделать ограничение, например, открывать архивы только из определенной папки и только с разрешенными символами в названии.

>>25457

Зависит от архитектуры. Ты можешь либо написать этот код в файле инициализации (bootstrap) и передавать объект соединения куда требуется, либо сделать функцию, осуществляющую подключение.

Немного есть в этом уроке, хотя он сложный: https://github.com/codedokode/pasta/blob/master/arch/di.md
557 1125756
Аноны, если вдруг у кого-то не работает отправка сообщений, и не показывается капча, то очистите куки, и оно может починиться.

>>25482

Я не вижу, где sessions во входных данных.

>>25477

Надо читать мануал и смотреть, как каждая функция сигнализирует об ошибке. Ну например:

> $zip->open($_GET[name]);



Читаем мануал: http://php.net/manual/ru/ziparchive.open.php

> Возвращаемые значения


> Возвращает TRUE при успешном завершении или код ошибки.


> ZipArchive::ER_EXISTS


> Файл уже существует.


...

Вот и ставь проверку, что open вернула true, а если не true, то анализируешь код ошибки и выводишь сообщение. Там ниже есть пример кода.

И так по каждой использованной функции. Некоторые IDE умеют показывать такие подсказки прямо не выходя из редактора.

Также, у тебя довольно опасный код: ты позволяет открывать вообще любой архив на компьютере. надо сделать ограничение, например, открывать архивы только из определенной папки и только с разрешенными символами в названии.

>>25457

Зависит от архитектуры. Ты можешь либо написать этот код в файле инициализации (bootstrap) и передавать объект соединения куда требуется, либо сделать функцию, осуществляющую подключение.

Немного есть в этом уроке, хотя он сложный: https://github.com/codedokode/pasta/blob/master/arch/di.md
558 1125757
>>25443

Скорее всего ты не сможешь использовать аппаратное ускорение виртуализации,то есть будет медленно. Кроме виртуализации есть еще паравиртуализация (OpenVZ) и linux контейнеры (lxc, docker), которые делают примерно то же, но без тормозов. Ну и наконец, может тебе просто сделать несколько linux-пользователей? linux довольно хорошо изолирует пользователей друг от друга.

Для микросервисов пойдут контейнеры.

И еще можно вместо одной виртуалки купить несколько, но поменьше.

>>25441

Ты используешь свойства, которые мало где поддерживаются, и хорошо, что ты это понял.

Я вижу такие варианты с классическим CSS2.1:

1) сделать враппер width: 100%, overflow: auto (hidden, если хочешь прокручивать яваскриптом), в него вложить див .line с display: inline-block, white-space: nowrap и картинками с display: inline-block. Плюс: вертикальное выравнивание. Подвох: пробелы между картинками, статья с костылями http://css-live.ru/articles/zagadochnye-otstupy-mezhdu-inlajn-blokami.html . Подвох: nowrap надо отключать для подписей к каринкам. Плюс: Можно использовать text-align для выравнивания .line по центру, когда картинок мало.

Объяснение: картинка или див с inline-block ведет себя как слово в тексте, nowrap запрещает перенос слов и они выстраиваются в длинную линию. inline-block на родителе (.line) нужен, чтобы он тянулся по ширине содержимого, просто block по умолчанию принимает ширину 100% родителя и не годится.

Для любопытных: на ширину содержимого тянутся такие блоки: inline-block, float, pos: abs, table-cell. Там исопльзуется алгоритм shrink-to-fit: https://github.com/codedokode/pasta/blob/master/html/shrink-to-fit.md

Еще немного информации: https://github.com/codedokode/pasta/blob/master/html/positioning.md

2) сделать враппер width 100%, ovf auto;. В него вложить блок div с width=суммарная ширина картинок,вычисленная JS или на сервере, и с clearfix. В него вложить блоки картинок, каждая с float: left. Плюс: нет пробелов между блоками.

Объяснение: флоаты встраиваются горизонтально по ширине родителя, мы задаем такую ширину, чтобы они все влезли в одну строчку.

3) сделать враппер width 100%, ovf: auto, в него вложить таблицу из 1 строки и множества колонок. Таблицу сделать не тегом table, а дивами с display: table, table-row, table-cell. Плюс: выравнивание как угодно, в том числе вертикально, железобетонность конструкции. Минус: у таблиц куча ограничений в плане позиционирования. Например, нельзя делать pos abs относительно ячейки.

Я бы сделал все 3 варианта и протестировал, и вбросил ссылочки в тред.

>>25417

Используй preg_replace_callback. Раньше там был другой способ, но он небезопасен и открывает уязвимости.
558 1125757
>>25443

Скорее всего ты не сможешь использовать аппаратное ускорение виртуализации,то есть будет медленно. Кроме виртуализации есть еще паравиртуализация (OpenVZ) и linux контейнеры (lxc, docker), которые делают примерно то же, но без тормозов. Ну и наконец, может тебе просто сделать несколько linux-пользователей? linux довольно хорошо изолирует пользователей друг от друга.

Для микросервисов пойдут контейнеры.

И еще можно вместо одной виртуалки купить несколько, но поменьше.

>>25441

Ты используешь свойства, которые мало где поддерживаются, и хорошо, что ты это понял.

Я вижу такие варианты с классическим CSS2.1:

1) сделать враппер width: 100%, overflow: auto (hidden, если хочешь прокручивать яваскриптом), в него вложить див .line с display: inline-block, white-space: nowrap и картинками с display: inline-block. Плюс: вертикальное выравнивание. Подвох: пробелы между картинками, статья с костылями http://css-live.ru/articles/zagadochnye-otstupy-mezhdu-inlajn-blokami.html . Подвох: nowrap надо отключать для подписей к каринкам. Плюс: Можно использовать text-align для выравнивания .line по центру, когда картинок мало.

Объяснение: картинка или див с inline-block ведет себя как слово в тексте, nowrap запрещает перенос слов и они выстраиваются в длинную линию. inline-block на родителе (.line) нужен, чтобы он тянулся по ширине содержимого, просто block по умолчанию принимает ширину 100% родителя и не годится.

Для любопытных: на ширину содержимого тянутся такие блоки: inline-block, float, pos: abs, table-cell. Там исопльзуется алгоритм shrink-to-fit: https://github.com/codedokode/pasta/blob/master/html/shrink-to-fit.md

Еще немного информации: https://github.com/codedokode/pasta/blob/master/html/positioning.md

2) сделать враппер width 100%, ovf auto;. В него вложить блок div с width=суммарная ширина картинок,вычисленная JS или на сервере, и с clearfix. В него вложить блоки картинок, каждая с float: left. Плюс: нет пробелов между блоками.

Объяснение: флоаты встраиваются горизонтально по ширине родителя, мы задаем такую ширину, чтобы они все влезли в одну строчку.

3) сделать враппер width 100%, ovf: auto, в него вложить таблицу из 1 строки и множества колонок. Таблицу сделать не тегом table, а дивами с display: table, table-row, table-cell. Плюс: выравнивание как угодно, в том числе вертикально, железобетонность конструкции. Минус: у таблиц куча ограничений в плане позиционирования. Например, нельзя делать pos abs относительно ячейки.

Я бы сделал все 3 варианта и протестировал, и вбросил ссылочки в тред.

>>25417

Используй preg_replace_callback. Раньше там был другой способ, но он небезопасен и открывает уязвимости.
559 1125758
>>25392

Гугли сравнение, например начать можно с мануала

http://php.net/manual/ru/mysqlinfo.api.choosing.php
http://php.net/manual/ru/mysqli.overview.php

> второй старый


не старый.

>>25360

Так нельзя. Есть принцип Лисков (это не название инопланетной расы, а фамилия), который говорит, что объект-наследник можно использовать вместо объекта-предка. То есть если где-то есть код

$a->lol($digit)

То он должен корректно работать с обоими классами.

Ты что-то делаешь не так. Если даже методы назвыаются одинаково, но у них разные аргументы - это разные методы, и надо переименовать метод в B (например в lolWithFlag). И в функции писать в тайп-хинте что ей нужен именно B.

>>25362

Это не очень красиво конечно получается. Ты скорее всего что-то плохо спроектировал.

>>25343

не уверен. Ссылка на тесты?

>>25265

> и работает он образно в духе isValid = validator->validate(['username' => 'required'])


Плохо, что тут не возвращается сам список ошибок. Какой смысл возвращать его как-то обходными путями?

> Другой подход это делать очень много громоздких классов валидаторов, где каждый класс отвечает за определенное правило


Сделай их негромоздкими.

Вообще, для простого приложения можно сделать все в одном классе. Но полезнее было бы попробовать спроектировать ООП-модель для описания и проверки правил. Пусть ты накосячишь, но хоть чему-то научишься и на какие-то грабли наступишь.

Ну например, сделать так:

- классы элементарных валидаторов
- класс для хранения набора правил и прогона валидаторов по данным
- класс-билдер для задания набора правил
- класс для информации об ошибках

> и насколько одно работает быстрее другого.


думаю, что это непринципиально так как ты не будешь проверять тысячи форм в секунду.

>>25021

Сначала надо изучить чистый PHP и ООП.
559 1125758
>>25392

Гугли сравнение, например начать можно с мануала

http://php.net/manual/ru/mysqlinfo.api.choosing.php
http://php.net/manual/ru/mysqli.overview.php

> второй старый


не старый.

>>25360

Так нельзя. Есть принцип Лисков (это не название инопланетной расы, а фамилия), который говорит, что объект-наследник можно использовать вместо объекта-предка. То есть если где-то есть код

$a->lol($digit)

То он должен корректно работать с обоими классами.

Ты что-то делаешь не так. Если даже методы назвыаются одинаково, но у них разные аргументы - это разные методы, и надо переименовать метод в B (например в lolWithFlag). И в функции писать в тайп-хинте что ей нужен именно B.

>>25362

Это не очень красиво конечно получается. Ты скорее всего что-то плохо спроектировал.

>>25343

не уверен. Ссылка на тесты?

>>25265

> и работает он образно в духе isValid = validator->validate(['username' => 'required'])


Плохо, что тут не возвращается сам список ошибок. Какой смысл возвращать его как-то обходными путями?

> Другой подход это делать очень много громоздких классов валидаторов, где каждый класс отвечает за определенное правило


Сделай их негромоздкими.

Вообще, для простого приложения можно сделать все в одном классе. Но полезнее было бы попробовать спроектировать ООП-модель для описания и проверки правил. Пусть ты накосячишь, но хоть чему-то научишься и на какие-то грабли наступишь.

Ну например, сделать так:

- классы элементарных валидаторов
- класс для хранения набора правил и прогона валидаторов по данным
- класс-билдер для задания набора правил
- класс для информации об ошибках

> и насколько одно работает быстрее другого.


думаю, что это непринципиально так как ты не будешь проверять тысячи форм в секунду.

>>25021

Сначала надо изучить чистый PHP и ООП.
560 1125804
>>25757
Ухх, сколько инфы.

Базовое (надо будет поиграться с подписями):

1) https://jsfiddle.net/zdrw38mk/
2) https://jsfiddle.net/zdrw38mk/1/

C таблицами ты меня озадачил, завтра почитаю и попробую. Спасибо.
561 1125807
Поясните мне за исключения.
Вижу примеры кода, когда наследуют кучу исключений от базового \Exception, а потом ловят их в set_exception_handler(function { }). Если видов исключений много и обрабатывать их надо по разному, то скоро вырастет простыня кода. Как от этого избавится?
Видел, что бросают исключения при валидации пользовательского ввода. Это вообще хорошая практика?
562 1125816
Гайд в шапке еще актуален?
Просто делаю задачку, а там доллар по 32
563 1125817
>>25816
Актуален.
564 1125829
>>25804

> ТАК УЖ ЛИ НУЖЕН CLEARFIX?


> У МЕНЯ БЕЗ НЕГО РАБОТАЕТ...


Вообще да, там же overflow. Это на случай, когда его не будет.

>>25807

Есть подробный урок по теме: https://github.com/codedokode/pasta/blob/master/php/exceptions.md

Для форм плохо подходят. Как ты сделаешь передачу информации о нескольких ошибках в разных полях?

Исключения все же для исключительных, неожиданных ситуаций, а ввод неправильных данных - ожидаемая ситуация, предусмотренная ТЗ.
565 1125831
>>25758

>Ты скорее всего что-то плохо спроектировал.


В методе B::lol(int $digit, bool $flag = false) аргумент $flag внутри метода влияет на $digit. Если быть точным, $digit - количество попыток сделать http-реквест, а $flag - флаг, говорящий, надо ли делать другие попытки, либо хватит одной. Проще говоря, лежит ли сайт.
A::lol(int $digit) принимает только количество попыток, это обобщенный отправитель http-реквестов. Класс B - это отправитель реквестов, заточенный под конкретный сайт. Внутри lol обоих классов всегда вызывается A::doRequest(int $digit). Разумеется, там еще url в параметрах, и даже streamContext, я упрощаю.
Я могу сделать сделать много реквестов за жизнь скрипта от одного инстанса. Каждый раз состояние флага неизвестно. Но, теоретически, я могу спрятать всю обработку флага внутрь класса B. Чтобы он, кроме реквестов, еще и сам читал этот флаг из файла перед отправкой, и сам писал в файл этот флаг. И тогда у обоих классов будет сигнатура lol(int $digit). Это будет ок?

Алсо, еще вопрос.
Сейчас у меня и А::lol, и B::lol возвращают объект WebResponse. Есть метод WebResponse::getStatusCode(). Для B мне нужно его пропатчить. Я делаю BWebResponse extends WebResponse и реализую метод BWebResponse::getStatusCode().
Теперь метод B::lol должен возвращать BWebResponse. Нормально ли будет написать в B::lol такое:
$webResponse = $this->doRequest($url, $streamContext, $qtyAttempts); // A::doRequest()
return new BWebResponse($webResponse->getHeaders(), $webResponse->getContent());
Проще говоря, я из объекта-предка делаю объекта-наследника не снимая свитер не реализуя B::doRequest(), а то геморройно.
566 1125832
>>25831
А еще я могу сделать класс А и B фабрикой одноразовых объектов для реквестов, а вот сигнатура метода будет везде одинаковой: AProduct::lol($url) и BProduct::lol($url).
Фабрика - синглтон, где живет базовый конфиг реквеста.
Но это какое-то дикое усложнение, как мне кажется.
567 1125944
Утро в хату, пыханы. Нужен джуниор для удаленного сотрудничества с опытом Вордпресс или способностью его быстро освоить. В перспективе - рост до фреймворков и прочих серьезных вещей. Почта: bizachinve'~qstANUSgma~I{ilPUNCTUMco<%Km
568 1125951
>>25757

>Для микросервисов пойдут контейнеры.


благодарю
569 1125952
>>25944

>Утро в хату


к слову о привлекательных работодателях лол
570 1125956
>>25571
>>25560
>>25755
Спасибо! Ухожу фиксить.
571 1125989
Анон, скажи, а как можно сделать, чтобы если поиск по БД закончился ничем, то выводилось сообщение ну или ничего не выводилось?
572 1125992
>>25944
Забыл пароль от фейкопочты. Пишите на: pgL;hpheadhuntANUSgmail"D~PUNCTUMcoG'_m

>>25952
This.
573 1125999
Посоны, возможно ли подсоединиться к базе данных при помощи PHP 7 (или даже 5), если база данных находится на SQL Server 2000? Дали такое задание на работе (эникейщиком сижу), второй день ебусь. Якобы ODBC драйвера 13ые не поддерживают SQL 2000, 11ые тоже, а старее я хуй знает как найти, еще и сервак сайта на Убунте виртуальной, а я вообще в линуксе ноль и как их ставить и где искать.
15165134079730.jpg151 Кб, 750x750
574 1126015
что почитать о проэктировании авторизации на сайте нубу?
нубяра кун
575 1126022
>>25999

>эникейщиком сижу


>в линуксе ноль



охуенный эникейщик

https://stackoverflow.com/questions/30721219/php-5-6-and-sql-server-2000
вот люди пишут:

>In Ubuntu, I used mssql functions and unixodbc drivers



а вообще, это наверное самое упоротое задание, о котором тут в треде писали. возможно, стоит даунгрейднуться до пхп4 или 5.2
576 1126026
>>26015
Что ты хочешь прочитать?
Вот те список задач.
Принять логин, пароль. Сравнить их с данными в бд. Если все правильно то логинишь.
577 1126034
Сап!

Делаю простенькую задачу по форме с поиском по БД.
Запилил такой запрос:

SELECT id FROM dbCountries WHERE fruit COLLATE UTF8_GENERAL_CI LIKE '%$food%' OR vegetable COLLATE UTF8_GENERAL_CI LIKE '%$food%'

Только-только вкатываюсь в пхп, посему к PDO даже не лезу.

Проблема в том, что сраный скрипт скармливает в БД массив, собранный из слов в строке, разделенных знаками или пробелами.

Как итог, если будет введена дебильная фраза "А Наташа любит банан", чертова буква "а" будет послана по бд и вылезет целая куча "подходящих" значений, типа "апельсин", "банан" и прочая хуита.

Казалось бы, простой ответ: замени свой паршивый лайк на что-нибудь по-проще и что-нибудь более строгое!

Но задача усложнена тем, что в одной ячейке, через запятую может находится несколько названий, разделенных запятой (можно заменить на пробелы, но кому это поможет?).

Короч, посаны, че делать?
578 1126043
>>26022
Нагуглил альтернативные драйвера и гайд, буду пробовать

https://www.easysoft.com/developer/languages/php/sql_server_unix_tutorial.html
579 1126047
>>26026
в теории я это понимаю.надо использовать fetch()?
580 1126053
>>26043
Сука, они платные.
581 1126074
А правда, что в SQL запросе можно спокойно использовать REGEXP и RLIKE , как синонимы и не будет никаких проблем ни в каких ситуациях?
582 1126083
>>26053
так пусть работодатель купит
583 1126159
>>19406
смотри, я сделал через foreach, но так и не понял, как сделать через него так, чтобы он две строки делал, копипаста же не пройдет? или оно так и задумано, чтоб с копипастой?
https://ideone.com/UDmeve
584 1126165
>>26015

У меня нет урока про авторизацию, но есть про правильное хранение паролей в базе, точнее хешей: https://github.com/codedokode/pasta/blob/master/security/password-hashing.md
585 1126200
Почему пыху считают за ущербный язык? Все пиздато же!
586 1126211
>>25816
Тоже проиграл.
587 1126212
>>26200
из-за легаси. раньше писали достаточно ущербно. для прикола найди исходники какого-нибудь проекта, который написан до 5.3.

ну и некоторые и сейчас пишут на семерке как будто это пхп4.
588 1126221
https://ru.wikipedia.org/wiki/Tiny_Core_Linux
Можно ли туда поставить сервер?
589 1126350
>>25989
if(empty(select znachenie from baza)) {
echo 'nichego ne naideno';
}
590 1126364
>>26159
Тебе нужно было поместить слова в один массив и так же добавить в него перенос строки в нужных местах, и затем пройтись по всему массиву с помощью foreach
Я же писал тебе подсказку из задачи дважды

>Подсказка: можно упростить программу, сделав что-то вроде шаблона для генерации стиха на основе массива. В каждый элемент массива мы кладем массив вариантов слова или строки, из которого надо сделать выбор: [$word1, $word2, $word3, ["\n"], ...]. Мы добавляем массив с "\n", чтобы в нужном месте вывелся перевод строки. Остается только пройти по массиву циклом и сгенерировать стих..



>$array = array(


>$word1 = array


Внутри массива не делают присваивание
Либо просто помещают значение или переменную, либо пользуются конструкцией key => value

Для вложений используют табуляцию 4 пробела

>foreach($array as $word)


>{


В циклах и условиях, перед скобкой, не ставиться перенос строки

>$text = array_rand($word);


>$text2 = $word[$text];


>echo "$text2";


Можно было написать проще $text = $word[array_rand($word)]

Или ещё проще echo $word[array_rand($word)]
591 1126542
>>25999
Читал файл install.txt прилагающийся к php и вспомнил про тебя

> MDAC requirements: If you use Microsoft Windows 98/NT4 download the latest version of the Microsoft Data Access Components (MDAC) for your platform. MDAC is available at http://msdn.microsoft.com/data/. This requirement exists because ODBC is built into the distributed Windows binaries.

592 1126576
Антоны, возможно ли овладеть за месяц PHP опыт программирования на других языках есть?
593 1126590
Вопрос: есть родительская таблица Товар, у него есть связь многие-ко-многим к таблице Жесткость (т.к. две стороны, могут быть обе одинаковые, а могут – разные) с промежуточной таблицей ТоварЖесткость. Надо выбрать Товары с определенной жесткостью, при этом не исключая наличия других.
SELECT p., h. FROM product p
LEFT JOIN product_hardness ph
ON ph.product_id = p.id
LEFT JOIN hardness h
ON h.id = ph.hardness_id
WHERE h.id = 3
Как быть? Мне надо отбросить только те, где нет Жесткости с id = 3, а не все те, где id !=3
594 1126594
>>26576
За месяц ты чем угодно овладеешь, вопрос только в уровне.
image.png258 Кб, 1920x1080
595 1126615
Почему не работает?
596 1126651
>>26200
щас все бэкенд языки (пхп, питон, руби, нода, джава) на 80 процентов одинаковы. вопрос в том, что недостаточно выучить язык, надо еще знать экосистему (фреймворки, библиотеки, бп).
597 1126712
>>26651

>пхп, питон, руби, нода, джава


Они же сильно отличаются.
598 1126714
>>26615
УМВР
Проверь, работает ли с латиницей.
599 1126728
Какой фреимворк учить, что бы взяли на работу джуном в дс?
sage 600 1126738
Анон, объясни, почему если я пишу так https://ideone.com/smm47E , то у меня выводится null, а если вот так https://ideone.com/ , то все просто разваливается.
sage 601 1126743
>>26738
Все исправил.
Глупые ошибки из-за незнания того, как массивы заполняются.
602 1126744
>>26728
Работы больше всего на yii2 и laravel или symfony. Один из этих и точно без работы не останешься.
603 1126751
Поцаны, а что лучше использовать для разбиение строки на массив:
explode или preg_split ?
604 1126752
Пыханы, как вы тестируете на локальной машине передачу данных от одного сервиса другому? Ну то есть есть у меня сайт, с которого я curl'ом или ajax'ом отправляю на сервер какие-то данные и получаю ответ. Вот как вы это дело тестируете?
605 1126753
>>26712
я не сказал бы, что для бэкенда пхп СИЛЬНО отличается от джавы. имея опыт в одном из них ты быстро разберешься во втором
606 1126754
>>26751
Если тебе нужно регулярное выражение, для разбиения строки, то естественно preg_split. Для простых случаев - типа разбиения строки по пробелу, запятой или другому разделителю - explode.
607 1126755
>>26754
Премного благодарен! Тогда, хотел бы уточнить ещё один вопрос: >>26074
608 1126756
>>26752

>Вот как вы это дело тестируете?


тестируем - в смысле пишем тесты? ну твоя задача - не тестировать ответ от чужого приложения, а что данные от тебя ушли в нужном формате и был правильно обработан ответ.

у пхп юнита есть т.н. классы-моки, которые этим занимаются: https://phpunit.de/manual/current/en/phpunit-book.html#test-doubles
609 1126760
>>26755
http://www.sqlines.com/mysql/regexp_rlike

>REGEXP and RLIKE are synonyms


Не знаю, что ещё тут можно ответить.
610 1126761
>>26728
если лоялен к относительному говнокоду, то yii2. на нем в снг больше всего легаси проектов.
611 1126762
>>26753
Но тот же руби, нода, питон отличаются довольно разительно.
А насчет джавы согласен, вкатываться несложно.
Мимо пришел с шарпа, ибо ASP подзаебал
612 1126768
>>26760
Ну просто иногда называют что-то "синонимами", с позиции "99.999% это идентично", А ПОТОМ КИШКИ КРОВЬ ГОВНО УЗНАЕШЬ ЧТО ЖИЗНЬ АДСКАЯ ПИЗДА.

Просто хотел убедиться. Спасибо ещё раз!
613 1126771
АНОНЫ, Я КАЖДУЮ ЗАДАЧУ ДЕЛАЮ ПРИ ПОМОЩИ РЕГУЛЯРОК, ЧТО ДЕЛАТЬ Я ВЕЗДЕ ЛИШЬ ВИЖУ РЕГУЛЯРКИ
614 1126786
Всегда писал на пхп для себя, понадобилось вкатиться на работку. Какой фраемворк не сильно тяжело выучить и который можно запускать с флешки через локальный сервер? С опенсервера например, привык к нему
149770-450x450.png792 Кб, 450x450
615 1126835
>>19867

> кто крутит продакшн на IIS


В виртуалке дебиана (да и такое бывает)
616 1126858
>>26786

>который можно запускать с флешки через локальный сервер



любой фреймворк можно запустить с флешки лол. странный критерий выбора. фреймворк - это для сервера просто пхп-код.

симфони или ларавел учи. на йии пока много работы, но он, чую, относительно скоро загнется
617 1126868
Есть вообще люди, которые считают, что yii2 - пиздатый фреймворк? Которые прям любят его?
618 1126872
если yii2 такое гавно то почему он так популярен?
619 1126908
>>26872
если битрикс такое гавно то почему он так популярен?

yii не говно, конечно. но популярен он на территории СНГ. мое предположение: из-за того, что его мануал переведен на русский, а для большинства вкатывальщиков английские мануалы - непреодолимое препятствие.
620 1127027
>>26771
Двачую, придрочишься к этому говну, оторваться невозможно
621 1127180
Люди поясните за "первые столбцы": Обе таблицы должны быть InnoDB-типа; обязательно также наличие индекса, в котором внешний ключ и ссылочный ключ должны находиться в первых столбцах. Для таблиц InnoDB индексы по внешним ключам или ссылочным ключам не создаются автоматически: их создание требуется задавать явно.
http://www.mysql.ru/docs/man/SEC451.html

Перед объявлением внешних ключей, нужно создать одинаковые по типу столбцы, один из которых должен быть первичным ключом. А что значит "внешний ключ и ссылочный ключ должны находиться в первых столбцах"?
622 1127368
$letters = array(

/
for ($i = 1; $i <= 4; $i++) {
$random = mt_rand(1, count($letters));
$randomText = $letters[$random];
Я не могу понять это.
Объясните пожалуйсто, всмысле как это работает?
623 1127477
Есть старое ПХП-приложение. Возможно ли, что из-за использования mysql_connect() вместо mysqli_connect() замедляется работа и сайт имеет боттлнек именно в этом месте?
624 1127496
Привет, аноны. Подскажите где почитать/посмотреть про загрузку файлов, чтобы прямо как здесь можно было несколько штук загрузить отдельно, а они бы списке красиво отобразились. Я может искал криво, но как такое сделать не нашел нигде.
625 1127528
>>27477
боттлнек - это работа самой бд. из-за выбранного расширения вряд ли будет именно тормозить (если железо не тех же годов, что и твое приложение), но mysql_ использовать крайне не рекомендуется: https://stackoverflow.com/questions/12859942/why-shouldnt-i-use-mysql-functions-in-php

>>27496
вот возьми любую из существующих библиотек и смотри исходники: https://www.slant.co/topics/4353/~javascript-libraries-for-file-uploading
626 1127531
>>27368
есть массив $letters. в нем что-то лежит.
дальше у тебя видимо куска кода нет, потом цикл for, видимо 4 раза делается echo $randomText.

в переменной $random задается число, которое представляет собой индекс массива (предполагаем, что массив не ассоциативный), далее переменной $randomText задаем значение в виде какого-то элемента из массива $letters.

алсо, никогда так не делай. в пхп для возврата индекса случайного элемента массива есть функция array_rand() - https://secure.php.net/manual/ru/function.array-rand.php всегда используй ее.
627 1127538
>>27368
ты видимо из другого языка пришел. в пхп в качестве индекса массива можно указывать переменную, метод, функцию, объект (при наличии у него метода __toString()), выражение, константу и т.д.

вообще в пхп (с версии 7, т.к. до нее было слишком много исключений) есть т.н. uniform syntax, т.е. возможно без страха задавать конструкции типа
getFilters()[1]('Foo');

что означает "выполнить анонимную функцию с аргументом 'Foo', которая содержится в массиве с индексом 1, который возвращается при вызове getFilters()"
628 1127541
>>27528
Спасибо, выходит действительно искал плохо.
629 1127705
Пыханы, подскажите, как правильно поступить.
Когда юзер заходит на сайт мне нужно ему отобразить некую информацию, которая зависит от параметров в адресной строке. Для этого мне нужно обратиться на другой сервер и получить её оттуда.
Как это лучше сделать: на бекенде сайта c помощью php, до того, как юзеру отрисована страница (тут, понятно, будет блок до того, как информация получена) или делать это после загрузки страниц посредством ajax? Во втором случае придётся делать больше работы (корректировать скрипт для каждого последующего сайта, куда буду подключать всё это дело, да и будет заметно дёргание и смена дефолтной информации на обновлённую), но зато, типа не будет блокирующего соединения.
Информация не прям критическая, но всё-таки очень хочется чтобы она всегда была донесена до юзера.
В первом случае с php можно установить таймаут для соединения, чтобы не терять - в случае с очень долгим ответом от сервера - юзера совсем. И отдавать ему дефолтное значение, если превышен таймаут.
630 1127802
>>27705
Для начала убедись, что ты можешь яваскриптом дергать чужие сайты. Для этого они должны отдавать тебе заготовок Access-Control-Allow-Origin с твоим доменным именем, либо звездочкой.

Если у тебя задача поддерживать только современные браузеры на новых мощных компах, делай как угодно.
Если у тебя задача, чтобы и пользователи ИЕ, и Оперы Мини, и Тор Браузера не получили фигу, то делай всё на бэкэнде. Заодно сможешь настроить кэширование по вкусу. А на клиенте для кэширования придется работать либо с LocalStorage, либо с Cache API через сервисворкеры.
631 1127803
>>27802

>А на клиенте для кэширования придется работать


А, ну и конечно, старые добрые заголовки Cache-Control, Last-Modified и ETag. Но это уже как настроено на другом сервере.
632 1127932
>>27802

>Для начала убедись


Это не проблема - удалённый сервер мой.
633 1128125
Как думаете, я сильно тупой, если я вроде как более менее прочитал прорешал всего кантора по жс, а сейчас не могу сделать задачу ОПа про создание стиха? Выдумываю какие то циклы, циклы в циклах, хоспади
634 1128136
>>28125
покажи код и саму задачу, решим вместе
635 1128193
>>25829
Гугол читеры! Это не Respоnsive как он должен быть, они генерируют свою версию под каждый экран и устройство на основе кучи факторов (например точно 2 разных экземпляра при медленном и быстром интернете, проверял, специально подсовывают "лайт" версию), короче лажа, зря ебался два дня. Такие дела. Алсо у меня нет возможности проверять на мобильных браузерах, но есть подозрение, что они оптимизируют под хром (на котором я тестировал) добавляя свои -webkit свойства, которым я поддержки не нашел на caniuse. Например они убирают тут >>25441 полосу прокрутки насильно (::-webkit-scrollbar {display: none;}).

Тру Respоnsive например у https://www.microsoft.com/ru-ru/
но здесь нет такого "вау"-эффекта. Все предсказуемо собирается-разбирается как в бутстрапе (от которого тошнит уже). Я расстроен.
636 1128308
>>28136
Кароч я сделал но как то хуево. Я хотел что бы все само подбиралось элегантно, бегало циклами по массивам и само подставлялось, а получилась какая то наивная фигня.
https://ideone.com/OedzJO
637 1128388
Почему не получается вызвать filename.php через командную строку?
Никаких ошибок не выдает. Просто ничего не происходит .
638 1128404
>>28388
Командная строка чего? Какой командой?
filename.php просто текстовый файл. Ты вызываешь интерпретатор с параметром имя файла, например для линупса:
php filename.php
639 1128494
test
640 1128533
как запилить самую простую проверку пользователя на существование в базе?
641 1128576
>>28308
во-первых, я предлагаю ОПу в шапку вынести: "для работы с массивами НЕ ИСПОЛЬЗУЙТЕ for и mt_rand. используйте foreach и array_rand"

во-вторых, помимо дублирования (это очевидный признак неправильного решения) желательно решение сделать более человеко-читаемым. все условия желательно подавать сначала, а у тебя порядок слов жестко определен в решении и надо смотреть весь код, чтобы его понять.

я бы сделал так https://ideone.com/Ec6w04
что позволяет нам все исполнение вынести в функцию, куда мы на вход подаем список слов и их порядок, а все решение скрыть от наших глаз.
642 1128586
>>28576
Сложна. Хз как те кто только открыл этот тред вообще понимают foreach. Я после Кантора все равно не уверен что до конца понимаю. Или я на самом деле просто очень тупой.
643 1128590
>>28586
Точнее ну как, понимаю, но вот в твоем решении как то не очень. Пойду распечатывать твой код по строке.
644 1128607
>>28586
ну мануал почитай и поймешь
645 1128639
Есть PHP код, выполняющий процедуру в базе данных (запрос в духе EXEC _название процедуры_ _параметры_). Заголовки результирующей таблицы идут названиями полей таблицы, (к примеру, ID, Name, Client и прочее). Можно ли сделать так, чтобы названия столбцов были на русском, не меняя код в процедуре, а только в PHP?
646 1128673
Анон, подскажи, как правильно реализовать:

Я собираю ссылки через циклы:

https://ideone.com/

Мне нужно сделать так, что если только одна ссылка сформирвоалась, то чтобы сразу был переход.

Если же ссылок несколько, то они должны просто вывестись на экран, чтобы юзер мог выбрать.

Как это лучше всего реализовать без дублирования циклов?
647 1128678
>>28673
ты ссылку забыл
648 1128680
>>28678
Разумное замечание: https://ideone.com/K5VHQK
649 1128685
>>28680
Ну раз у тебя уде есть массив, просто через if посмотри сколько в нём элементов, и если один - перенаправляй, если больше - цикл делай.
650 1128701
Может внатуре, тот случай, когда не дано?
https://ideone.com/bGpVBE

Пол дня ебусь. Палиндром.
651 1128704
>>28701
Жди ответа опа, а пока ждёшь -0 приступай к следующему (хотя тут ты должен поставить что-то типа break(); при выполнении какого--либо условия)
652 1128708
>>28586

>foreach


>прочитал прорешал всего кантора по жс



В жс практически такой же форич.

https://learn.javascript.ru/array-iteration#foreach
653 1128710
>>28708
Это не ты тупой, это foreach странный. Я до сих пор не понимаю до конца вот этого '=>' вот.
654 1128717
>>28710
Я вообще решил пхп учить потому что в жс обосрался. Ну как обосрался, Кантора вроде с горем поплам прорешал, а потом решил закрепить хекслетом - а там уже пиздец, ес6 синтаксис, функции в функции в функции вот это вот все. Вот сюда пришел опять обсираюсь. Пиздец. Надо наверное все свободное время пытаться ебенить эти задачи, палиндромы и всякие вот эти задачи, что у кантора что у Опа. По два часа в день нихуя не прокатит.
655 1128719
>>28717
Не отчаивайся бро. Тут главное не бросить это дело, и по несколько часов таки уделять, даже если пока ничего не понимаешь. Поверь, спустя какое-то время прийдёт знание.
656 1128723
>>28710
Это просто стрелочка.
584d5002bdef8158ee008ada.png114 Кб, 500x366
657 1128725
>>28723
Я не очень умный.
658 1128734
Нужно допилить бэк тырнет-магазина.
Работа за еду.
@username561
659 1128738
>>28734
Ну ты это, больше подробностей кидай если хочешь чтобы к тебе кто-то действительно переходил.
660 1128743
>>28738
Сайт стоит на самописной цмс. Нужно допилить функционал корзины (фронт уже запилен) и прикрутить оплату от яндекса.
+ пара мелких фиксов
Бюджет – 3к
661 1128749
>>28710
у него только одна задача - присваивать элементу массива значение. все.
662 1128750
>>28725
Так указывается соответствие в массивах.
Тут это означает, что вот в этом массиве такой-то элемент.

Это ещё в объектах используется.
663 1128751
Очередное спасибо товарищу >>25757

Для показа элементов фиксированной высоты идеально подходит inline-block (лента картинок)

Поддерживается в мобильных, десктопах и ие с 5.5

Для сколь угодно сложных элементов — table. Растягивается, позволяет держать сетку.
Минусы:
1) при вложении картинок тегом <img> при пересчете пропорций появляются мерзкие полосы, у inline-block такого нет.
2) таблица рассчитана на скроллинг вертикально, в ней обычно добавляются строки, а тут для заполнения надо добавлять столбцы. Приходится разбирать содержимое на "слои": одна строка для каждого кусочка, и привставке нового элемента добавлять ячейку в каждую строку. Геморно, непонятно, как использовать в темплейтах. Или использовать одну строку, но тогда теряется выгода таблицы.

Поддерживается в мобильных, десктопах и ие с 8

Решил буду использовать оба.

Вариант с flоat — надо знать ширину ленты. Сложнее inline-block, а выгоды никакой, не подходит.

Кстати, самое современное — flex, но это уже совсем не кроссбраузерное, не подходит.

Ты няша :3
664 1128753
>>28750
В объедках другая стрелочка ( -> )
665 1128755
>>28753
Ладно. Притворимся, что я не дебил, который дает "советы" другим.
666 1128759
>>28753
>>28755
Не не не, я именно эту стрелку и имел ввиду. Спасибо тебе анон.
667 1128762
>>28751

>2) таблица рассчитана на скроллинг вертикально, в ней обычно добавляются строки, а тут для заполнения надо добавлять столбцы. Приходится разбирать содержимое на "слои": одна строка для каждого кусочка, и привставке нового элемента добавлять ячейку в каждую строку.


Вот тут непонятно. Ты ведь заранее знаешь сколько фоток будешь в таблицу пихать. Какие проблемы?
668 1128764
>>28762
Ну смотри: при открытии страницы я ставлю 10 фоток. Крутишь влево, доходит до конца, и тут в зависимости от контекста оно может подгрузить еще фоток (бесконечная лента) или показать кнопку "еще" / "подробно" и т.п.

А если тебе не интересен этот блок ты просто скроллишь дальше вниз.
669 1128769
>>28764
Хм, интересная постановка задачи. Если бесконечная лента, то да.
670 1128779
>>28743
ну удачи в поиске, лол
671 1129042
Вы перекатились чтоли? Почему никто не пишет?
672 1129109
>>29042
не было переката вроде
673 1129110
Можно ли парсить с помощью PHP XML документ, названия узлов которого на русском языке? Если да, то как?

На инглише то все понятно:
$test = simplexml_load_file("test.xml");
echo $test->lang[0]->creator;
674 1129142
Правда, что в пхп 5.4 я могу увеличить дату на какое-то количество дней только через объекты?
675 1129144
>>29142
Вот такой толстоты ещё в треде небыло.
676 1129146
>>29144
http://php.net/manual/ru/datetime.modify.php

(PHP 5 >= 5.2.0, PHP 7)

Все понял. В шары поебался знатно.

Но почему у меня не срабатывает простой код:

https://ideone.com/ulv535
677 1129180
>>29146
билядь

>PHP Warning: date_modify() expects parameter 1 to be DateTime, string given in /home/mlpI86/prog.php on line 10



у тебя ж написано все. date возвращает строку, а не объект DateTime
678 1129190
>>29180

>у тебя ж написано все. date возвращает строку



Я не понимаю. Почему по подобию этого:

$date = date_create('2006-12-12');
date_modify($date, '+1 day');
echo date_format($date, 'Y-m-d');

У меня не работает:

$datefrom = date('d/m/Y', strtotime($_GET[from]));
date_modify($datefrom, '+20 day');
echo $datefrom, '<br>';

В ебучем мануале все очень просто!
679 1129208
>>29190
потому что полезно читать мануал.

>$date = date_create('2006-12-12');


Возвращает созданный объект класса DateTime

>$datefrom = date('d/m/Y', strtotime($_GET[from]));


вернет СТРОКУ блять.

date_modify не принимает строку. она принимает объект класса DateTime. все это тебе написал ideone

>PHP Warning: date_modify() expects parameter 1 to be DateTime, string given in /home/mlpI86/prog.php on line 10

680 1129286
Сап, программач, поясни за класс Request. Я понимаю, что это обертка для запросов, для удобной работы с post, get, но можно еще немного разъяснить для меня.
681 1129384
объясните за тернарный оператор. в мануале есть пример:

>// on first glance, the following appears to output 'true'


>echo (true?'true':false?'t':'f');



>// however, the actual output of the above is 't'


>// this is because ternary expressions are evaluated from left to right



я этого не понимаю. если они выполняются СЛЕВА НАПРАВО, то первое певое 'true' выполнится и все, нет? я нихуя не понимаю почему еще дальше выполняется
682 1129389
>>29384
все, понел.
true?'true':false?'t':'f'
сначала выполняем
true?'true':false
получаем 'true'
потом выполняем
'true'?'t':'f'

ну если так кто-то реально это использует, то ему надо по рукам ебнуть
683 1129513
Как выполнить часть кода PHP на странице только после того, как пользователь введет нужные данные в поля? Примечание: поля для ввода данных генерируются до этого, то есть они могут быть разными и разное количество.

Если подробней то, есть БД с названиями процедур и отдельной колонкой с перечислением параметров. На стартовой странице я их вывожу и по клику перехожу на новую страницу, где я, забрав название процедуры, забираю уже из БД ее параметры, а зависимости от параметров отрисовываю поля для их ввода. Теперь же нужно, чтобы процедура выполнилась после введения данных в поля для ввода (а они могут быть разными, в зависимости от процедуры). Плюс необходимо допустить возможность менять данные в полях для ввода и запускать процедуру сколько хочешь.
684 1129514
>>29513
процедуры выполняю в виде собираемого как string запроса к БД через команду EXEC

$exec="EXEC " . $procedureName . " "; //; $exec = строчка запроса, которую мы собираем

$result=mssql_query($exec . $dateS . ','. $dateE) or die(mssql_get_last_message()); //выполнение процедуры
685 1129529
Отправляю c клиента пост запрос, на сервере принимаю. Вывожу его в лог print_r и почему то эти данные попадают в ключ массива. Что за фигня? То есть выглядит это так

Array ( ['мои данные'] => )
686 1129578
кто пользуется symfony security component, есть вопросик.

как лучше закрывать части приложения? через access_control в security.yaml или с помощью аннотации @Security?

в мануале советуют второй способ https://symfony.com/doc/current/best_practices/security.html

но также пишут

>For protecting broad URL patterns, use access_control



это имеется в виду урлы, которые соответствуют множеству контроллеров?

вы конкретно как закрываете например админку?
687 1129584
>>29529
если ты имеешь в виду, что выводишь в файл лога, то надо использовать var_export($data, true)

print_r и var_dump используются для отладки, а не для возврата значений.

>>29513
в смысле как? ajax-запросом.
алсо, привет sql-инъекции.
688 1129630
>>29584

>если ты имеешь в виду, что выводишь в файл лога, то надо использовать var_export($data, true)


Не-не-не. Я долбоёб и отправлял в теле пост запроса инфу тупо сериализуя массив без http_build_query и на выходе получалась такая хуйня.
14138698791003373645.png1,2 Мб, 1200x1800
689 1129655
Сап двач. Есть один заказчик, ему нужно показать пример проекта на Joomla. У меня нет опыта на Joomla (только Laravel, Wordpress). Так вот, может какой нибудь добра-анон поделится годным проектом на Joomla? Буду крайне признателен.
690 1129742
Сделал задачу по функциям, надо подсчитать, сколько выйдет итоговая сумма по трем разным предложениям кредита, вроде все изи.
https://repl.it/@Uzas/WorthlessUnusualArthropods
691 1129817
>>29655
поделится - это как? даст доступы к серверу?
692 1129893
>>29817
ну не тупи
я имел в виду может у кого открытом репе что то такое лежит
555-692 693 1129945
>>29742

Код конечно надо форматировать, добавлять отступы, а то трудно понять, где начинается и заканчивается функция.

Имена переменных начинаются с маленькой буквы.

"} else {" пишется в одну строку

> $creditBalance;/ Долг анона перед банком /


Так писать вообще неправильно. Что делает эта строчка? Если ты хотел добавить комментарий к аргументу функции, то лучше было перед ней написать так

/ $creditBalance - Долг анона перед банком /

Результат получился неточный. Во втором кредите плата будет 61270 с копейками.

Скорее всего, это из-за того, что ты проверяешь, что долг меньше 5000 до того, как начислены проценты и комиссия. Получается такая вещь: прибавляется комиссия, проценты, остается 9000 долга, анон выплачивает 5000, остается 4000 и в следующем месяце ты без добавления комиссии и процентов погашаешь остаток.

>>29578

access_control это для закрытия целой области на сайте. Например, всех URL вида /admin/... или весь поддомен admin.example.com. Не надо беспокоиться о том, что кто-то при добавлении нового действия забудет поставить там проверку.

Далее можно использовать @security или ручную проверку для ограничения доступа к отдельным действиям.

>>29513

если (запрос отправлен методом POST) {
если (все поля заполнены правильно) {
выполнить действие;
сделать редирект;
выход;
}
}

иначе вывести форму;

Это описано у меня в уроке https://github.com/codedokode/pasta/blob/master/forms.md

> процедуры выполняю в виде собираемого как string запроса к БД через команду EXEC


Там не будет SQL инъекции? Урок https://github.com/codedokode/pasta/blob/master/security/sql-injection.md
555-692 693 1129945
>>29742

Код конечно надо форматировать, добавлять отступы, а то трудно понять, где начинается и заканчивается функция.

Имена переменных начинаются с маленькой буквы.

"} else {" пишется в одну строку

> $creditBalance;/ Долг анона перед банком /


Так писать вообще неправильно. Что делает эта строчка? Если ты хотел добавить комментарий к аргументу функции, то лучше было перед ней написать так

/ $creditBalance - Долг анона перед банком /

Результат получился неточный. Во втором кредите плата будет 61270 с копейками.

Скорее всего, это из-за того, что ты проверяешь, что долг меньше 5000 до того, как начислены проценты и комиссия. Получается такая вещь: прибавляется комиссия, проценты, остается 9000 долга, анон выплачивает 5000, остается 4000 и в следующем месяце ты без добавления комиссии и процентов погашаешь остаток.

>>29578

access_control это для закрытия целой области на сайте. Например, всех URL вида /admin/... или весь поддомен admin.example.com. Не надо беспокоиться о том, что кто-то при добавлении нового действия забудет поставить там проверку.

Далее можно использовать @security или ручную проверку для ограничения доступа к отдельным действиям.

>>29513

если (запрос отправлен методом POST) {
если (все поля заполнены правильно) {
выполнить действие;
сделать редирект;
выход;
}
}

иначе вывести форму;

Это описано у меня в уроке https://github.com/codedokode/pasta/blob/master/forms.md

> процедуры выполняю в виде собираемого как string запроса к БД через команду EXEC


Там не будет SQL инъекции? Урок https://github.com/codedokode/pasta/blob/master/security/sql-injection.md
694 1129946
>>29286

Ты вот не написал, о каком фреймворке или библиотеке идет речь. Это ведь не стандартный класс PHP, а часть какой-то библиотеки. И не написал конкретного вопроса.

Лучше всего наверно прочесть документацию.

Я предположу, что ты хотел задать вопрос "зачем нужен этот класс, если можно брать данные напрямую из $_GET/POST/SERVER".

Обычно объект класса Request представляет собой информацию о HTTP-запросе, пришедшем от пользователя. Представление запроса в виде объекта позволяет явно показать, что той или иной функции нужны данные из запроса, явно их передать. Ну например:

- getUserCity(Request $req) - определяет город пользователя по каким-то параметрам запроса (скорее всего, по IP адресу). Явно видно, что она использует данные из запроса.

Сравни с функцией, которая не использует объект Request:

- getUserCity() - непонятно, по каким данным она определяет город.

При этом мы можем легко создавать свои объекты Request, например, для тестирования, имитируя приход какого-то запроса. Можем сохранять объект Request куда-то и позже восстанавливать обратно, можем дампить его в лог итд.

Часто он также содержит полезные методы вроде getInt (преобразовать параметр к числу) или getRemoteIp().

Наконец, PHP парсит входные данные не любых типов. Например, если твой код в браузере присылает POST запрос с телом в формате application/json, то эти данные не попадут в $_POST, тебе надо самому их как-то парсить. Класс Request может взять это на себя (если ты это в нем реализуешь).

>>29110

Если так?

$test->{название}

Также, можно попробовать использовать PHP DOM:

$test->getElementsByTagname('название')

И еще поиск по XPath.

Убедись, что исходник в кодировке utf-8 и что при разборе XML ты правильно выставляешь все кодировки. Если в XML не указана кодировка, его надо привести к utf-8.

А вообще, я не знаю, получится ли.
694 1129946
>>29286

Ты вот не написал, о каком фреймворке или библиотеке идет речь. Это ведь не стандартный класс PHP, а часть какой-то библиотеки. И не написал конкретного вопроса.

Лучше всего наверно прочесть документацию.

Я предположу, что ты хотел задать вопрос "зачем нужен этот класс, если можно брать данные напрямую из $_GET/POST/SERVER".

Обычно объект класса Request представляет собой информацию о HTTP-запросе, пришедшем от пользователя. Представление запроса в виде объекта позволяет явно показать, что той или иной функции нужны данные из запроса, явно их передать. Ну например:

- getUserCity(Request $req) - определяет город пользователя по каким-то параметрам запроса (скорее всего, по IP адресу). Явно видно, что она использует данные из запроса.

Сравни с функцией, которая не использует объект Request:

- getUserCity() - непонятно, по каким данным она определяет город.

При этом мы можем легко создавать свои объекты Request, например, для тестирования, имитируя приход какого-то запроса. Можем сохранять объект Request куда-то и позже восстанавливать обратно, можем дампить его в лог итд.

Часто он также содержит полезные методы вроде getInt (преобразовать параметр к числу) или getRemoteIp().

Наконец, PHP парсит входные данные не любых типов. Например, если твой код в браузере присылает POST запрос с телом в формате application/json, то эти данные не попадут в $_POST, тебе надо самому их как-то парсить. Класс Request может взять это на себя (если ты это в нем реализуешь).

>>29110

Если так?

$test->{название}

Также, можно попробовать использовать PHP DOM:

$test->getElementsByTagname('название')

И еще поиск по XPath.

Убедись, что исходник в кодировке utf-8 и что при разборе XML ты правильно выставляешь все кодировки. Если в XML не указана кодировка, его надо привести к utf-8.

А вообще, я не знаю, получится ли.
695 1129947
>>29042

Перекатимся через пару-другую дней.

>>28751

У таблицы (и флоатов) нет проблемы с пробелами между элементами, можно задавать произвольный шаг для ячеек. А так да, у таблиц есть разные заморочки, например, нельзя позиционироваться относительно элементов таблицы, overflow на ячейках может не работать и тд.

У flex полно своих проблем. Баги ( гугли flex bugs ), было 2 версии спецификации, плюс, там сложный алгоритм расчета размеров, в котором надо разбираться. Ну например, я встречал случаи, когда флекс масштабировал картинки до нулевых размеров из-за нехватки места.

>>28717

Если ты чувствуешь, что не до конца понимаешь какую-то тему, можно попросить дополнительные усложненные задачки по ней.

По функциям в функциях в JS, у нас есть в ОП посте ссылочка, на наши задачи по JS, там как раз по этой теме много задач.

>>28701

> $textLength = strlen($text);


strlen не работает с кириллицей, используй mb_strlen: https://github.com/codedokode/pasta/blob/master/php/strings-utf8.md

> if ($text[$i]


Это тоже не работает с кириллицей, используй mb_substr (учти, что mb-функции не работают на ideone, используй другой сервис).

Вырезать пробелы проще всего через str_replace(' ', '', ..)

> $lost--;


> $first++;


Эти команды никакого смысла не имеют, так как на следующем шаге цикла ты снова вычисляешь эти переменные заново:

> $lost = $newText[$newTextLength - 1];


> $first = $newText[$j];



Более того, first/last хранят букву, а не число, и нет никакого смысла пытаться их увеличивать.

Попробуй вставить в цикл echo, который будет выводить значение first и lost, чтобы увидеть, что именно ты сравниваешь. Вообще, выводить содержимое переменных полезно, чтобы увидеть, где именно твоя программа работает не так.

Если ты обнаружил различие между буквами, то нет смысла продолжать цикл, надо выйти из него с помощью break.
695 1129947
>>29042

Перекатимся через пару-другую дней.

>>28751

У таблицы (и флоатов) нет проблемы с пробелами между элементами, можно задавать произвольный шаг для ячеек. А так да, у таблиц есть разные заморочки, например, нельзя позиционироваться относительно элементов таблицы, overflow на ячейках может не работать и тд.

У flex полно своих проблем. Баги ( гугли flex bugs ), было 2 версии спецификации, плюс, там сложный алгоритм расчета размеров, в котором надо разбираться. Ну например, я встречал случаи, когда флекс масштабировал картинки до нулевых размеров из-за нехватки места.

>>28717

Если ты чувствуешь, что не до конца понимаешь какую-то тему, можно попросить дополнительные усложненные задачки по ней.

По функциям в функциях в JS, у нас есть в ОП посте ссылочка, на наши задачи по JS, там как раз по этой теме много задач.

>>28701

> $textLength = strlen($text);


strlen не работает с кириллицей, используй mb_strlen: https://github.com/codedokode/pasta/blob/master/php/strings-utf8.md

> if ($text[$i]


Это тоже не работает с кириллицей, используй mb_substr (учти, что mb-функции не работают на ideone, используй другой сервис).

Вырезать пробелы проще всего через str_replace(' ', '', ..)

> $lost--;


> $first++;


Эти команды никакого смысла не имеют, так как на следующем шаге цикла ты снова вычисляешь эти переменные заново:

> $lost = $newText[$newTextLength - 1];


> $first = $newText[$j];



Более того, first/last хранят букву, а не число, и нет никакого смысла пытаться их увеличивать.

Попробуй вставить в цикл echo, который будет выводить значение first и lost, чтобы увидеть, что именно ты сравниваешь. Вообще, выводить содержимое переменных полезно, чтобы увидеть, где именно твоя программа работает не так.

Если ты обнаружил различие между буквами, то нет смысла продолжать цикл, надо выйти из него с помощью break.
696 1129948
>>28639

Можно, сделать массив с соответствием английский-русский заголовок и использовать этот массив при выводе заголовков.

>>28586

А что в foreach сложного? он используется так в простом варианте:

foreach ($массив as $переменная) {
тело цикла;
}

Он берет по очереди каждый элемент массива, копирует его значение в указанную переменную и выполняет тело цикла. То есть тело выполняется столько раз, сколько элементов в массиве. Простейший пример:

$array = ['red', 'green', 'blue'];
foreach ($array as $color) {
echo "Color: $color\n";
}

У анона вместо массива-переменной в foreach указано выражение (explode(' ', $pattern), которое разбивает строку по пробелам на массив слов. Соответственно, foreach на каждом шаге берет очередное слово (первый раз - word1, второй раз - word2 и тд).

>>28576

Не думаю, что шапка лучшее место для этого. Может надо просто улучшить урок по массивам.

> if (in_array($value, array_keys($words))) {


Вот это сложновато, я бы использовал if (array_key_exists($value, $words))

>>28533

А в чем вопрос? Если ты SQL знаешь, то по моему, это нетрудно.

>>28388

надо писать php filename.php

При этом если php не в PATH, то надо писать полный путь к нему, например c:\php\php.exe. Если filename.php не в текущей папке, то к нему тоже надо написать полный путь. Под windows пути с пробелами надо брать в двойные кавычки.

Подробнее https://github.com/codedokode/pasta/blob/master/soft/cli.md#Виды-команд

А может, твой код просто успешно выполняется, потому ничего и не пишет?
696 1129948
>>28639

Можно, сделать массив с соответствием английский-русский заголовок и использовать этот массив при выводе заголовков.

>>28586

А что в foreach сложного? он используется так в простом варианте:

foreach ($массив as $переменная) {
тело цикла;
}

Он берет по очереди каждый элемент массива, копирует его значение в указанную переменную и выполняет тело цикла. То есть тело выполняется столько раз, сколько элементов в массиве. Простейший пример:

$array = ['red', 'green', 'blue'];
foreach ($array as $color) {
echo "Color: $color\n";
}

У анона вместо массива-переменной в foreach указано выражение (explode(' ', $pattern), которое разбивает строку по пробелам на массив слов. Соответственно, foreach на каждом шаге берет очередное слово (первый раз - word1, второй раз - word2 и тд).

>>28576

Не думаю, что шапка лучшее место для этого. Может надо просто улучшить урок по массивам.

> if (in_array($value, array_keys($words))) {


Вот это сложновато, я бы использовал if (array_key_exists($value, $words))

>>28533

А в чем вопрос? Если ты SQL знаешь, то по моему, это нетрудно.

>>28388

надо писать php filename.php

При этом если php не в PATH, то надо писать полный путь к нему, например c:\php\php.exe. Если filename.php не в текущей папке, то к нему тоже надо написать полный путь. Под windows пути с пробелами надо брать в двойные кавычки.

Подробнее https://github.com/codedokode/pasta/blob/master/soft/cli.md#Виды-команд

А может, твой код просто успешно выполняется, потому ничего и не пишет?
697 1129949
>>28308

Так конечно можно сделать, но надо исправить предупреждение:

> PHP Notice: Undefined offset: 9 in /home/mH91p8/prog.php on line 30



>>28193

> Это не Respоnsive как он должен быть, они генерируют свою версию под каждый экран и устройство


Да, есть такое, я замечал, они для старых браузеров могут отдавать старую верстку. Вот видишь, как полезно ковыряться в других сайтах и смотреть, как что сделано.

Может это оптимизация, не отдавать на устройство правила, которые ему не понадобятся все равно.

> Алсо у меня нет возможности проверять на мобильных браузерах


Можно использовать Хром (с движком webkit или blink) и в инструментах разработчика ставить эмуляцию мобильных устройств - она довольно хорошо работает.

> но есть подозрение, что они оптимизируют под хром (на котором я тестировал) добавляя свои -webkit свойства, которым я поддержки не нашел на caniuse


А большинство мобильных браузеров на движке webkit/blink (андроидовский встроенный, Хром, safari). Не на нем разве что мобильный фаерфокс и может еще какая-то экзотика. Сейчас осталось всего 3 движка - Webkit/blink, Gecko (FF) и Trident (IE).

Само свойство, кстати, описано в MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/::-webkit-scrollbar

Конечно, использовать такие свойства надо с пониманием, что они работают далеко не везде.

>>27802

Вообще, кроссдоменные запросы можно сделать и для старых браузеров, без поддержки кроссдоменных заголовков, например, с помощью древней технологии JSONP: https://learn.javascript.ru/ajax-jsonp - там единственная проблема, не всегда удается обнаружить ошибку, только если по таймауту.

Также, я помню, была какая-то хитрая технология передачи данных через hash в URL страницы в ифрейме.

Была библиотека easyxdm для поддержки таких вот древних браузеров https://easyxdm.net/wp/ (список поддерживаемых браузеров впечатляет).

Статья: https://habrahabr.ru/post/120336/

>>27368

> $randomText = $letters[$random];


Найти в массиве $letters элемент с ключом, который хранится в $random, и вернуть значение этого элемента в переменную $randomText.
697 1129949
>>28308

Так конечно можно сделать, но надо исправить предупреждение:

> PHP Notice: Undefined offset: 9 in /home/mH91p8/prog.php on line 30



>>28193

> Это не Respоnsive как он должен быть, они генерируют свою версию под каждый экран и устройство


Да, есть такое, я замечал, они для старых браузеров могут отдавать старую верстку. Вот видишь, как полезно ковыряться в других сайтах и смотреть, как что сделано.

Может это оптимизация, не отдавать на устройство правила, которые ему не понадобятся все равно.

> Алсо у меня нет возможности проверять на мобильных браузерах


Можно использовать Хром (с движком webkit или blink) и в инструментах разработчика ставить эмуляцию мобильных устройств - она довольно хорошо работает.

> но есть подозрение, что они оптимизируют под хром (на котором я тестировал) добавляя свои -webkit свойства, которым я поддержки не нашел на caniuse


А большинство мобильных браузеров на движке webkit/blink (андроидовский встроенный, Хром, safari). Не на нем разве что мобильный фаерфокс и может еще какая-то экзотика. Сейчас осталось всего 3 движка - Webkit/blink, Gecko (FF) и Trident (IE).

Само свойство, кстати, описано в MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/::-webkit-scrollbar

Конечно, использовать такие свойства надо с пониманием, что они работают далеко не везде.

>>27802

Вообще, кроссдоменные запросы можно сделать и для старых браузеров, без поддержки кроссдоменных заголовков, например, с помощью древней технологии JSONP: https://learn.javascript.ru/ajax-jsonp - там единственная проблема, не всегда удается обнаружить ошибку, только если по таймауту.

Также, я помню, была какая-то хитрая технология передачи данных через hash в URL страницы в ифрейме.

Была библиотека easyxdm для поддержки таких вот древних браузеров https://easyxdm.net/wp/ (список поддерживаемых браузеров впечатляет).

Статья: https://habrahabr.ru/post/120336/

>>27368

> $randomText = $letters[$random];


Найти в массиве $letters элемент с ключом, который хранится в $random, и вернуть значение этого элемента в переменную $randomText.
698 1129950
>>27180

> Перед объявлением внешних ключей, нужно создать одинаковые по типу столбцы, один из которых должен быть первичным ключом


Не требуется, чтобы один из столбцов был бы первичным ключом. Не требуется, чтобы они были в разных таблицах. Можно связать любые поля или группы полей, лишь бы они были одного типа.

> А что значит "внешний ключ и ссылочный ключ должны находиться в первых столбцах"?


В обоих таблицах должны быть индексы, где колонки, из которых составлен внешний и ссылочный ключ, идут в начале списка полей.

Допустим, есть таблицы a и b, и поля в них a.b_id (внешний ключ) и b.id (первичный ключ).

Чтобы создать внешний ключ, связывающий поле a.b_id с b.id, нужно, чтобы для обоих этих полей были бы созданы индексы. Иначе проверка наличия связи будет очень медленной и потребует перебора всей таблицы.

Следовательно, в таблице a должен быть индекс либо по полю b_id, либо по нескольким полям, где b_id идет первым (например: (b_id, x, y)). Аналогично должно быть и в таблице b для поля id. Если id - это первичный ключ, то индекс по нему уже есть, так как при объявлении первичного ключа в MySQL создается уникальный индекс по указанному полю.

Внешний ключ может связывать не одно поле с одним, а пары или группы полей. Например, можно определить, что тройка полей (a.x, a.y, a.z) ссылается на тройку полей (b.x, b.y, b.z). В этои случае должен быть индекс, содержащий эти 3 поля или такой, в котором список полей начинается с них.

Однако, информация у тебя в переводе немного устарела. Вот более новый мануал на англ:

> https://dev.mysql.com/doc/refman/5.5/en/create-table-foreign-keys.html



> MySQL requires indexes on foreign keys and referenced keys so that foreign key checks can be fast and not require a table scan. In the referencing table, there must be an index where the foreign key columns are listed as the first columns in the same order. Such an index is created on the referencing table automatically if it does not exist.



> MySQL требует наличия индексов на внешних и ссылочных ключах так, что проверки могут быть быстрыми и не потребуют полного обхода таблицы. В ссылающейся таблице должен быть индекс, где колонки из внешнего ключа идут первыми, в том же порядке. Такой индекс создается в ссылающейся таблице автоматически, если он не существует.



Про индексы и зачем они нужны: https://ruhighload.com/post/Работа+с+индексами+в+MySQL

Про внешние ключи: http://denis.in.ua/foreign-keys-in-mysql.htm

>>26786

Думаю, что любой фреймворк.

Вообще, для каких-то простых случаев может хватить встроенного в PHP веб-сервера:

https://github.com/codedokode/pasta/blob/master/soft/web-server.md#Веб-сервер

https://www.google.ru/search?q=php+встроенный+сервер&newwindow=1&dcr=0&gbv=1&sei=rF5yWtSSJo6VkwWfwYWwDw

Копируешь PHP с php.ini на флешку, и запускаешь из командной строки.

Если твой сайт/фреймворк использовал htaccess и ЧПУ, придется написать свой скрипт маршрутизации.
698 1129950
>>27180

> Перед объявлением внешних ключей, нужно создать одинаковые по типу столбцы, один из которых должен быть первичным ключом


Не требуется, чтобы один из столбцов был бы первичным ключом. Не требуется, чтобы они были в разных таблицах. Можно связать любые поля или группы полей, лишь бы они были одного типа.

> А что значит "внешний ключ и ссылочный ключ должны находиться в первых столбцах"?


В обоих таблицах должны быть индексы, где колонки, из которых составлен внешний и ссылочный ключ, идут в начале списка полей.

Допустим, есть таблицы a и b, и поля в них a.b_id (внешний ключ) и b.id (первичный ключ).

Чтобы создать внешний ключ, связывающий поле a.b_id с b.id, нужно, чтобы для обоих этих полей были бы созданы индексы. Иначе проверка наличия связи будет очень медленной и потребует перебора всей таблицы.

Следовательно, в таблице a должен быть индекс либо по полю b_id, либо по нескольким полям, где b_id идет первым (например: (b_id, x, y)). Аналогично должно быть и в таблице b для поля id. Если id - это первичный ключ, то индекс по нему уже есть, так как при объявлении первичного ключа в MySQL создается уникальный индекс по указанному полю.

Внешний ключ может связывать не одно поле с одним, а пары или группы полей. Например, можно определить, что тройка полей (a.x, a.y, a.z) ссылается на тройку полей (b.x, b.y, b.z). В этои случае должен быть индекс, содержащий эти 3 поля или такой, в котором список полей начинается с них.

Однако, информация у тебя в переводе немного устарела. Вот более новый мануал на англ:

> https://dev.mysql.com/doc/refman/5.5/en/create-table-foreign-keys.html



> MySQL requires indexes on foreign keys and referenced keys so that foreign key checks can be fast and not require a table scan. In the referencing table, there must be an index where the foreign key columns are listed as the first columns in the same order. Such an index is created on the referencing table automatically if it does not exist.



> MySQL требует наличия индексов на внешних и ссылочных ключах так, что проверки могут быть быстрыми и не потребуют полного обхода таблицы. В ссылающейся таблице должен быть индекс, где колонки из внешнего ключа идут первыми, в том же порядке. Такой индекс создается в ссылающейся таблице автоматически, если он не существует.



Про индексы и зачем они нужны: https://ruhighload.com/post/Работа+с+индексами+в+MySQL

Про внешние ключи: http://denis.in.ua/foreign-keys-in-mysql.htm

>>26786

Думаю, что любой фреймворк.

Вообще, для каких-то простых случаев может хватить встроенного в PHP веб-сервера:

https://github.com/codedokode/pasta/blob/master/soft/web-server.md#Веб-сервер

https://www.google.ru/search?q=php+встроенный+сервер&newwindow=1&dcr=0&gbv=1&sei=rF5yWtSSJo6VkwWfwYWwDw

Копируешь PHP с php.ini на флешку, и запускаешь из командной строки.

Если твой сайт/фреймворк использовал htaccess и ЧПУ, придется написать свой скрипт маршрутизации.
699 1129951
>>26752

Один из вариантов - сделать сайт-имитацию, который будет притворяться другим сайтом и отдавать заранее заложенные в него ответы. И поменять на основном сайте настройку, чтобы он обращался к этой копии.

Другой вариант - просто в коде предусмотреть заглушку, чтобы возвращались какие-то заранее заготовленные данные безо всяких запросов.

Речь об автоматизированных тестах или ручной проверке?

Еще тут вопрос, что именно ты хочешь протестировать?

1) что твое приложение отправляет запрос с определенными параметрами на внешний сервер?
2) что твое приложение корректно разбирает пришедший от внешнего сервера ответ?
3) что твое приложение корректно обрабатывает ошибки соединения с внешним сервером?
4) что твое приложение корректно использует полученные от внешнего сервера данные?

Для случаев 1-3 надо либо делать имитацию внешнего сайта, либо для автоматических тестов, можно мокать HTTP-клиент. Для случая 4 можно просто возвращать заранее заготовленные данные.

>>26728

Проведи исследование вакансий на hh.ru. Напиши сюда отчет.

>>26615

Файл с php-кодом надо сохранить в кодировке utf-8 без BOM. Проверь, так ли это.

>>26590

Ох, как сложно понять, что тебе требуется.

Я думаю, что тут нужна группировка строк, относящихся к одному товару, и проверка по условию HAVING (это условие, которое применяется к сгруппированным строкам, после группировки, в отличие от WHERE).

То есть:

- джойним к товару все его значения жесткости, получаем несколько строк на товар
- группируем строки, относящиеся к 1 товару
- отбираем только те, где есть (или где нет) определенная жесткость

SELECT ...
FROM products p
LEFT JOIN product_hardness ph
LEFT JOIN hardness h
...
GROUP BY p.id
HAVING SUM(h.id = 3) > 0

Как это работает?

h.id = 3 возвращает 0 или 1 в зависимости от выполнения равенства
SUM() складывает результаты (0 и 1) в группе

В чем тут подвох?

Если у товара нет жесткости, то LEFT JOIN произведет строку, где h.id IS NULL и равенство h.id = 3 даст тоже NULL. Не испортит ли это результат суммирования, превратив его в NULL? Гуглим:

https://stackoverflow.com/questions/39384791/understanding-sumnull-in-mysql/39384877

> This section describes group (aggregate) functions that operate on sets of values. Unless otherwise stated, group functions ignore NULL values.



SUM пропускает значения NULL. Ну и прекрасно.

Почему кстати LEFT JOIN? Бывают товары без жесткости?

Уточняй, если что-то непонятно.
699 1129951
>>26752

Один из вариантов - сделать сайт-имитацию, который будет притворяться другим сайтом и отдавать заранее заложенные в него ответы. И поменять на основном сайте настройку, чтобы он обращался к этой копии.

Другой вариант - просто в коде предусмотреть заглушку, чтобы возвращались какие-то заранее заготовленные данные безо всяких запросов.

Речь об автоматизированных тестах или ручной проверке?

Еще тут вопрос, что именно ты хочешь протестировать?

1) что твое приложение отправляет запрос с определенными параметрами на внешний сервер?
2) что твое приложение корректно разбирает пришедший от внешнего сервера ответ?
3) что твое приложение корректно обрабатывает ошибки соединения с внешним сервером?
4) что твое приложение корректно использует полученные от внешнего сервера данные?

Для случаев 1-3 надо либо делать имитацию внешнего сайта, либо для автоматических тестов, можно мокать HTTP-клиент. Для случая 4 можно просто возвращать заранее заготовленные данные.

>>26728

Проведи исследование вакансий на hh.ru. Напиши сюда отчет.

>>26615

Файл с php-кодом надо сохранить в кодировке utf-8 без BOM. Проверь, так ли это.

>>26590

Ох, как сложно понять, что тебе требуется.

Я думаю, что тут нужна группировка строк, относящихся к одному товару, и проверка по условию HAVING (это условие, которое применяется к сгруппированным строкам, после группировки, в отличие от WHERE).

То есть:

- джойним к товару все его значения жесткости, получаем несколько строк на товар
- группируем строки, относящиеся к 1 товару
- отбираем только те, где есть (или где нет) определенная жесткость

SELECT ...
FROM products p
LEFT JOIN product_hardness ph
LEFT JOIN hardness h
...
GROUP BY p.id
HAVING SUM(h.id = 3) > 0

Как это работает?

h.id = 3 возвращает 0 или 1 в зависимости от выполнения равенства
SUM() складывает результаты (0 и 1) в группе

В чем тут подвох?

Если у товара нет жесткости, то LEFT JOIN произведет строку, где h.id IS NULL и равенство h.id = 3 даст тоже NULL. Не испортит ли это результат суммирования, превратив его в NULL? Гуглим:

https://stackoverflow.com/questions/39384791/understanding-sumnull-in-mysql/39384877

> This section describes group (aggregate) functions that operate on sets of values. Unless otherwise stated, group functions ignore NULL values.



SUM пропускает значения NULL. Ну и прекрасно.

Почему кстати LEFT JOIN? Бывают товары без жесткости?

Уточняй, если что-то непонятно.
700 1129953
>>26221

Это зависит от того, какие пакеты там есть и какие из них тебе нужны.

Судя по списку http://www.tinycorelinux.net/8.x/x86/tcz/ там есть:

- php5/7
- apache2
- postgresql

Нет

- mysql
- многих PHP расширений

Потому тебе придется их устанавливать и компилировать самому.

Я бы попробовал его поставить в virtual box и посмотрел.

Ну и вообще, я бы смотрел в сторону Debian Testing - он не такой огромный, консольная версия отнимает меньше гига на диске по моему и памяти много не ест, но выбор пакетов куда больше.

>>26015

Не знаю. Изучить куки наверно, поискать готовые статьи по теме.

>>26034

Если ты вставляешь переменные прямо в запрос, появляется риск SQL-инъекции, прочти тут: https://github.com/codedokode/pasta/blob/master/security/sql-injection.md

> Короч, посаны, че делать?


Вообще, лучше нормально проектировать БД. В твоем случае - можно попробовать искать не просто "а", а например CONCAT(',', friut, ',') LIKE '%,а,%'. Ну или использовать принципы нормализации и не писать в одну ячейку несколько разных значений: https://github.com/codedokode/pasta/blob/master/db/normalization.md

Также, в PostgreSQL можно хранить в ячейке массив строк или даже JSON объект.
700 1129953
>>26221

Это зависит от того, какие пакеты там есть и какие из них тебе нужны.

Судя по списку http://www.tinycorelinux.net/8.x/x86/tcz/ там есть:

- php5/7
- apache2
- postgresql

Нет

- mysql
- многих PHP расширений

Потому тебе придется их устанавливать и компилировать самому.

Я бы попробовал его поставить в virtual box и посмотрел.

Ну и вообще, я бы смотрел в сторону Debian Testing - он не такой огромный, консольная версия отнимает меньше гига на диске по моему и памяти много не ест, но выбор пакетов куда больше.

>>26015

Не знаю. Изучить куки наверно, поискать готовые статьи по теме.

>>26034

Если ты вставляешь переменные прямо в запрос, появляется риск SQL-инъекции, прочти тут: https://github.com/codedokode/pasta/blob/master/security/sql-injection.md

> Короч, посаны, че делать?


Вообще, лучше нормально проектировать БД. В твоем случае - можно попробовать искать не просто "а", а например CONCAT(',', friut, ',') LIKE '%,а,%'. Ну или использовать принципы нормализации и не писать в одну ячейку несколько разных значений: https://github.com/codedokode/pasta/blob/master/db/normalization.md

Также, в PostgreSQL можно хранить в ячейке массив строк или даже JSON объект.
701 1129954
>>25831

> Если быть точным, $digit - количество попыток сделать http-реквест, а $flag - флаг, говорящий, надо ли делать другие попытки, либо хватит одной


Зачем flag, если можно просто указать digit = 1 ?

> A::lol(int $digit) принимает только количество попыток, это обобщенный отправитель http-реквестов. Класс B - это отправитель реквестов, заточенный под конкретный сайт.



Тогда я не уверен, что тут стоит применять наследование A от B. Это же по сути разные классы. "обобщенный отправитель реквестов" называется HTTP-клиент и как минимум, он должен принимать URL, куда делается запрос. А класс B мог бы получать его через конструктор:

$httpClient = new HttpClient(...);
$exampleComParser = new ExampleComParser($httpClient);

Это называется DI и описано в моем уроке, более того, в конце есть как раз пример с отправкой запросов: https://github.com/codedokode/pasta/blob/master/arch/di.md

Теперь про HttpClient. Часто код в нем можно разделить на "базовый клиент" и "расширения", например, расширение для кеширования ответов, расширение для повторных запросов при ошибке, расширение для использования случайного прокси-сервера из списка. Тут обычно используют один из 2 подходов:

1) встраивают возможность расширения в сам HttpClient, чтобы он держал в себе список расширений (тот же DI) и вызывал бы их на разных этапах:

$httpClient = new HttpClient;
$httpClient->addExtension(new HttpCacheExtension(параметры кеширования));
$httpClient->addExtension(new HttpProxySelectExtension(список прокси));
$response = $httpClient->get(...);

Для расширений стоит сделать интерфейс и/или базовый класс.

2) используют "оборачивание" HttpClient в расширения. При этом стоит их объединить общим интерфейсом:

$httpClient = new HttpClient;
$cachedClient = new CachedHttpClient($httpClient, параметры кеширования);
$response = $cachedClient->get(...);

Во втором случае HttpClient не обязан знать ничего про расширения к нему и как-то с ними специально взаимодействовать.

> Сейчас у меня и А::lol, и B::lol возвращают объект WebResponse. Есть метод WebResponse::getStatusCode(). Для B мне нужно его пропатчить. Я делаю BWebResponse extends WebResponse и реализую метод BWebResponse::getStatusCode().



Не надо патчить, надо сразу создавать объект с нужным кодом.

В общем, мне не нравится твоя архитектура. Посмотри на мои предложения, также посмотри на готовые библиотеки вроде Guzzle, как у них сделано.

Если ты хочешь лучше разбираться в ООП, я бы советовал начать с более простых задач, например, про Гостиницу или Продюсерское Агенство: https://phpclub.tech/pr/res/1109863.html#1116338

>>18864

А меня в Си отталкивает наличие хедеров, отстутствие нормальных строк и массивов. Как на нем вообще можно что-то писать?
701 1129954
>>25831

> Если быть точным, $digit - количество попыток сделать http-реквест, а $flag - флаг, говорящий, надо ли делать другие попытки, либо хватит одной


Зачем flag, если можно просто указать digit = 1 ?

> A::lol(int $digit) принимает только количество попыток, это обобщенный отправитель http-реквестов. Класс B - это отправитель реквестов, заточенный под конкретный сайт.



Тогда я не уверен, что тут стоит применять наследование A от B. Это же по сути разные классы. "обобщенный отправитель реквестов" называется HTTP-клиент и как минимум, он должен принимать URL, куда делается запрос. А класс B мог бы получать его через конструктор:

$httpClient = new HttpClient(...);
$exampleComParser = new ExampleComParser($httpClient);

Это называется DI и описано в моем уроке, более того, в конце есть как раз пример с отправкой запросов: https://github.com/codedokode/pasta/blob/master/arch/di.md

Теперь про HttpClient. Часто код в нем можно разделить на "базовый клиент" и "расширения", например, расширение для кеширования ответов, расширение для повторных запросов при ошибке, расширение для использования случайного прокси-сервера из списка. Тут обычно используют один из 2 подходов:

1) встраивают возможность расширения в сам HttpClient, чтобы он держал в себе список расширений (тот же DI) и вызывал бы их на разных этапах:

$httpClient = new HttpClient;
$httpClient->addExtension(new HttpCacheExtension(параметры кеширования));
$httpClient->addExtension(new HttpProxySelectExtension(список прокси));
$response = $httpClient->get(...);

Для расширений стоит сделать интерфейс и/или базовый класс.

2) используют "оборачивание" HttpClient в расширения. При этом стоит их объединить общим интерфейсом:

$httpClient = new HttpClient;
$cachedClient = new CachedHttpClient($httpClient, параметры кеширования);
$response = $cachedClient->get(...);

Во втором случае HttpClient не обязан знать ничего про расширения к нему и как-то с ними специально взаимодействовать.

> Сейчас у меня и А::lol, и B::lol возвращают объект WebResponse. Есть метод WebResponse::getStatusCode(). Для B мне нужно его пропатчить. Я делаю BWebResponse extends WebResponse и реализую метод BWebResponse::getStatusCode().



Не надо патчить, надо сразу создавать объект с нужным кодом.

В общем, мне не нравится твоя архитектура. Посмотри на мои предложения, также посмотри на готовые библиотеки вроде Guzzle, как у них сделано.

Если ты хочешь лучше разбираться в ООП, я бы советовал начать с более простых задач, например, про Гостиницу или Продюсерское Агенство: https://phpclub.tech/pr/res/1109863.html#1116338

>>18864

А меня в Си отталкивает наличие хедеров, отстутствие нормальных строк и массивов. Как на нем вообще можно что-то писать?
702 1129969
>>18851

Конечно, можно.
703 1130056
>>29954

ОПчик, спасибо большое за твой труд и помощь.
Мне больше не к кому обратиться по поводу код-ревью - только к тебе и анону.
Можешь посмотреть этот небольшой метод для отправки данных на сервер через fsockopen и посоветовать что улучшить и ответить на вопросы, которые я написал в комментариях к коду? Спасибо.

https://pastebin.com/i69cKanH
HNCK4067.jpg6,6 Мб, 4000x2667
704 1130366
Парни, всем добра.
Подскажите какие плагины мне смотреть что-бы превратить Sublime в PhpStorm? Интересует отладка XDEBUG ну это гуглится и форматирование кода, проверки на ходу, которые делает PhpStorm, ну и если будет так же дополнять код по мере набора и высвечивать описание функций - будет просто супер.
705 1130536
Сделал временное зеркало для сайта без рекламы и прочей ерунды https://codedokode.github.io/phpbook (оно вас отредиректит на временный домен, не запоминайте его, не сохраняйте, не распространяйте, он тестовый, временный и в будущем поменяется. Плюс, это бесплатный домен и я ему абсолютно не доверяю).

Протестируйте, пожалуйста.

Если все будет ок, перейдем с юкоза на гитхаб.
706 1130599
Почему не работает? Ошибку выдает такую: String could not be parsed as XML. Как и что тогда передавать итератору?

$test = simplexml_load_file("myfile.xml");

$xmlIterator = new SimpleXMLIterator($test);
var_dump($xmlIterator->current());

$xmlIterator->rewind(); // сбрасывает курсор к первому элементу
var_dump($xmlIterator->current());
707 1130614
>>30536
На первый взгляд всё ок. Пощёлкал по всем ссылкам.
708 1130625
>>18555 (OP)
Анон, у меня тут два вопроса:

1.ГДЕ ПЕРЕКОТ???
2.Я правильно понимаю, что MVC - это модуль для Visual studio?
709 1130632
>>18555 (OP)
Залил свой код на сайт phpformatter.com , а он повис.
710 1130635
>>30625

>MVC - это модуль для Visual studio?


Может и есть такой модуль для VS, не знаю. Но чаще это означает Model-View-Controller - https://ru.wikipedia.org/wiki/Model-View-Controller
711 1130639
>>30635
Меня вообще напугала эта хуйня: гигантский Visual Studio. В него добавил модуль PHP.
Там, блядь. сообщение, что все платно!

И ведь, сука, если я через нотпад++ буду на серваке все гонять, то нахуя мне вообще понадобится такой левиафан?
712 1130647
>>30639
Для разработки на php лучше всего подойдёт phpstorm, но он платный. Можешь бесплатно купить с торрентов.
А для решения задач опа хватит и нотепада или саблайма с головой.
713 1130659
>>30647
Просто я сейчас работаю недомакакой (преобразование текста в ссылку) и вот подумал, что нужно отучиваться от нотпада.

Алсо, а куда можно скинуть код, чтобы меня обоссали?
Ну т.е. у меня уже есть полностью рабочая версия кода, но я хочу, чтобы мне заяснили, где я изобретал велосипед, где делал бессмысленные вещи, а где просто валял хуйню?
714 1130858
>>30659
ideone, pastebin, github
715 1131195
Еле тред нашел. Перекотываться будете, пыханы?
716 1131219
пацаны, а что значит "изучать фреймворк"? я вот учу симфони и пока получается, что я изучаю как писать конфиги к компонентам, грубо говоря. предполагает ли изучение фреймворка изучение исходного кода?
717 1131227
Здравствуйте, тут год назад ( наверное) кто то создавал конференцию в телеграмме, я туда зашел, был в числе первого десятка кто сидел, но проебал сим-карту, и теперь ее не могу нигде найти. Может у кого сохранилась ссылка, не могли-бы вы поделиться, пожалуйста?
718 1131245
>>31195

Погоди еще день-два, и перекатимся.

>>31219

Да, это понадобится, как только ты захочешь сделать что-то нестандартное. У нас в шапке есть задача про TestHub, в ней конфигами ты вряд ли обойдешься.
719 1131251
Здравствуйте, я вот начал изучать с++, сделал на нем примитивный текстовой квест на чистых условиях, параллельно потихоньку просматривал пхп из гайда для новичков в шапке, и решил спросить, а можно ли такое же сделать и на пхп?

В с++ как, в вижуал студио написал, скомпилировал - и весь квест в консольке работает, а взаимодействие - введите 1 или 2 для продвижения, и тому подобное.

Условия в пхп я изучил, но что то не наблюдаю такой возможности, что бы человек мог ввести какую либо цифру, или значение - и что то произошло. Это уже дальше будет?
изображение.png20 Кб, 780x322
721 1131256
>>31255
Т.е. вот это аналог cin >> в крестах? Понял, спасибо.
722 1131257
Сап, Оп. Я мелкопараша-кун, если помнишь. Разгреб свои дела и приступил к разработке, а если точнее, то к проектированию бд. Поизучал другие движки, как ты и советовал, сел с ручкой и листком, вроде сделал.
Но тут возникла проблема в моем непонимании устройства самой борды, т.к я на бордах относительно недавно да и педалику вакабу не настраивал. Не могу понять, как тонут и как взлетаю треды, что значит поле bump (если тред, то время последнего отписанного в него поста, но что это значит??) и тд. Буду очень благодарен, если кто-то объяснит этот аспект.
723 1131258
>>31256
fgets читает данные из ресурса, коим может быть файл или stdin или что-то другое (https://secure.php.net/manual/en/resource.php вон их сколько).

по аналогам из с++ пусть подскажет кто-то более сведущий. я хз
kotik-sdelaj-sam.gif5,6 Мб, 461x259
724 1131288
>>30056
Всё ещё жду чьего-нибудь код-ревью.
725 1131302
>>31257
Если в треде постов меньше бамп-лимита, то при добавлении поста обновляем поле бамп (меняем там время на свежее), если больше, не обновляем. При сортировке по этому полю по убыванию, свежие треды будут сверху, чутка подтухшие ниже, треды в бамплимите в самом низу. Так же мы выбираем только треды до определенного лимита (например не более 50 для раздела). Если при сортировке по бампу тред идет 51, пользователь его не увидит, тред "смыло". В базе он еще будет, нам нужно позаботится что бы иногда чистить базу от старых тредов (например отправлять их на архивач). Если у тебя открыта вкладка в браузере со старым тредом, ты некоторое время еще можешь открывать картинки из него, значит скрипт уборщик еще не отработал.
726 1131334
>>31302
Премного благодарен.
727 1131535
>>21562

>Может тогда автоматические тесты сделаешь?


Сделал тесты для задачки по студентам (а заодно переделал все по твоим замечаниям):
https://github.com/moabit/student-list/tree/master/app/Tests
ОП, можешь глянуть, если не сложно? Тесты пока что никогда не пробовал писать. Нужно ли для них тоже писать комментарии и PHPDoc? Я правильно понял, что тесты для контроллеров не имеют смысла?
728 1131584
>>31245
спасибо, решу задачку эту! а для проверки только код на гитхабе или сам сайт задеплоить?
729 1131859
Почему header("Location:dashboard.php"); не работает у меня? Он не перенаправляет на страницу, перезагружает текущую без вывода каких-либо ошибок?
Может ли это быть из-за того, что я pdo накосячи
а я накосячил
?
image.png94 Кб, 690x273
730 1131896
Как в Symfony инициализируется приложение? Т.е. работа приложения начинается с индексной страницы, насколько я понимаю? Она создаётся автоматически и со всему настройками, после composer create-project symfony/website-skeleton my-project?
Почему, кстати, в Quick Tour написано просто skeleton? Где можно прочитать об этом?
15176866562360.jpg452 Кб, 1243x1024
731 1131930
ОП, раскрой, пожалуйста, исходники https://phpclub.tech/.
Очень хочется посмотреть на грамотное решение сайта с пагинацией и архивированием тредов.
732 1131935
>>31930
Я не ОП, но, всем известно, что код находиться здесь https://github.com/someApprentice/phpClub
733 1131937
>>30056

>С помощью @ подавляю ошибки


Никогда так не делай. Некоторые ребята говорят, что всякие запросы через интернет - это исключения, когда можно юзать собачек. Нет, нельзя.
В интернете может сломаться даже небо, даже аллах - такой уровень абстракций скрывается под простым открытием сокета. Но что интересно - ломается, как правило, однократно. Можешь сделать трассировку от твоего хостинга до сайта, куда ты ломишься. Там будет 10-20 хопов. На каждом хопе пакетик может куда-нибудь деться, переполниться буфер или еще что-нибудь.
Так как fsockopen не кидает обрабатываемых эксепшнов, надо это починить.
Делаешь так: https://pastebin.com/LaVbsbGQ (Заметь, что сломаются собачки. Их можно починить, но не скажу как. В хорошем коде никаких собачек нет, только try/catch.)
Затем оборачиваешь fsockopen в try/catch, пишешь в лог, что случилось, и вот тогда уже возвращаешь что-то дефолтное. Но это уже две задачи для твоей функции. Сделай обертку, которая будет делать sockPost(), и возвращать либо ответ, либо дефолт. Плюс дефолт не должен быть захардкожен.

>Какая разница между timeout в fsockopen и этой настройкой?


Полагаю, ее нет.

>Что значит non blocking mode?


https://stackoverflow.com/questions/5294544/blocking-and-non-blocking-modes-in-php-streams

>Я только нашёл, что если его поставить в 0 то вместе с нужными мне данными от сервера придут ещё заголовки http запроса


Они должны прийти тебе в любом случае.

>если я меняю версию HTTP на 1.1 то время ответа увеличивается в несколько раз! Почему так?


Потому что HTTP 1.1 по умолчанию ждет от тебя несколько запросов в одном сокете. Ждет-ждет, не дожидается, рвет коннект. Тебе нужно явно обзначить, что запрос только один, заголовком Connection: close.

>Вот эту часть не понимаю - зачем вообще она нужна


Ты читаешь все http-заголовки в переменную headers. Так как заголовки отделены от тела пустой строкой, цикл прекращает крутится на пустой строчке.

>Если я правильно понял, metainfo['timed_out'] нужно, чтобы закрыть соединение


Неправильно. При наступлении тайм-аута соединение уже оборвано. fgets просто вернет тебе false, а feof не вернет, конец-то не достгнут. А еще false от fgets может прилететь и по другим поводам. Вот так лучше:
https://stackoverflow.com/questions/18349123/stream-set-timeout-doesnt-work-in-php#18350140

А теперь самое главное и веселое. Ты зачем это написал-то? file_get_contents делает всё то же самое, только под капотом. POST-запросы и куча других опций отправляются добавлением stream context.
733 1131937
>>30056

>С помощью @ подавляю ошибки


Никогда так не делай. Некоторые ребята говорят, что всякие запросы через интернет - это исключения, когда можно юзать собачек. Нет, нельзя.
В интернете может сломаться даже небо, даже аллах - такой уровень абстракций скрывается под простым открытием сокета. Но что интересно - ломается, как правило, однократно. Можешь сделать трассировку от твоего хостинга до сайта, куда ты ломишься. Там будет 10-20 хопов. На каждом хопе пакетик может куда-нибудь деться, переполниться буфер или еще что-нибудь.
Так как fsockopen не кидает обрабатываемых эксепшнов, надо это починить.
Делаешь так: https://pastebin.com/LaVbsbGQ (Заметь, что сломаются собачки. Их можно починить, но не скажу как. В хорошем коде никаких собачек нет, только try/catch.)
Затем оборачиваешь fsockopen в try/catch, пишешь в лог, что случилось, и вот тогда уже возвращаешь что-то дефолтное. Но это уже две задачи для твоей функции. Сделай обертку, которая будет делать sockPost(), и возвращать либо ответ, либо дефолт. Плюс дефолт не должен быть захардкожен.

>Какая разница между timeout в fsockopen и этой настройкой?


Полагаю, ее нет.

>Что значит non blocking mode?


https://stackoverflow.com/questions/5294544/blocking-and-non-blocking-modes-in-php-streams

>Я только нашёл, что если его поставить в 0 то вместе с нужными мне данными от сервера придут ещё заголовки http запроса


Они должны прийти тебе в любом случае.

>если я меняю версию HTTP на 1.1 то время ответа увеличивается в несколько раз! Почему так?


Потому что HTTP 1.1 по умолчанию ждет от тебя несколько запросов в одном сокете. Ждет-ждет, не дожидается, рвет коннект. Тебе нужно явно обзначить, что запрос только один, заголовком Connection: close.

>Вот эту часть не понимаю - зачем вообще она нужна


Ты читаешь все http-заголовки в переменную headers. Так как заголовки отделены от тела пустой строкой, цикл прекращает крутится на пустой строчке.

>Если я правильно понял, metainfo['timed_out'] нужно, чтобы закрыть соединение


Неправильно. При наступлении тайм-аута соединение уже оборвано. fgets просто вернет тебе false, а feof не вернет, конец-то не достгнут. А еще false от fgets может прилететь и по другим поводам. Вот так лучше:
https://stackoverflow.com/questions/18349123/stream-set-timeout-doesnt-work-in-php#18350140

А теперь самое главное и веселое. Ты зачем это написал-то? file_get_contents делает всё то же самое, только под капотом. POST-запросы и куча других опций отправляются добавлением stream context.
734 1131944
>>31935
Нихрена себе сторонних зависимостей ради такой простой задачи!
735 1131954
>>31944
это по-твоему много? это вообще хуета
736 1131957
>>31954
Сколько нужно сторонних модулей, чтобы, мать его, просто сграбить посты, положить в базу, показать юзеру? Серьезно, там же вообще список охуевший.
737 1132011
>>31957
ты видимо просто еще не привык. в реальных приложениях зависимостей всегда дохуя. для crud-приложения на симфони с 4 сущностями их допустим 25+. но я тут проблемы не вижу - они жрать не просят
738 1132193
Делал задачку из шапки, где надо сделать форму, которая расчитывает кредит на пхп. Поясните дебилу, как сделать так, чтобы мой код не выполнялся до того, пока не отправишь форму.
739 1132198
>>32193

Если (форма отправлена) {
выполнить расчет;
}

вывести форму;
если проведен расчет, вывести результаты;

Проверить, что форма была отправлена, можно разными способами:

- по наличию в $_GET ключей, соответствующих полям формы
- по наличию в $_GET ключа, соответствующего имени кнопки
- для POST-форм проверкой $_SERVER['REQUEST_METHOD'] (не для нашего случая)

Урок про работу с формами вообще, не знаю, пригодится ли: https://github.com/codedokode/pasta/blob/master/forms.md
740 1132203
>>32198

>Проверить, что форма была отправлена, можно разными способами:


Единственно верный способ уходить на ветку обработки формы - проверять присутствие всех необходимых ключей в $_GET либо $_POST.
741 1132204
>>32198
спасибо, два чаю тебе с куками
14949623451540.jpg109 Кб, 475x462
742 1132212
>>32011
В том-то и дело, что я один из 25 человек, пилящих ебовешие сервисы на PHP, в багтрекере скоро будет тикет номер 17000. И, сука, у нас конфиг композера размером примерно с этот, а это малюсенький сервис, который просто архивирует сообщения.

>но я тут проблемы не вижу - они жрать не просят


А я - вижу. Когда-то давным-давно у нас первопроходцы натаскали зависимостей, и теперь, несмотря на то, что всё лежит локально, бутстрап лезет на какие-то CDN; выполняешь тикет и меняешь input type="text" на input type="number" и модалка с формой просто перестает открываться, потому что плагин для jQuery ожидает только type="text", сука.
Чужой модуль - это куча чужих багов и хуй знает как написанного кода. Ты экономишь полчаса-час работы, прикручивая васянский модуль, а затем живешь с черными ящиками в своем проекте.
743 1132272
>>32212

Ощущение, что ты просто то ли в композере не разбираешься, то ли еще в чем-то.

> бутстрап лезет на какие-то CDN


При чем тут композер, если бутстрап это JS-код и если он и ставится через менеджер пакетов, то через какой-нибудь bower или yarn. И даже в этом случае он не должен лезить ни на какие CDN.

Просто у вас какой-то инвалид вписал ссылку на CDN и ты теперь винишь в этом композер.

Мог бы исправить, кстати.

> выполняешь тикет и меняешь input type="text" на input type="number" и модалка с формой просто перестает открываться, потому что плагин для jQuery ожидает только type="text"



Это ваши проблемы и композер тут не при чем.

> Чужой модуль - это куча чужих багов и хуй знает как написанного кода.



Не надо ставить все подряд, надо изучить доступные библиотеки и выбрать нормальные.

> Ты экономишь полчаса-час работы, прикручивая васянский модуль, а затем живешь с черными ящиками в своем проекте.


Это несерьезное рассуждение. за сколько часов ты напишешь аналог Доктрины? Или Guzzle?

У нас есть ровно 2 варианта: либо использовать сторонние библиотеки, либо не использовать и писать велосипед. Если мы используем, то либо копируем и ставим все руками, либо перекладываем эту задчу на композер.

В том проекте все зависимости

- Доктрина - для ORM
- migrations - для миграций
- slim, php-view - как фреймворк
- cache - для кеширования
- dom-crawler - для парсинга HTML
- guzzle - как HTTP клиент

И так далее. Расскажи, как обойтись без них и сколько часов ты на этом сэкономишь.

Или вот мой простой скрипт проверки целостности ссылок на сайте: https://github.com/codedokode/pasta-link-checker/blob/master/composer.json - давай, расскажи, без чего тут можно обойтись?
743 1132272
>>32212

Ощущение, что ты просто то ли в композере не разбираешься, то ли еще в чем-то.

> бутстрап лезет на какие-то CDN


При чем тут композер, если бутстрап это JS-код и если он и ставится через менеджер пакетов, то через какой-нибудь bower или yarn. И даже в этом случае он не должен лезить ни на какие CDN.

Просто у вас какой-то инвалид вписал ссылку на CDN и ты теперь винишь в этом композер.

Мог бы исправить, кстати.

> выполняешь тикет и меняешь input type="text" на input type="number" и модалка с формой просто перестает открываться, потому что плагин для jQuery ожидает только type="text"



Это ваши проблемы и композер тут не при чем.

> Чужой модуль - это куча чужих багов и хуй знает как написанного кода.



Не надо ставить все подряд, надо изучить доступные библиотеки и выбрать нормальные.

> Ты экономишь полчаса-час работы, прикручивая васянский модуль, а затем живешь с черными ящиками в своем проекте.


Это несерьезное рассуждение. за сколько часов ты напишешь аналог Доктрины? Или Guzzle?

У нас есть ровно 2 варианта: либо использовать сторонние библиотеки, либо не использовать и писать велосипед. Если мы используем, то либо копируем и ставим все руками, либо перекладываем эту задчу на композер.

В том проекте все зависимости

- Доктрина - для ORM
- migrations - для миграций
- slim, php-view - как фреймворк
- cache - для кеширования
- dom-crawler - для парсинга HTML
- guzzle - как HTTP клиент

И так далее. Расскажи, как обойтись без них и сколько часов ты на этом сэкономишь.

Или вот мой простой скрипт проверки целостности ссылок на сайте: https://github.com/codedokode/pasta-link-checker/blob/master/composer.json - давай, расскажи, без чего тут можно обойтись?
744 1132274
>>32212
я твою позицию понимаю, система разрастается и копит зависимости, а потом ее и еще 25 других встраивают в другую систему и все растет как снежный ком. тревожненько.

но зато
1) RAD
2) я не вижу альтернатив. ты же не будешь писать свои сервисы контейнеров, логгеров, валидаторов и т.д.? а если и будешь, в них будут такие же баги

>первопроходцы натаскали зависимостей


звучит как косяк в архитектуре и кто-то просто не ожидал, что проект выстрелит. ну ничего, так везде

вообще это забавно, т.к. у меня на прошлой работе все было наоборот. почти все компоненты были написаны сотрудниками компании из-за того, что легаси. потом легаси отрефакторили, а сервисы остались собственными. в них везде была какая-то поебень, мешанина подходов и прочее. только сторонние библиотеки доставляли удовольствие при работе с собой
745 1132281
>>32272

>У нас есть ровно 2 варианта: либо использовать сторонние библиотеки, либо не использовать и писать велосипед


Писать велосипед - это с нуля написать свой DOM-парсер, например. А написать вспомогательный класс из 50-100 строк вместо подтягивания какой-то либы - это нормально. Это как глупые ребята, не шарящие в CSS, везде суют reset.css, потому что им стандартные стили говна в жопу залили, а умные ребята знают, как верстать без таких глупостей.

>Доктрина - для ORM


Пишу класс DBSaver с методами saveUser, saveNebo, saveAllah, куда передаю объекты User, Nebo, Allah.

>migrations - для миграций


Не знаю, что это.

>slim, php-view - как фреймворк


Для роутинга пишу правила регулярками и классы, куда должно улетать исполнение при совпадении.

>cache - для кеширования


Что может быть проще, чем файловый кэш? Сохраняешь файл, при запросе чекаешь, есть ли файл и не тухлый ли он.

> dom-crawler - для парсинга HTML


Тебе из коробки даются либы на любой вкус - https://secure.php.net/manual/en/refs.xml.php

> guzzle - как HTTP клиент


file_get_contents отличный http-клиент.
746 1132288
>>31584

Для начала хватит кода на гитхабе. Потому что я в основном смотрю код, а прокликать сайт и проверить что все работает, ты можешь и без меня. Но если будет еще и сайт, то может это пригодится.
747 1132341
>>32272

>вот мой простой скрипт проверки целостности ссылок на сайте: https://github.com/codedokode/pasta-link-checker/blob/master/composer.json - давай, расскажи, без чего тут можно обойтись?


Ну ты дрочишься. Ты прекрасно понимаешь, что мне нужно прочитать и понять весь твой проект, чтобы делать такие заключения.

Давай просто разберем по частям тобой написанное.
Допустим, class Fetcher.

Начнем с того, что я не понимаю, зачем все методы передают друг другу $url, а не хранят его внутри объекта. Почему нельзя создавать инстанс на каждый $url?

$scheme = parse_url($url, PHP_URL_SCHEME);
if ($scheme == 'file') {
return 0;
}

Опа-ча, работаем с урликами, а внутри $url может быть локальный путь. Как так? Урл - это указатель чего-то в сети.

>getDomainForPause


Хм, что это такое и что оно делает

>parse_url($url, PHP_URL_HOST)


Вау, стоило выносить и давать загадочное имя.

Оп-па, у функции pause сайд-эффект - она сохраняет время последнего запроса. Причем она делает это до запроса. Таким образом, $this->interval соблюдаться не будет. Ведь http-реквест может затормозить в любой момент - на открытии сокета, на открытии сокета сервером, на выдаче первого HTTP-заголовка, на выдаче любой порции стрима, где угодно. Реквест может проходить сколько угодно секунд, и сервер может контролировать частоту твоих запросов от закрытия сокета, например. Но вот беда - сокет может держаться и больше дефолтных трез секунд, и в итоге ты сделаешь два последовательных запроса, а юзер твоего кода мог ожидать 3 секунды задержки.

>if ($response->getStatusCode() != 200)


Код 203 равен коду 200, если информация берется из кэша сервера. Я на одном проекте отдаю 203, если предполагаю, что в базе может быть информация актуальнее, но репликация еще не произошла.
Код 300 может быть отдан, если страница либо файл доступны в разных форматах.
А еще можно получить 101, если сайт хочет работать только по HTTP/2.
Во всех этих случаях юзер получает сайт, ничего не подозревая, а у тебя - ошибка.

>$response->getStatusCode() >= 300 &&


$response->getStatusCode() < 400 &&
$response->hasHeader('Location')
У нас код 300 и Location. Нас хотят перенаправить? Не обязательно. Файл либо страница доступны в разных форматах, и юзер волен выбрать, в каком он хочет получить. При этом Location определяет дефолтный выбор, куда браузер может, но не обязан перейти.
Для юзера это будет абсолютно обычная страница, как код 200.

Вообще, очень странно, что функция fetchUrl заодно выносит какие-то вердикты и просто не возвращает $response. Любые вынесения вердиктов стоит делать методами в классе ResponseMetadata.

if (!$type) {
$errorText = "No Content-Type";
Сервер не обязан отсылать Content-Type. Если его нет, браузер угадывает его по сигнатуре первых байтов.

if (!preg_match("#^text/html#i", $type)) {
$errorText = "Content-Type invalid: $type";
application/xhtml+xml, application/xml и text/plain грустят.
text/vnd.wap.wml и не надеется, что про него вспомнят некоторые олдфаги.

Преимуществ guzzle не увидел. Мало того, если ты спустишься на уровень сокетов, сможешь просто закрывать его после получения заголовков через GET. Будет тот же HEAD, только без возможных 405.
747 1132341
>>32272

>вот мой простой скрипт проверки целостности ссылок на сайте: https://github.com/codedokode/pasta-link-checker/blob/master/composer.json - давай, расскажи, без чего тут можно обойтись?


Ну ты дрочишься. Ты прекрасно понимаешь, что мне нужно прочитать и понять весь твой проект, чтобы делать такие заключения.

Давай просто разберем по частям тобой написанное.
Допустим, class Fetcher.

Начнем с того, что я не понимаю, зачем все методы передают друг другу $url, а не хранят его внутри объекта. Почему нельзя создавать инстанс на каждый $url?

$scheme = parse_url($url, PHP_URL_SCHEME);
if ($scheme == 'file') {
return 0;
}

Опа-ча, работаем с урликами, а внутри $url может быть локальный путь. Как так? Урл - это указатель чего-то в сети.

>getDomainForPause


Хм, что это такое и что оно делает

>parse_url($url, PHP_URL_HOST)


Вау, стоило выносить и давать загадочное имя.

Оп-па, у функции pause сайд-эффект - она сохраняет время последнего запроса. Причем она делает это до запроса. Таким образом, $this->interval соблюдаться не будет. Ведь http-реквест может затормозить в любой момент - на открытии сокета, на открытии сокета сервером, на выдаче первого HTTP-заголовка, на выдаче любой порции стрима, где угодно. Реквест может проходить сколько угодно секунд, и сервер может контролировать частоту твоих запросов от закрытия сокета, например. Но вот беда - сокет может держаться и больше дефолтных трез секунд, и в итоге ты сделаешь два последовательных запроса, а юзер твоего кода мог ожидать 3 секунды задержки.

>if ($response->getStatusCode() != 200)


Код 203 равен коду 200, если информация берется из кэша сервера. Я на одном проекте отдаю 203, если предполагаю, что в базе может быть информация актуальнее, но репликация еще не произошла.
Код 300 может быть отдан, если страница либо файл доступны в разных форматах.
А еще можно получить 101, если сайт хочет работать только по HTTP/2.
Во всех этих случаях юзер получает сайт, ничего не подозревая, а у тебя - ошибка.

>$response->getStatusCode() >= 300 &&


$response->getStatusCode() < 400 &&
$response->hasHeader('Location')
У нас код 300 и Location. Нас хотят перенаправить? Не обязательно. Файл либо страница доступны в разных форматах, и юзер волен выбрать, в каком он хочет получить. При этом Location определяет дефолтный выбор, куда браузер может, но не обязан перейти.
Для юзера это будет абсолютно обычная страница, как код 200.

Вообще, очень странно, что функция fetchUrl заодно выносит какие-то вердикты и просто не возвращает $response. Любые вынесения вердиктов стоит делать методами в классе ResponseMetadata.

if (!$type) {
$errorText = "No Content-Type";
Сервер не обязан отсылать Content-Type. Если его нет, браузер угадывает его по сигнатуре первых байтов.

if (!preg_match("#^text/html#i", $type)) {
$errorText = "Content-Type invalid: $type";
application/xhtml+xml, application/xml и text/plain грустят.
text/vnd.wap.wml и не надеется, что про него вспомнят некоторые олдфаги.

Преимуществ guzzle не увидел. Мало того, если ты спустишься на уровень сокетов, сможешь просто закрывать его после получения заголовков через GET. Будет тот же HEAD, только без возможных 405.
748 1132342
>>32341
Ну и про черные ящики. Вот ты предполагаешь, что Grunt вернет тебе Content-Type так, что строка будет начинаться с text/...
А что будет, если сервер поставит два пробела между двоеточием и значением? Это валидный заголовок. У тебя будет первый пробел? Или не будет? Ты не можешь ответить на этот вопрос. Это не твой код.
Не понятно.mp46,4 Мб, mp4,
1280x720, 0:44
749 1132364

>основная функция spellNumber(), которая принимает на вход большое число, разбивает его на части по 3 цифры и вызывая указанные выше функции, получает число прописью.


И как мне это сделать, если

>Некоторые делают ошибку, пытаясь работать с числами строковыми функциями вроде mb_substr() или mb_strlen(). Это неправильно.



Тогда как мне

>разбивает его на части по 3 цифры



Нужно число делить на 10, сотни и тысячи для того, чтобы разделить?
750 1132381
>>32364
Так, я придумал.
Сперва поделить число на десятки миллионов, если делится, то задать переменной то количество десятков и форму слова миллион\ов\а.
Потом взять остаток и его уже делить на миллионы. Повторить то же, что и с десятками.
Проделывать так до единиц.
Потом вывести эти переменные.
751 1132459
>>32341

Ну проект довольно маленький, и он на ООП, так что не требуется его целиком изучать, можно смотреть отдельный класс. И да, он не идеальный, так как написан по сути (видно по коммитам) в 2 присеста и мне надо было получить что-то работабщее побыстрее. И я получил - теперь я могу получить список "сомнительных", потенциально сломанных или изменившихся ссылок для ручной перепроверки, не обходя все свои уроки вручную. Разве это не прекрасно?

Также, я думал использовать эту проверялку через Travis (CI сервис), чтобы при каждом коммите Travis бы скачивал мой репозиторий с уроками или сайтом, скачивал проверяльщик, проверял все ссылки, и я бы мог видеть по значку в ридми, что появились сломанные ссылки. И да, у меня еще есть (пока очень сырой и требующий работы) набор скриптов для проверки правописания через hunspell.

> Начнем с того, что я не понимаю, зачем все методы передают друг другу $url, а не хранят его внутри объекта. Почему нельзя создавать инстанс на каждый $url?



Потому, что Fetcher - это сервис, который может сделать много запросов. Не вижу, в чем мне выгода на каждый запрос создавать новый Fetcher. Более того, у него есть состояние - он запоминает время последней отправки запроса к каждому домену, чтобы не делать запросы к одному домену чаще, чем раз в 3 секунды.

И кстати, я там в checker.php прикрутил костылек, чтобы делать сначала запросы к доменам, которые с меньшей вероятностью заблокируются. Хотя, конечно, самое правильное решение было бы сделать параллельный запрашиватель файлов, но это бы потребовало намного больше времени на написание и отладку (хотя в Guzzle вроде что-то такое есть, может когда-нибудь гляну).

И заметь, я еще стараюсь по возможности делать HEAD, если он поддерживается сервером и если мне не нужно тело запроса. И умею перепрыгивать на GET, если сервер отказывается выполнять этот метод.

Вот реальная проблема, которую я пока не исправил - это отстутствие четкого разделения обязанностей между Fetcher и LinkChecker, это да.

> Опа-ча, работаем с урликами, а внутри $url может быть локальный путь. Как так? Урл - это указатель чего-то в сети.


Вообще, нет https://ru.wikipedia.org/wiki/URL#Схемы_(протоколы)_URL

> file — Имя локального файла


> tel — звонок по указанному телефону (хотя, тут может правильнее было бы использовать URN)


> data — Непосредственные данные (Data: URL)



Поддержка file пока не готова, но планируется на будущее, чтобы можно было проверять ссылки в папке с HTML файлами. Удобно же.

>>getDomainForPause


> Хм, что это такое и что оно делает


Наверно неудачно названо и не хватает комментария. Определяет ключ, по которому проверяется частота запросов. Может быть, я захочу завтра ограничивать частоту запросов не по всему домену, а по домену 2-го уровня.

> Оп-па, у функции pause сайд-эффект - она сохраняет время последнего запроса.


В этом ее предназначение - сделать паузу необходимой длины перед отправкой запроса.

> Но вот беда - сокет может держаться и больше дефолтных трез секунд, и в итоге ты сделаешь два последовательных запроса, а юзер твоего кода мог ожидать 3 секунды задержки.


interval это интервал, чаще которого нельзя посылать запросы к одному домену.

> Код 203 равен коду 200, если информация берется из кэша сервера


Не исключаю, что мой код не идеален. Однако, я не сталкивался пока с кодом 203, и никто мне не писал про этов Issues - значит, пока можно не тратить время на решение этой проблемы. Однако, записал твою идею в TODO.

Я тебе могу рассказать про более интересную проблему - обнаружение припаркованных (то есть потерянных или проданных владельцем) доменов. Эти домены отдают 200 на любой URL, но естественно, не содержат никакой полезной информации, а лишь список рекламных ссылок. Пример ww1.verginmobile.com

Другая проблема - некоторые домены не любят ботов (а я честно подписываю User-Agent) и отдают им ответ 403 или редиректят на localhost (я не шучу). Видимо, придется как-то вручную сделать исключения по доменам. Не знаю, как это лучше оформить, чтобы не хардкодить.

Третья проблема - проверка ссылок вроде mega.nz/#12345 (хеш там проверяется JS-кодом, даже если файлы недоступны, отдается 200) или rghost.net/12345 (если файл удален, он все равно отдает страницу 200). Опять же, наверно, нужны исключения на основе домена.

Сейчас эти проблемы актуальнее, чем экзотичные коды ответа.

> А еще можно получить 101, если сайт хочет работать только по HTTP/2.


Надеюсь, что Гузл это сам обработает, так как код 1xx - это информационный код, который не завершает HTTP запрос, как я помню, и за ним придет настоящий код. Если нет, то просматривая список ошибок, я увижу проблему и исправлю код.

> У нас код 300 и Location. Нас хотят перенаправить? Не обязательно.


Странно, мне кажется, что обязательно. Но я, конечно, так тщательно спеку HTTP не читал. Можешь дать пример страницы, где есть 3xx но это не редирект?

Ну и как я понимаю, большинство браузеров отредиректит пользователя, значит, ссылка у меня в статье неправильная. Может, конечно, надо различать виды редиректов, 301 от других, но по факту на сайте может быть криво настроен код, и мой скрипт должен работать в этом неидеальном мире.

> Вообще, очень странно, что функция fetchUrl заодно выносит какие-то вердикты и просто не возвращает $response. Любые вынесения вердиктов стоит делать методами в классе ResponseMetadata.



Я думал, но тогда нам придется просто засунуть туда целиком содержимое Response, а он еще и не сериализируемый и в кеш не пойдет. Я подумал, что проще будет переименовать его в CheckResult.

> Сервер не обязан отсылать Content-Type. Если его нет, браузер угадывает его по сигнатуре первых байтов.


Не уверен. Знаю, что так любил делать ИЕ (content sniffing) и это приводило к уязвимостям. У тебя есть ссылка по теме?

> application/xhtml+xml, application/xml и text/plain грустят.


ты бы мог еще добавить, что в статье может стоять ссылка на картинку или PDF. да, это написано в TODO. Тут еще сложность, что мне надо как-то отличать технические страницы с ошибкой от нормальных.

> Преимуществ guzzle не увидел.


Мне не пришлось писать свой HTTP клиент, объекты для представления HTTP запросов и ответов. Не пришлось изучать кучу тонкостей, про которые ты написал (про 203 я например не знал), это уже скорее всего сделано за меня. Если это сделано - прекрасно, я сэкономил время. Если нет - то в любом случае, и со сторонней библиотекой, и со своей, придется тратить время на решение.

Чтобы делать запросы, нам в любом случае нужен HTTP клиент. Кто-то должен его написать, отладить, протестировать (а тесты тоже требуют немало времени), задокументировать, поддерживать, исправлять баги. При использовании сторонней библиотеки делать это придется не мне, я экономлю время.

Или по твоему, каждый разработчик в мире должен писать свою версию HTTP клиента? Или может, лучше просто взять библиотеку и исправить, если в ней чего-то не хватает? Так все сообщество будет в выгоде, получив твои исправления.

Ты не забывай, что приоритеты могут быть разными. Часто программисты пытаются оптимизировать код по каким-то техническим критериям: время работы, потребление памяти, уровень соответствия спецификации, покрытие тестами, субъективное восприятие качества кода. Но если это не учебный код, часто надо учитывать еще и бизнес-факторы (время/деньги). Ну например, бизнес может предпочесть получить код, потребляющий 1 Гб памяти и написанный за час коду, который потребляет 100 Мб, но требует 20 часов на написание. И даже если проект некоммерческий, бизнес-критерии к нему применимы, так как ты тратишь на него свое время и время доровоьцев, которое ограничено. То есть опен сурс живет по тем же экономическим законам.

Для меня это всего лишь вспомогательный инструмент, задача у меня уменьшить количество битых ссылок. В идеале до нуля, но не обязательно.
751 1132459
>>32341

Ну проект довольно маленький, и он на ООП, так что не требуется его целиком изучать, можно смотреть отдельный класс. И да, он не идеальный, так как написан по сути (видно по коммитам) в 2 присеста и мне надо было получить что-то работабщее побыстрее. И я получил - теперь я могу получить список "сомнительных", потенциально сломанных или изменившихся ссылок для ручной перепроверки, не обходя все свои уроки вручную. Разве это не прекрасно?

Также, я думал использовать эту проверялку через Travis (CI сервис), чтобы при каждом коммите Travis бы скачивал мой репозиторий с уроками или сайтом, скачивал проверяльщик, проверял все ссылки, и я бы мог видеть по значку в ридми, что появились сломанные ссылки. И да, у меня еще есть (пока очень сырой и требующий работы) набор скриптов для проверки правописания через hunspell.

> Начнем с того, что я не понимаю, зачем все методы передают друг другу $url, а не хранят его внутри объекта. Почему нельзя создавать инстанс на каждый $url?



Потому, что Fetcher - это сервис, который может сделать много запросов. Не вижу, в чем мне выгода на каждый запрос создавать новый Fetcher. Более того, у него есть состояние - он запоминает время последней отправки запроса к каждому домену, чтобы не делать запросы к одному домену чаще, чем раз в 3 секунды.

И кстати, я там в checker.php прикрутил костылек, чтобы делать сначала запросы к доменам, которые с меньшей вероятностью заблокируются. Хотя, конечно, самое правильное решение было бы сделать параллельный запрашиватель файлов, но это бы потребовало намного больше времени на написание и отладку (хотя в Guzzle вроде что-то такое есть, может когда-нибудь гляну).

И заметь, я еще стараюсь по возможности делать HEAD, если он поддерживается сервером и если мне не нужно тело запроса. И умею перепрыгивать на GET, если сервер отказывается выполнять этот метод.

Вот реальная проблема, которую я пока не исправил - это отстутствие четкого разделения обязанностей между Fetcher и LinkChecker, это да.

> Опа-ча, работаем с урликами, а внутри $url может быть локальный путь. Как так? Урл - это указатель чего-то в сети.


Вообще, нет https://ru.wikipedia.org/wiki/URL#Схемы_(протоколы)_URL

> file — Имя локального файла


> tel — звонок по указанному телефону (хотя, тут может правильнее было бы использовать URN)


> data — Непосредственные данные (Data: URL)



Поддержка file пока не готова, но планируется на будущее, чтобы можно было проверять ссылки в папке с HTML файлами. Удобно же.

>>getDomainForPause


> Хм, что это такое и что оно делает


Наверно неудачно названо и не хватает комментария. Определяет ключ, по которому проверяется частота запросов. Может быть, я захочу завтра ограничивать частоту запросов не по всему домену, а по домену 2-го уровня.

> Оп-па, у функции pause сайд-эффект - она сохраняет время последнего запроса.


В этом ее предназначение - сделать паузу необходимой длины перед отправкой запроса.

> Но вот беда - сокет может держаться и больше дефолтных трез секунд, и в итоге ты сделаешь два последовательных запроса, а юзер твоего кода мог ожидать 3 секунды задержки.


interval это интервал, чаще которого нельзя посылать запросы к одному домену.

> Код 203 равен коду 200, если информация берется из кэша сервера


Не исключаю, что мой код не идеален. Однако, я не сталкивался пока с кодом 203, и никто мне не писал про этов Issues - значит, пока можно не тратить время на решение этой проблемы. Однако, записал твою идею в TODO.

Я тебе могу рассказать про более интересную проблему - обнаружение припаркованных (то есть потерянных или проданных владельцем) доменов. Эти домены отдают 200 на любой URL, но естественно, не содержат никакой полезной информации, а лишь список рекламных ссылок. Пример ww1.verginmobile.com

Другая проблема - некоторые домены не любят ботов (а я честно подписываю User-Agent) и отдают им ответ 403 или редиректят на localhost (я не шучу). Видимо, придется как-то вручную сделать исключения по доменам. Не знаю, как это лучше оформить, чтобы не хардкодить.

Третья проблема - проверка ссылок вроде mega.nz/#12345 (хеш там проверяется JS-кодом, даже если файлы недоступны, отдается 200) или rghost.net/12345 (если файл удален, он все равно отдает страницу 200). Опять же, наверно, нужны исключения на основе домена.

Сейчас эти проблемы актуальнее, чем экзотичные коды ответа.

> А еще можно получить 101, если сайт хочет работать только по HTTP/2.


Надеюсь, что Гузл это сам обработает, так как код 1xx - это информационный код, который не завершает HTTP запрос, как я помню, и за ним придет настоящий код. Если нет, то просматривая список ошибок, я увижу проблему и исправлю код.

> У нас код 300 и Location. Нас хотят перенаправить? Не обязательно.


Странно, мне кажется, что обязательно. Но я, конечно, так тщательно спеку HTTP не читал. Можешь дать пример страницы, где есть 3xx но это не редирект?

Ну и как я понимаю, большинство браузеров отредиректит пользователя, значит, ссылка у меня в статье неправильная. Может, конечно, надо различать виды редиректов, 301 от других, но по факту на сайте может быть криво настроен код, и мой скрипт должен работать в этом неидеальном мире.

> Вообще, очень странно, что функция fetchUrl заодно выносит какие-то вердикты и просто не возвращает $response. Любые вынесения вердиктов стоит делать методами в классе ResponseMetadata.



Я думал, но тогда нам придется просто засунуть туда целиком содержимое Response, а он еще и не сериализируемый и в кеш не пойдет. Я подумал, что проще будет переименовать его в CheckResult.

> Сервер не обязан отсылать Content-Type. Если его нет, браузер угадывает его по сигнатуре первых байтов.


Не уверен. Знаю, что так любил делать ИЕ (content sniffing) и это приводило к уязвимостям. У тебя есть ссылка по теме?

> application/xhtml+xml, application/xml и text/plain грустят.


ты бы мог еще добавить, что в статье может стоять ссылка на картинку или PDF. да, это написано в TODO. Тут еще сложность, что мне надо как-то отличать технические страницы с ошибкой от нормальных.

> Преимуществ guzzle не увидел.


Мне не пришлось писать свой HTTP клиент, объекты для представления HTTP запросов и ответов. Не пришлось изучать кучу тонкостей, про которые ты написал (про 203 я например не знал), это уже скорее всего сделано за меня. Если это сделано - прекрасно, я сэкономил время. Если нет - то в любом случае, и со сторонней библиотекой, и со своей, придется тратить время на решение.

Чтобы делать запросы, нам в любом случае нужен HTTP клиент. Кто-то должен его написать, отладить, протестировать (а тесты тоже требуют немало времени), задокументировать, поддерживать, исправлять баги. При использовании сторонней библиотеки делать это придется не мне, я экономлю время.

Или по твоему, каждый разработчик в мире должен писать свою версию HTTP клиента? Или может, лучше просто взять библиотеку и исправить, если в ней чего-то не хватает? Так все сообщество будет в выгоде, получив твои исправления.

Ты не забывай, что приоритеты могут быть разными. Часто программисты пытаются оптимизировать код по каким-то техническим критериям: время работы, потребление памяти, уровень соответствия спецификации, покрытие тестами, субъективное восприятие качества кода. Но если это не учебный код, часто надо учитывать еще и бизнес-факторы (время/деньги). Ну например, бизнес может предпочесть получить код, потребляющий 1 Гб памяти и написанный за час коду, который потребляет 100 Мб, но требует 20 часов на написание. И даже если проект некоммерческий, бизнес-критерии к нему применимы, так как ты тратишь на него свое время и время доровоьцев, которое ограничено. То есть опен сурс живет по тем же экономическим законам.

Для меня это всего лишь вспомогательный инструмент, задача у меня уменьшить количество битых ссылок. В идеале до нуля, но не обязательно.
752 1132460
>>32341

Для меня это всего лишь вспомогательный инструмент, задача у меня уменьшить количество битых ссылок. В идеале до нуля, но не обязательно.

> Мало того, если ты спустишься на уровень сокетов, сможешь просто закрывать его после получения заголовков через GET. Будет тот же HEAD, только без возможных 405.


Это костыльно и недружелюбно по отношению к серверу, зачем его заставлять генерировать ответ, который мне не нужен? Ну и я подозреваю, что в Guzzle это тоже возможно (ограничивать размер ответа 0 байтами).

- тут для Guzzle 6 https://stackoverflow.com/questions/26507081/limit-the-request-size-when-using-guzzle-goutte
- также можно костылем передать нужные опции для curl

Я кстати, когда-то давно тоже страдал изобретением велосипедов, но, к счастью, много времени на это потратить не успел.

Но вообще, спасибо за подробный пост, я даже узнал что-то новое для себя. Не так часто такое бывает. Заходи почаще в наш тред, у нас есть и сложные задачки (как тебе задача на SPA из Оп поста?), может тебе интересно будет что-то поделать.

>>32342

Я с таким не сталкивался. Если такое произойдет, то я увижу ошибку, начну разбирать ее и либо 1) найду баг в своем коде и исправлю 2) пойму что проблема на сервере и сделаю костыль дял нее 3) пойму что проблема в сторонней библиотеке, зарепорчу баг, и пока у себя сделаю костыль для исправления.

Я ведь точно так же и в своем коде не предусмотрю все возможные ситуации. да и я не хочу писать свой клиент, параллельно разгребая 100-страничный RFC.

>>32364

Работать через строки неудобно. PHP может иногда преобразовать большие числа к виду "1.23456e10" (подробнее: https://ru.wikipedia.org/wiki/Экспоненциальная_запись#Компьютерный_способ_экспоненциальной_записи ) и строчные функции тут тебя подведут.

Используй математику. Есть 2 функции для разделения чисел на части, $x % 1000 - берет 3 последние цифры, floor($x / 1000) - отбрасывает 3 последние цифры.
752 1132460
>>32341

Для меня это всего лишь вспомогательный инструмент, задача у меня уменьшить количество битых ссылок. В идеале до нуля, но не обязательно.

> Мало того, если ты спустишься на уровень сокетов, сможешь просто закрывать его после получения заголовков через GET. Будет тот же HEAD, только без возможных 405.


Это костыльно и недружелюбно по отношению к серверу, зачем его заставлять генерировать ответ, который мне не нужен? Ну и я подозреваю, что в Guzzle это тоже возможно (ограничивать размер ответа 0 байтами).

- тут для Guzzle 6 https://stackoverflow.com/questions/26507081/limit-the-request-size-when-using-guzzle-goutte
- также можно костылем передать нужные опции для curl

Я кстати, когда-то давно тоже страдал изобретением велосипедов, но, к счастью, много времени на это потратить не успел.

Но вообще, спасибо за подробный пост, я даже узнал что-то новое для себя. Не так часто такое бывает. Заходи почаще в наш тред, у нас есть и сложные задачки (как тебе задача на SPA из Оп поста?), может тебе интересно будет что-то поделать.

>>32342

Я с таким не сталкивался. Если такое произойдет, то я увижу ошибку, начну разбирать ее и либо 1) найду баг в своем коде и исправлю 2) пойму что проблема на сервере и сделаю костыль дял нее 3) пойму что проблема в сторонней библиотеке, зарепорчу баг, и пока у себя сделаю костыль для исправления.

Я ведь точно так же и в своем коде не предусмотрю все возможные ситуации. да и я не хочу писать свой клиент, параллельно разгребая 100-страничный RFC.

>>32364

Работать через строки неудобно. PHP может иногда преобразовать большие числа к виду "1.23456e10" (подробнее: https://ru.wikipedia.org/wiki/Экспоненциальная_запись#Компьютерный_способ_экспоненциальной_записи ) и строчные функции тут тебя подведут.

Используй математику. Есть 2 функции для разделения чисел на части, $x % 1000 - берет 3 последние цифры, floor($x / 1000) - отбрасывает 3 последние цифры.
753 1132462
>>32281

Ты бы изучил рассматриваемые библиотеки получше. Может и тебе пригодятся ;)

> Это как глупые ребята, не шарящие в CSS, везде суют reset.css


Это плохой подход, сбросить все стили, а потом переопределять их заново или получить текст без абзацев.

> Пишу класс DBSaver с методами saveUser, saveNebo, saveAllah, к


В Доктрине намного больше. Там еще есть загрузка объектов из БД, ленивая загрузка, поддержка отношений (ну-ка, напиши-ка), автоматический поиск изменений в объектах и тд. Это все экономит время.

>>migrations - для миграций


> Не знаю, что это.



Миграции позволяют фиксировать в репозитории изменения в структуре БД, привязывать их к коммитам, воссоздавать структуру БД в любой точке истории, позволяют обновлять структуру БД без потери данных в ней, передавать эту информацию другим разработчикам. Иногда позволяют выражать изменения структуры БД не на SQL, чем достигается поддержка нескольких СУБД. А как ты в своих проектах обновляешь структуру БД? Вот понадобилось тебе например таблицу добавить, или поле, или индекс?

Я обычно пишу миграции руками на SQL, но некоторые любят сначала поменять схему БД вручную и потом сгенерировать миграицию из разницы схем новой и старой версии.

http://docs.doctrine-project.org/projects/doctrine-migrations/en/latest/toc.html

> Для роутинга пишу правила регулярками и классы, куда должно улетать исполнение при совпадении.



Изобретаешь велосипед. Symfony Routing например умеет генерировать из удобного читабельного YAML конфига (который читать проще чем твой код) код с регулярками ради оптимизации: https://symfony.com/doc/current/routing.html

Попробуй, только советую не использовать аннотации, а использовать YAML.

> Что может быть проще, чем файловый кэш? Сохраняешь файл, при запросе чекаешь, есть ли файл и не тухлый ли он.


Так я это и делаю, только не пишу этот код сам. И получаю кучу готовых видов кешей, могу кеширвоать данные вообще куда угодно, хоть в шареную память.

> Тебе из коробки даются либы на любой вкус - https://secure.php.net/manual/en/refs.xml.php


Они очень неудобные и не поддерживают CSS синтаксис (а в XSLT искать классы неудобно и громоздко).

> file_get_contents отличный http-клиент.


Нет, чтобы получить просто заголовки, тебе придется писать код, чтобы добавить таймаут, еще какой-то код и так далее.

И кстати, я использую из Гуззла еще URL resolver - он умеет делать так: http://example.com/a/b + ../file.txt = http://example.com/file.txt . На сайтах ведь встречаются относительные ссылки. Ты его тоже предлагаешь самому писать?

В любом случае, кто-то должен написать, протестировать, поддерживать библиоетку - либо ты, либо сообщество. Не вижу в чем выгода тратить время на переизобретение того, что уже написано. И что я теряю, используя готовую библиотеку.

Тот проект (phpclub.tech) пишу не я, а аноны сами организовались и пишут. У них есть много своих дел, работа, учеба, и тд. Вряд ли они могут себе позволить тратить время на переизобретение ORM или HTTP клиента.
753 1132462
>>32281

Ты бы изучил рассматриваемые библиотеки получше. Может и тебе пригодятся ;)

> Это как глупые ребята, не шарящие в CSS, везде суют reset.css


Это плохой подход, сбросить все стили, а потом переопределять их заново или получить текст без абзацев.

> Пишу класс DBSaver с методами saveUser, saveNebo, saveAllah, к


В Доктрине намного больше. Там еще есть загрузка объектов из БД, ленивая загрузка, поддержка отношений (ну-ка, напиши-ка), автоматический поиск изменений в объектах и тд. Это все экономит время.

>>migrations - для миграций


> Не знаю, что это.



Миграции позволяют фиксировать в репозитории изменения в структуре БД, привязывать их к коммитам, воссоздавать структуру БД в любой точке истории, позволяют обновлять структуру БД без потери данных в ней, передавать эту информацию другим разработчикам. Иногда позволяют выражать изменения структуры БД не на SQL, чем достигается поддержка нескольких СУБД. А как ты в своих проектах обновляешь структуру БД? Вот понадобилось тебе например таблицу добавить, или поле, или индекс?

Я обычно пишу миграции руками на SQL, но некоторые любят сначала поменять схему БД вручную и потом сгенерировать миграицию из разницы схем новой и старой версии.

http://docs.doctrine-project.org/projects/doctrine-migrations/en/latest/toc.html

> Для роутинга пишу правила регулярками и классы, куда должно улетать исполнение при совпадении.



Изобретаешь велосипед. Symfony Routing например умеет генерировать из удобного читабельного YAML конфига (который читать проще чем твой код) код с регулярками ради оптимизации: https://symfony.com/doc/current/routing.html

Попробуй, только советую не использовать аннотации, а использовать YAML.

> Что может быть проще, чем файловый кэш? Сохраняешь файл, при запросе чекаешь, есть ли файл и не тухлый ли он.


Так я это и делаю, только не пишу этот код сам. И получаю кучу готовых видов кешей, могу кеширвоать данные вообще куда угодно, хоть в шареную память.

> Тебе из коробки даются либы на любой вкус - https://secure.php.net/manual/en/refs.xml.php


Они очень неудобные и не поддерживают CSS синтаксис (а в XSLT искать классы неудобно и громоздко).

> file_get_contents отличный http-клиент.


Нет, чтобы получить просто заголовки, тебе придется писать код, чтобы добавить таймаут, еще какой-то код и так далее.

И кстати, я использую из Гуззла еще URL resolver - он умеет делать так: http://example.com/a/b + ../file.txt = http://example.com/file.txt . На сайтах ведь встречаются относительные ссылки. Ты его тоже предлагаешь самому писать?

В любом случае, кто-то должен написать, протестировать, поддерживать библиоетку - либо ты, либо сообщество. Не вижу в чем выгода тратить время на переизобретение того, что уже написано. И что я теряю, используя готовую библиотеку.

Тот проект (phpclub.tech) пишу не я, а аноны сами организовались и пишут. У них есть много своих дел, работа, учеба, и тд. Вряд ли они могут себе позволить тратить время на переизобретение ORM или HTTP клиента.
754 1132463
>>31957

К хорошему быстро привыкаешь. Я когда начну писать простой скрипт (тот же проект для проверки битых ссылок), обнаруживаю, что мне нужны сторонние библиотеки. С ними все проще. Ну вот даже если открыть https://github.com/codedokode/pasta-link-checker/blob/master/checker.php:

- CacertBundle дает мне файл cacert.pem для проверки HTTPS-сертификатов. А как же иначе, без корневого набора сертификатов ты HTTPS корректно выполнять не сможешь, и в той же винде например у PHP этих корневых сертификатов нет, использовать системные он видимо не умеет. В линуксе дела получше, но тоже наверно зависит от репозитория, так что проще исопльзовать готовое решение.

- ConsoleOutput и ConsoleLogger из symfony/console дают мне готовый PSR-логгер. Я могу легко перенаправить сообщения куда хочу и переключать подробный/краткий вывод логов.

- new InputDefinition из компонента symfony/console дает мне средство для разбора аргументов из $argv, а также умеет генерировать help по ним. Я знаю про getopt, он ужасен и сквозит своей сишной сущностью.

- guzzle делает HTTP запросы, и вроде как даже умеет параллельность, если не умеет, я могу взять клиент из ReactPHP

- FilesystemCache отвечает за кеширование с проверкой времени, и умеет очищать кеш. Это не очень долго писать, но ведь потом захочется сделать тесты, добавить какие-то фичи, и тд, и куча времени уйдет.

- symfony/dom-crawler и symfony/css-selector не идеальны, но парсить ими HTML удобнее, чем встроенным в PHP XML-расширением. Чего там стоит возня с настройкой кодировки или перехват ошибок.

Каждая зависимость в моем проекте обоснована и добавлена на основе взвешивания ее преимуществ/недостатков.

Ты наверно и шаблонизаторы не используешь? Зря, советую тебе изучить библиотеки, которые использовал я и аноны из phpclub, и они тебе не раз пригодятся. Я всегда готов что-то по ним подсказать и поделиться опытом.

Вот ты там выше анону написал про кучу тонкостей работы с HTTP, но ведь многое из этого, если не все, уже решено в Гуззле.

>>31930

Что сложного в пагинации тредов? Берешь таблицу тредов и делаешь SELECT ... FROM threads ORDER BY bump_date DESC LIMIT :x OFFSET :y. Если тредов не тысячи, это будет быстро работать.

>>31896

Тут стоит просто поставить себе образец Symfony приложения (например https://github.com/symfony/demo/ ) и смотреть код, начиная с public/index.php.

Там происходит все примерно так:

- инициализируем автозагрузку
- создаем объект класса Kernel (я думаю, это будет App\Kernel: https://github.com/symfony/demo/blob/master/src/Kernel.php ). Его задача - инициализация фреймворка, загрузка DI контейнера, бандлов, разбор конфигов.
- инициализируем DI контейнер
- загружаем все бандлы (они тоже объекты), инициализиурем их, они читают свои конфиги и настриваются, ставят обработчики разных событий. Этот этап зверски оптимизирован и использует кеш, чтобы не делать это на каждом запросе, но пока на кеш можно не смотреть. В Симфони есть несколько встроенных бандлов (увидеть их список можно в AppKernel), и тебе придется посмотреть их код тоже.
- создаем Request, передаем его Kernel для обработки
- создаем по моему HttpKernel и заходим в цикл обработки запроса: https://symfony.com/doc/current/components/http_kernel.html
- на всех этапах работы HttpKernel в процесс вмешиваются бандлы, и что-то делают свое. Роутер например разбирает URL запроса и ищет соответствие ему в конфиге роутинга, фаерволл проверяет права доступа
- затем Httpkernel определяет текущий контроллер и запускает его
- контроллер получает на вход Request и должен вернуть Response (HTTP-ответ с телом страницы внутри)
- HttpKernel отдает Response юзеру

Также, прочитай про структуру приложения, что такое бандлы (расширения к ядру фреймворка, которые могут добавлять свои сервисы, роуты, обработчики событий и тд).

Также, есть подвохи: например, ты там не найдешь прямого вызова роутера для разбора URL или вызова фаерволла, который проверяет права доступа. Бандл с роутером просто в своем конфиге прописывает вызор роутера перед обработкой запроса HttpKernel, роутер разбирает URL и добавляет результаты разбора назад в объект запроса. Это специально так сделано, чтобы банглы могли менять процесс обработки запроса и отдачи ответа.
754 1132463
>>31957

К хорошему быстро привыкаешь. Я когда начну писать простой скрипт (тот же проект для проверки битых ссылок), обнаруживаю, что мне нужны сторонние библиотеки. С ними все проще. Ну вот даже если открыть https://github.com/codedokode/pasta-link-checker/blob/master/checker.php:

- CacertBundle дает мне файл cacert.pem для проверки HTTPS-сертификатов. А как же иначе, без корневого набора сертификатов ты HTTPS корректно выполнять не сможешь, и в той же винде например у PHP этих корневых сертификатов нет, использовать системные он видимо не умеет. В линуксе дела получше, но тоже наверно зависит от репозитория, так что проще исопльзовать готовое решение.

- ConsoleOutput и ConsoleLogger из symfony/console дают мне готовый PSR-логгер. Я могу легко перенаправить сообщения куда хочу и переключать подробный/краткий вывод логов.

- new InputDefinition из компонента symfony/console дает мне средство для разбора аргументов из $argv, а также умеет генерировать help по ним. Я знаю про getopt, он ужасен и сквозит своей сишной сущностью.

- guzzle делает HTTP запросы, и вроде как даже умеет параллельность, если не умеет, я могу взять клиент из ReactPHP

- FilesystemCache отвечает за кеширование с проверкой времени, и умеет очищать кеш. Это не очень долго писать, но ведь потом захочется сделать тесты, добавить какие-то фичи, и тд, и куча времени уйдет.

- symfony/dom-crawler и symfony/css-selector не идеальны, но парсить ими HTML удобнее, чем встроенным в PHP XML-расширением. Чего там стоит возня с настройкой кодировки или перехват ошибок.

Каждая зависимость в моем проекте обоснована и добавлена на основе взвешивания ее преимуществ/недостатков.

Ты наверно и шаблонизаторы не используешь? Зря, советую тебе изучить библиотеки, которые использовал я и аноны из phpclub, и они тебе не раз пригодятся. Я всегда готов что-то по ним подсказать и поделиться опытом.

Вот ты там выше анону написал про кучу тонкостей работы с HTTP, но ведь многое из этого, если не все, уже решено в Гуззле.

>>31930

Что сложного в пагинации тредов? Берешь таблицу тредов и делаешь SELECT ... FROM threads ORDER BY bump_date DESC LIMIT :x OFFSET :y. Если тредов не тысячи, это будет быстро работать.

>>31896

Тут стоит просто поставить себе образец Symfony приложения (например https://github.com/symfony/demo/ ) и смотреть код, начиная с public/index.php.

Там происходит все примерно так:

- инициализируем автозагрузку
- создаем объект класса Kernel (я думаю, это будет App\Kernel: https://github.com/symfony/demo/blob/master/src/Kernel.php ). Его задача - инициализация фреймворка, загрузка DI контейнера, бандлов, разбор конфигов.
- инициализируем DI контейнер
- загружаем все бандлы (они тоже объекты), инициализиурем их, они читают свои конфиги и настриваются, ставят обработчики разных событий. Этот этап зверски оптимизирован и использует кеш, чтобы не делать это на каждом запросе, но пока на кеш можно не смотреть. В Симфони есть несколько встроенных бандлов (увидеть их список можно в AppKernel), и тебе придется посмотреть их код тоже.
- создаем Request, передаем его Kernel для обработки
- создаем по моему HttpKernel и заходим в цикл обработки запроса: https://symfony.com/doc/current/components/http_kernel.html
- на всех этапах работы HttpKernel в процесс вмешиваются бандлы, и что-то делают свое. Роутер например разбирает URL запроса и ищет соответствие ему в конфиге роутинга, фаерволл проверяет права доступа
- затем Httpkernel определяет текущий контроллер и запускает его
- контроллер получает на вход Request и должен вернуть Response (HTTP-ответ с телом страницы внутри)
- HttpKernel отдает Response юзеру

Также, прочитай про структуру приложения, что такое бандлы (расширения к ядру фреймворка, которые могут добавлять свои сервисы, роуты, обработчики событий и тд).

Также, есть подвохи: например, ты там не найдешь прямого вызова роутера для разбора URL или вызова фаерволла, который проверяет права доступа. Бандл с роутером просто в своем конфиге прописывает вызор роутера перед обработкой запроса HttpKernel, роутер разбирает URL и добавляет результаты разбора назад в объект запроса. Это специально так сделано, чтобы банглы могли менять процесс обработки запроса и отдачи ответа.
755 1132464
>>31859

Должен направлять, посмотри отладчиком в браузере (Ctrl + Shift + I) на вкладке Network, какие заголовки отдает сервер.

>>30056
>>31288

> ЗАДАЧА: сделать отправку данных на сервер через fsockopen, то есть используя только стандартные возможности php


Почему нельзя использовать Guzzle?

> # С помощью @ подавляю ошибки fsockopen и возвращаю пустую $data


Это плохо, так как мы не узнаем причину ошибки. А чтобы нормально работать с ошибками, лучше всего использовать исключения: https://github.com/codedokode/pasta/blob/master/php/exceptions.md

> # Какая разница между timeout в fsockopen и этой настройкой? Как правильно сделать?


Надо читать мануал, думаю, в timeout ставится таймаут на установку TCP-соединения с сервером, а тут таймаут на ожидание пакета данных.

> fwrite($fp, $head);


Тут ошибка. Ты почему-то думаешь, что все данные отправятся за один запрос. Но если почитать описание fwrite, то она всегда может вернуться раньше, отправив только часть данных. Надо проверять результат, который она возвращает, там есть много вариантов:

- отправлены все данные
- отправлены не все данные
- произошла ошибка

То есть надо читать мануал.

> # Вот эту часть не понимаю - зачем вообще она нужна, но если её убрать то мне всегда вместе с данными с


> # сервера приходят и заголовки, которые мне не нужны.


Изучи протокол HTTP, у меня есть урок: https://github.com/codedokode/pasta/blob/master/network/http.md

Тут тоже написано неправильно, кстати, надо проверять результат fgets. И опять же прочесть мануал по ней.

В общем, для всех функций, которые могут возвращать разные результаты, надо их проверять, не произошло ли ошибки. И изучить сам протокол HTTP сначала.

>>31251

Открой stdin или используй константу STDIN и читай из этого потока: http://php.net/manual/ru/features.commandline.io-streams.php

Ну и изучи саму идею потоков ввода-вывода.
755 1132464
>>31859

Должен направлять, посмотри отладчиком в браузере (Ctrl + Shift + I) на вкладке Network, какие заголовки отдает сервер.

>>30056
>>31288

> ЗАДАЧА: сделать отправку данных на сервер через fsockopen, то есть используя только стандартные возможности php


Почему нельзя использовать Guzzle?

> # С помощью @ подавляю ошибки fsockopen и возвращаю пустую $data


Это плохо, так как мы не узнаем причину ошибки. А чтобы нормально работать с ошибками, лучше всего использовать исключения: https://github.com/codedokode/pasta/blob/master/php/exceptions.md

> # Какая разница между timeout в fsockopen и этой настройкой? Как правильно сделать?


Надо читать мануал, думаю, в timeout ставится таймаут на установку TCP-соединения с сервером, а тут таймаут на ожидание пакета данных.

> fwrite($fp, $head);


Тут ошибка. Ты почему-то думаешь, что все данные отправятся за один запрос. Но если почитать описание fwrite, то она всегда может вернуться раньше, отправив только часть данных. Надо проверять результат, который она возвращает, там есть много вариантов:

- отправлены все данные
- отправлены не все данные
- произошла ошибка

То есть надо читать мануал.

> # Вот эту часть не понимаю - зачем вообще она нужна, но если её убрать то мне всегда вместе с данными с


> # сервера приходят и заголовки, которые мне не нужны.


Изучи протокол HTTP, у меня есть урок: https://github.com/codedokode/pasta/blob/master/network/http.md

Тут тоже написано неправильно, кстати, надо проверять результат fgets. И опять же прочесть мануал по ней.

В общем, для всех функций, которые могут возвращать разные результаты, надо их проверять, не произошло ли ошибки. И изучить сам протокол HTTP сначала.

>>31251

Открой stdin или используй константу STDIN и читай из этого потока: http://php.net/manual/ru/features.commandline.io-streams.php

Ну и изучи саму идею потоков ввода-вывода.
756 1132489
>>32464

>Почему нельзя использовать Guzzle?


Потому что не нужны зависимости лишние. Этот метод будет в классе, который предполагается подключать к сайтам клиентов.
И почему для такой простой задачи ты советуешь огромный guzzle, а не curl тогда уж?
757 1132496
>>32489

Тогда тем более надо сделать проверки всех результатов и обработку ошибок. А то ошибка произойдет - и никто не разберется почему.

Ну и я плохо понимаю в чем проблема использовать сторонние библиотеки. Ты хочешь, чтобы все в одном файле было? Тогда можно использовать склейщик (хотя он вызовет проблемы, если у клиента уже подключен Guzzle).

Но вообще, это сложная затея на мой взгляд. Если клиент не использует тот же композер, то скорее всего у него легаси сайт с неизвсетными настройками PHP, неизвестной конфигурацией обработчика ошибок и тд.

Вот посмотри, как Гугл свой клиент API делает: https://github.com/google/google-api-php-client

Там в зависимостях есть кстати Guzzle.

Зато все с ООП и гибко.

И у Яндекса Guzzle есть: https://github.com/nixsolutions/yandex-php-library

И кстати, да, curl или file_get_contents в твоем случае лучше бы подошел.

Вот я тебе (и другому любителю писать велосипеды) еще такой вопрос задам: а что, если с сервера приходит HTML в формате chunked ? Вы тоже его будет сами разбирать своим велосипедом? А поддержку gzip?
758 1132527
>>32496
Ничего с сервера в формате chunked приходить не будет. Сервер будет наш, посылать будет в ответ строку определённого формата. С клиента же должна уходить некоторая информация, в том числе сессионные переменные.
Да, важно, чтобы не было лишних зависимостей, класс этот простой, будет представлять из себя один файл - чем проще, тем лучше, потому что скорее всего клиенты будут подключать его сами - втыкать будут в индексный файл. Не думаю, что им захочется возиться с установкой композера и зависимостей.
Спасибо. Сделаю, видимо, с помощью file_get_contents.
759 1132552
Некто кладет в банк 10000 р. Банк начисляет 10% годовых (то есть, каждый год на счету становится на 10% больше, чем в прошлом году). Напиши программу, считающую, через сколько лет в банке будет миллион? Сколько лет будет этому некто? Доживет ли некто до этого дня, если сегодня ему 16 лет?

https://ideone.com/SjLcUJ
Я не пойму, мое решение норм или нет? Просто все, что я нагуглил выглядит иначе.
760 1132748
поясните за кэш в симфони.

там есть компонент symfony cache. это по сути такая обертка на memcached или другой кэш-драйвер, который мы выберем. это понятно

но что за компонент управляет кэшом, который кладет скомпилированные твиги и аннотации в var/cache? где его настройки? это тот же компонент или часть frameworkbundle? как понять логику прогрева кэша - если у меня для каждого пользователя должен быть уникальный csrf-токен, он будет сгенерирован при прогреве? как этим управлять?

и главный вопрос: это вообще можно называть кэшом или это правильнее назвать чем-то типа компилятора из кода фреймворка в raw php-код?

буду также благодарен, если кто-то скинет ссылки где про это почитать. я искал, но не нашел.
761 1132769
У кого есть опыт подскажите как сохранять несколько объектов одного класса в бд? У меня есть объекты Event и мэппер EventMapper, в котором есть метод Insert для сохранения одного ивента. Если я хочу сохранить несколько, нужно сделать метод вроде InsertEvents(array $events), или для каждого ивента создавать новый мэппер?

Еще вопрос, а что если ивент содержит вложенные классы Reminder, которые тоже нужно сохранить. Пусть родительский EventMapper проверяет наличие "детей" и сам создает ReminderMapper и вызывает ReminderMapper->insertReminders(Reminders)? Или это забота контроллера, вытащить детей из родителя, и для каждого класса создать соответствующий мэппер?

И похожая ситуация, нужно трансформировать Event из класса в json определенной структуры. Event содержит дочерние классы Reminder. Есть соответствующие мэпперы для них. Должен ли родитель проверять наличие детей и создавать мапперы для них или вынести это в код, который создает родительский мэппер, например создать супер класс Mapper, который уже достает детей из родителей и для всех создает нужные мэпперы?
762 1132777
>>32769
Я читаю это вот всё из треда и про себя думаю. Господи Как же ты хорошь. ты знаешь про обьекты, ты определаешь их типы, ты сохранаешь ивенты. И хочешь это многократно делать. Как же ты по сравнению со мной хорошь. Я ведь только начал путь. Я ведь только начинаю айфоны и айпады, я только начинаю оп задачки, а ты уже на вершине. Смогу ли я достичь такого мегамонстрячества?
Сорян за оффтоп. Накипело всё.
763 1132812
>>32777
Да бро, сможешь, продолжай заниматься, уже после задачи про департаменты ты будешь знать про объекты и их типы. Я верю в тебя!
764 1132846
>>32748

> который кладет скомпилированные твиги


Это сам твиг делает, и бандл Симфони только задает настройки для него вроде пути к папке.

> и аннотации в var/cache


О каких аннотациях речь? Если о Доктриновских, то это делает сама Доктрина. Если об аннотациях контроллеров, то думаю, надо искать где-то в FrameworkBundle или по коду, где они ищутся.

> как понять логику прогрева кэша - если у меня для каждого пользователя должен быть уникальный csrf-токен, он будет сгенерирован при прогреве? как этим управлять?



"прогревом кеша" называется генерация симфониевских кешей (например создание компилированной версии DI контейнера или компилированной версии роутера или прокси-классов для доктрины или твиг-шаблонов) при вызове команды cache:warmup. На продакшене это делается вызововом команды, на dev кеш генерируется и обновляется сам при обновлении любого из файлов (например конфига), на основе которого он сгенерирован.

Прогрев кеша не относится к каким-то поьзовательским кешам и твой токен тут не при чем.

В коде можно искать прогрев кеша, изучив команду https://github.com/symfony/framework-bundle/blob/master/Command/CacheWarmupCommand.php :

Например, в FrameworkBundle есть набор cache warmers, можно глянуть их: https://github.com/symfony/framework-bundle/tree/master/CacheWarmer Я не уверен, но может другие бандлы добаляют свои вармеры. Можно попробовать поискать их поиском по файлам у себя.

Вообще, я вроде писал про кеши в Симфони, но не могу найти пост, продублирую тут.

1) кешер опкода (например, opcache) - не часть Симфони, но крайне рекомендуется, если вам важна производительность. Нужно включить. На дев настраиваем revalidate_freq (частота проверки времени модификации файла) низким 1-2 секунды, на продакшене можно настроить его на 1-2-3 минуты, и сбрасывать кеш после деплоя скриптом.

2) Кеш DI контейнера и роутера

Симфони читает конфиги бандлов и пользователя, и создает компилированную версию DI контейнера (то есть PHP класс со всеми вписанными в него настройками и сервисами из контейнера) и роутера (PHP класс, где роуты превращены в код разбора URL на основе preg_match, а также класс генератора URL).

Просто посмотри эти классы в var/cache, это будет лучше любого объяснения. Имена классов вроде devUrlMatcher, devDEbugProjectContainer если я не путаю.

На проде это делается вручную при вызове warmup, на dev эти кеши генерируются и обновляются полност ью сами. Код использования этих кешей можно найти если смотреть тут: https://github.com/symfony/http-kernel/blob/master/Kernel.php#L121 и далее функции вроде

- initializeContainer: https://github.com/symfony/http-kernel/blob/master/Kernel.php#L449
- buildContainer https://github.com/symfony/http-kernel/blob/master/Kernel.php#L591

Заметь, что бандлы и ты сам можешь влиять на процесс компиляции контейнера с помощью классов CompilerPass. Это описано в доках:

- https://symfony.com/doc/current/components/dependency_injection/workflow.html
- https://symfony.com/doc/current/components/dependency_injection/compilation.html
- https://knpuniversity.com/screencast/symfony-journey-di/symfony-builds-the-container

Обрати внимание, что там есть бандлы и компоненты. Компоненты Симфони вроде DI Container - это независимые от фреймворка части, которые можно использовать без него, а бандлы - это именно части фреймворка. Контейнер сделан именно в виде отдельного компонента.

Прогрев роутера надо искать где-то начиная отсюда: https://github.com/symfony/framework-bundle/blob/master/Routing/Router.php (и смотреть класс-предок тоже).

3) Кеш шаблонов твига

Твиг компилирует шаблоны в php-файлы. В дев-версии это делается автоматически, в продакшене командой warmup. Подробности надо искать в самом твиге:

- в прогревальщике кеша шаблонов https://github.com/symfony/twig-bundle/blob/master/CacheWarmer/TemplateCacheWarmer.php
- в компоненте твига, в процессе загрузки шаблона https://github.com/twigphp/Twig/blob/2.x/lib/Twig/Environment.php#L331

Обрати внимание, что есть твиг - независимый компонент, и есть бандл TwigBundle, часть Симфони, которая интегрирует его в фреймворк. Не путай их.

4) Кеш аннотаций доктрины

Доктрина кеширует аннотации из сущностей в php-файлы (которые затем кешируются в opcache). ПРинцип генерации тот же, на продакшене явно, на dev - автоматически при изменении исходных файлов.

5) Прокси-классы Доктрины

Нужны для реализации ленивой загрузки сущностей из БД. На проде генерируются при прогреве и сохраняются как php файлы, на dev вроде бы генерируются на лету в памяти и не сохраняются.

6) Кеш DQL-запросов Доктрины и кеш метаданных сущностей

DQL-запросы надо конвертировать в SQL, это требует время и потому результат конвертирования кешируется. По моему, в Apc.

Это наверно не все кеши, остальные надо искать разбором кода Симфони.

> и главный вопрос: это вообще можно называть кэшом или это правильнее назвать чем-то типа компилятора из кода фреймворка в raw php-код?


Можно назвать кешем.
764 1132846
>>32748

> который кладет скомпилированные твиги


Это сам твиг делает, и бандл Симфони только задает настройки для него вроде пути к папке.

> и аннотации в var/cache


О каких аннотациях речь? Если о Доктриновских, то это делает сама Доктрина. Если об аннотациях контроллеров, то думаю, надо искать где-то в FrameworkBundle или по коду, где они ищутся.

> как понять логику прогрева кэша - если у меня для каждого пользователя должен быть уникальный csrf-токен, он будет сгенерирован при прогреве? как этим управлять?



"прогревом кеша" называется генерация симфониевских кешей (например создание компилированной версии DI контейнера или компилированной версии роутера или прокси-классов для доктрины или твиг-шаблонов) при вызове команды cache:warmup. На продакшене это делается вызововом команды, на dev кеш генерируется и обновляется сам при обновлении любого из файлов (например конфига), на основе которого он сгенерирован.

Прогрев кеша не относится к каким-то поьзовательским кешам и твой токен тут не при чем.

В коде можно искать прогрев кеша, изучив команду https://github.com/symfony/framework-bundle/blob/master/Command/CacheWarmupCommand.php :

Например, в FrameworkBundle есть набор cache warmers, можно глянуть их: https://github.com/symfony/framework-bundle/tree/master/CacheWarmer Я не уверен, но может другие бандлы добаляют свои вармеры. Можно попробовать поискать их поиском по файлам у себя.

Вообще, я вроде писал про кеши в Симфони, но не могу найти пост, продублирую тут.

1) кешер опкода (например, opcache) - не часть Симфони, но крайне рекомендуется, если вам важна производительность. Нужно включить. На дев настраиваем revalidate_freq (частота проверки времени модификации файла) низким 1-2 секунды, на продакшене можно настроить его на 1-2-3 минуты, и сбрасывать кеш после деплоя скриптом.

2) Кеш DI контейнера и роутера

Симфони читает конфиги бандлов и пользователя, и создает компилированную версию DI контейнера (то есть PHP класс со всеми вписанными в него настройками и сервисами из контейнера) и роутера (PHP класс, где роуты превращены в код разбора URL на основе preg_match, а также класс генератора URL).

Просто посмотри эти классы в var/cache, это будет лучше любого объяснения. Имена классов вроде devUrlMatcher, devDEbugProjectContainer если я не путаю.

На проде это делается вручную при вызове warmup, на dev эти кеши генерируются и обновляются полност ью сами. Код использования этих кешей можно найти если смотреть тут: https://github.com/symfony/http-kernel/blob/master/Kernel.php#L121 и далее функции вроде

- initializeContainer: https://github.com/symfony/http-kernel/blob/master/Kernel.php#L449
- buildContainer https://github.com/symfony/http-kernel/blob/master/Kernel.php#L591

Заметь, что бандлы и ты сам можешь влиять на процесс компиляции контейнера с помощью классов CompilerPass. Это описано в доках:

- https://symfony.com/doc/current/components/dependency_injection/workflow.html
- https://symfony.com/doc/current/components/dependency_injection/compilation.html
- https://knpuniversity.com/screencast/symfony-journey-di/symfony-builds-the-container

Обрати внимание, что там есть бандлы и компоненты. Компоненты Симфони вроде DI Container - это независимые от фреймворка части, которые можно использовать без него, а бандлы - это именно части фреймворка. Контейнер сделан именно в виде отдельного компонента.

Прогрев роутера надо искать где-то начиная отсюда: https://github.com/symfony/framework-bundle/blob/master/Routing/Router.php (и смотреть класс-предок тоже).

3) Кеш шаблонов твига

Твиг компилирует шаблоны в php-файлы. В дев-версии это делается автоматически, в продакшене командой warmup. Подробности надо искать в самом твиге:

- в прогревальщике кеша шаблонов https://github.com/symfony/twig-bundle/blob/master/CacheWarmer/TemplateCacheWarmer.php
- в компоненте твига, в процессе загрузки шаблона https://github.com/twigphp/Twig/blob/2.x/lib/Twig/Environment.php#L331

Обрати внимание, что есть твиг - независимый компонент, и есть бандл TwigBundle, часть Симфони, которая интегрирует его в фреймворк. Не путай их.

4) Кеш аннотаций доктрины

Доктрина кеширует аннотации из сущностей в php-файлы (которые затем кешируются в opcache). ПРинцип генерации тот же, на продакшене явно, на dev - автоматически при изменении исходных файлов.

5) Прокси-классы Доктрины

Нужны для реализации ленивой загрузки сущностей из БД. На проде генерируются при прогреве и сохраняются как php файлы, на dev вроде бы генерируются на лету в памяти и не сохраняются.

6) Кеш DQL-запросов Доктрины и кеш метаданных сущностей

DQL-запросы надо конвертировать в SQL, это требует время и потому результат конвертирования кешируется. По моему, в Apc.

Это наверно не все кеши, остальные надо искать разбором кода Симфони.

> и главный вопрос: это вообще можно называть кэшом или это правильнее назвать чем-то типа компилятора из кода фреймворка в raw php-код?


Можно назвать кешем.
765 1132847
>>32769

> У меня есть объекты Event и мэппер EventMapper, в котором есть метод Insert для сохранения одного ивента. Если я хочу сохранить несколько, нужно сделать метод вроде InsertEvents(array $events), или для каждого ивента создавать новый мэппер?



Маппер по логике должен быть в одном экземпляре. Ты либо несколько раз вызываешь Insert, либо делаешь метод InsertMany и вызываешь его один раз.

Вообще, классы часто делят на "сущности", которых может быть много экземпляров и "сервисов", которые существуют в одном экземпляре и не имеют состояния.

> Еще вопрос, а что если ивент содержит вложенные классы Reminder, которые тоже нужно сохранить. Пусть родительский EventMapper проверяет наличие "детей" и сам создает ReminderMapper


Маппер точно не должен заниматься созданием других объектов-мапперов, это задача каких-то внешних классов, например, фабрики мапперов:

$this->mapperFactory->getMapperFor(Reminder::class);

Фабрику можно внедрить в маппер через DI. Подумай на досуге, почему я не предлагаю вместо фабрики внедрить в маппер сразу DI контейнер.

> Или это забота контроллера, вытащить детей из родителя, и для каждого класса создать соответствующий мэппер?


Зависит от выбранного тобой подхода. Кстати, Доктрина все это делает сама.

> Есть соответствующие мэпперы для них. Должен ли родитель проверять наличие детей и создавать мапперы для них


Лучше фабрику. Если класс занимается конвертацией в JSON, не его задача создавать другие классы.

>>32777

Сможешь, но надо изучать все последовательно - если ты сейчас возьмешься за мапперы, то можешь запутаться. Но если тебе хочется глянуть одним глазком, то:

- в учебнике на http://codedokode.github.io/phpbook есть глава про ООП, что такое классы и объекты
- в сборнике паст есть урок про ООП-работу с БД и там описано что такое маппер: https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md (если ты не знаком с SQL и с драйверами БД вроде PDO то пока будет сложновато понять)

Наш тред всему этому научит.
765 1132847
>>32769

> У меня есть объекты Event и мэппер EventMapper, в котором есть метод Insert для сохранения одного ивента. Если я хочу сохранить несколько, нужно сделать метод вроде InsertEvents(array $events), или для каждого ивента создавать новый мэппер?



Маппер по логике должен быть в одном экземпляре. Ты либо несколько раз вызываешь Insert, либо делаешь метод InsertMany и вызываешь его один раз.

Вообще, классы часто делят на "сущности", которых может быть много экземпляров и "сервисов", которые существуют в одном экземпляре и не имеют состояния.

> Еще вопрос, а что если ивент содержит вложенные классы Reminder, которые тоже нужно сохранить. Пусть родительский EventMapper проверяет наличие "детей" и сам создает ReminderMapper


Маппер точно не должен заниматься созданием других объектов-мапперов, это задача каких-то внешних классов, например, фабрики мапперов:

$this->mapperFactory->getMapperFor(Reminder::class);

Фабрику можно внедрить в маппер через DI. Подумай на досуге, почему я не предлагаю вместо фабрики внедрить в маппер сразу DI контейнер.

> Или это забота контроллера, вытащить детей из родителя, и для каждого класса создать соответствующий мэппер?


Зависит от выбранного тобой подхода. Кстати, Доктрина все это делает сама.

> Есть соответствующие мэпперы для них. Должен ли родитель проверять наличие детей и создавать мапперы для них


Лучше фабрику. Если класс занимается конвертацией в JSON, не его задача создавать другие классы.

>>32777

Сможешь, но надо изучать все последовательно - если ты сейчас возьмешься за мапперы, то можешь запутаться. Но если тебе хочется глянуть одним глазком, то:

- в учебнике на http://codedokode.github.io/phpbook есть глава про ООП, что такое классы и объекты
- в сборнике паст есть урок про ООП-работу с БД и там описано что такое маппер: https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md (если ты не знаком с SQL и с драйверами БД вроде PDO то пока будет сложновато понять)

Наш тред всему этому научит.
766 1132876
>>32847

>Фабрику можно внедрить в маппер через DI. Подумай на досуге, почему я не предлагаю вместо фабрики внедрить в маппер сразу DI контейнер.


Спасибо, буду думать
767 1132879
>>32846
огромное спасибо!
получается, что это можно назвать кэшем, т.к. кэш - это некий буфер между системой и запросом, но в то же время это и компиляция конфигов с аннотациями и прочим. меня само слово "кэш" и немного смутило, т.к. есть еще symfony/cache, а еще FrameworkBundle\HttpCache
768 1132883
>>32879

Кеш это не некий буфер. Это хранилище для данных, которые требуют больших затрат на вычисление.
769 1132922
>>32463

>Тут стоит просто поставить себе образец Symfony приложения (например https://github.com/symfony/demo/ ) и смотреть код, начиная с public/index.php.


Я смотрел, но в Get Started ничего не говориться о таком коде. Это же автоматически создается?
770 1132945
допустим есть страничка которая, логирует ипишники пользователей, емли я вставлю эту страничку через айфрейм, на другой сайт, то в итоге будут логировптьмя ип пользователей или ип сайта с айфреймом?
771 1132986
>>32847

>Вообще, классы часто делят на "сущности", которых может быть много экземпляров и "сервисов", которые существуют в одном экземпляре и не имеют состояния.


А свойство с объектом PDO означает, что экземпляр имеет состояние?

>Фабрику можно внедрить в маппер через DI.


вот так?
$jsonMapper = new JsonMapper($container['JsonMapperFactory'])
$dbMapper = new DBMapper($container['DBMapperFactory'])

>внедрить в маппер сразу DI контейнер.


$jsonMapper = new JsonMapper($container)
а внутри $jsonMapper:
$reminderMapper = $this->container['reminderMapper']

>почему я не предлагаю вместо фабрики внедрить в маппер сразу DI контейнер.


Наверное потому, что JsonMapper'y не нужно создавать ничего кроме потомков определенного класса, и передача контейнера означала бы передачу большей ответственности, чем необходимо.

DI контейнер, насколько я понял, это более сложная версия фабрики, которая умеет создавать и инициализировать переданные ей объекты вместе с дополнительными параметрами, которые можно легко изменить.
772 1133014
Как правильно делать пагинацию, если есть ассоциации, а надо отобрать 30 основых сущностей со всеми их ассоциациями?
Речь о Доктрине. Если я делаю LIMIT 30, то в БД это 30 строк, среди которых может быть только одна главная сущность со всеми своими ассоциациями и вторая с неполным набором ассоциаций?
773 1133165
https://ideone.com/FCtJz7
Подскажите, пожалуйста, если у меня код получился рабочим, но у меня, как я понял, "слишком сложный" код, когда решение может быть гораздо проще. Это сильно плохо?
774 1133211
В PDO чем заменить mysqli_real_escape_string?
775 1133217
Почему при добавлении строки $category = $connection->quote($_POST["Category"]); перестаёт работать header("Location:dashboard.php");?
Я всё облазил, всё проверил. Вроде всё правильно, но браузер не перенаправляет на нужную страницу, а просто перезагружает текущую без выведения ошибок.
Однако, если я удалю строку с connection, то всё работает.
776 1133228
>>33211
Ничем конкретно, потому что надо использовать параметризованные запросы.
777 1133229
>>33165
Плох тот код, который не может быть улучшен.

https://ideone.com/KzQmI5
778 1133230
>>33217
Скорее всего у тебя там таки ошибка при подключении к БД.
779 1133235
>>33229
"//" нужны для удобства?
780 1133237
>>33235
Штоу
Это закомментированные строки.
781 1133238
>>33237
Ну я по ссылке https://ideone.com/KzQmI5 перешел, там перед foreach и перед if стоят //.
782 1133245
>>33230
Я всячески пытался их PDO что-нибудь слепить. Конечный вариант хоть ошибки выдаёт.
783 1133254
>>33229
>>33237
А, все, я понял, как это работает. Спасибо, анон.
784 1133256
подскажите по симфони еще раз. вот есть два способа показать пользователю страничку с какой-то сущностью:

1 вариант - как в демо приложении симфони:
public function showArticle(Article $article): Response
{
return $this->render('article.html.twig', ['article' => $article]);
}

2 вариант (как я сначала написал):
public function showArticle(int $id): Response
{
$repo = $this->getDoctrine()->getRepository(Article::class);
$article = $repo->find($id);

if (!$article) {
throw new NotFoundHttpException('The article is not found');
}

return $this->render('article.html.twig', ['article' => $article]);
}

чем второй вариант хуже?
785 1133257
>>33245
Что за ошибки?
Вот простой и понятный пример использования pdo
https://phpdelusions.net/pdo
Внимательно изучи и попробуй разобраться что к чему.
14969423748560.png285 Кб, 1000x800
786 1133258
>>32459

>interval это интервал, чаще которого нельзя посылать запросы к одному домену.


И в чем его смысл, если этот интервал может истечь до завершения текущего запроса?

>я не сталкивался пока с кодом 203, и никто мне не писал про этов Issues


Лол. У меня тут на проекте с посещалкой 4к уников/день месяца два назад, оказывается, отвалилась фича, не покрытая тестами. Багрепорт я получил только вчера. Никто никогда не напишет тебе issue про такие вещи.

>обнаружение припаркованных (то есть потерянных или проданных владельцем) доменов


Обходим все ссылки первый раз. Здесь придется проверить глазками, отдают ли ссылки то, что отдавали ранее. Пишем таймстамп последней проверки, пишем eTag, если имеется, Last-Modified, если имеется, Content-Length, если имеется. Делаем запрос whois, записываем expire-date.
Алгоритм последующих проверок:
Отправляем запрос с Etag / If-Modified-Since. Получаем 304? Ссылка живая.
Делаем запрос. Content-Length прежний? Ссылка живая.
Expire-date < now? Делаем запрос в whois. Домен перерегистрирован? Подозрительность ссылки +1.
Днс поменялись на днс из словаря доменных парковок? Подозрительность ссылки +1.
На странице присутствуют вхождения $domainParkingMarkers = ['parking', 'for sale', 'domain owner']? Подозрительность ссылки +1.
site.com/dsfjklsjfklsjdf отдавало 404, а теперь отдает 200, и Content-Length плюс-минус одинаков на любой странице? Подозрительность ссылки +1.
Ответы в твоем же вопросе.

>Другая проблема - некоторые домены не любят ботов (а я честно подписываю User-Agent)


Если 403, либо редирект на локалхост, делаешь второй запрос с юзер-агентом браузера. А вообще веб должен быть доступен для любого клиента, поэтому можешь слать к черту такие ссылки. Btw, если ты претендуешь на честность, тебе нужно уважать robots.txt.

>Третья проблема - проверка ссылок вроде mega.nz/#12345


Ну да, здесь придется писать правила. Btw, ргхост отдает мне 404.

>Надеюсь, что Гузл это сам обработает


Проблемы черных ящиков.

>Странно, мне кажется, что обязательно


>Можешь дать пример страницы, где есть 3xx но это не редирект?


Пожалуйста. Запусти да проверь.
https://pastebin.com/VAmaBpLQ
Ты увидишь "Есть два стула". Редиректа не произойдет.
А еще 304 не редирект.
А еще 305 deprecated.
А еще 306 зарезервирован. А еще все коды, начиная с 309. Ты обязан игнорировать Location у таких кодов.
Итого, безусловных редиректов пять - 301, 302, 303, 307, 308. А у тебя - сотня.

>Ну и как я понимаю, большинство браузеров отредиректит пользователя


Неправильно понимаешь, не отредиректит. Ты споришь со мной, хотя можешь открыть первую ссылку в гугле и почитать RFC.
https://tools.ietf.org/html/rfc7231#section-6.4.1

> The user agent MAY use the Location field value for automatic redirection.


> MAY



>> Сервер не обязан отсылать Content-Type.


>Не уверен.


А RFC уверен.
https://tools.ietf.org/html/rfc7231#section-3.1.1.5

> A sender that generates a message containing a payload body SHOULD


> generate a Content-Type header field in that message unless the


> intended media type of the enclosed representation is unknown to the


> sender. If a Content-Type header field is not present, the recipient


> MAY either assume a media type of "application/octet-stream"


> ([RFC2046], Section 4.5.1) or examine the data to determine its type.


Напомню, что SHOULD это не MUST. Должен, но не обязан. Юзер-агент может посмотреть данные, чтобы определить тип.

>Мне не пришлось писать свой HTTP клиент


file_get_contents

>объекты для представления HTTP запросов и ответов


Для запросов из коробки stream context. Для ответов обертка хидеров и контента пишется за 5 минут.

>Не пришлось изучать кучу тонкостей, про которые ты написал (про 203 я например не знал)


Одну секунду, причем тут 203? Газл тебе возвращает ответ, а дальше, чем делать с этими кодами - твой геморрой. Газл тебя от этого не избавляет.

>4 строчки про то, зачем писать HTTP-клиент


Действительно зачем, если есть file_get_contents, который даже из коробки, мать его, через stream notification callback может рассказать тебе о переадресациях согласно RFC, и так же из коробки ты можешь запретить ходить по переадресациям.
Но лучше я возьму Газл, он лучше, и напишу свой велосипед, предполагая, что все 3хх коды - переадресации. Вместо использования того, что решает задачу из коробки! Ты не поверишь, можно даже подписаться на STREAM_NOTIFY_MIME_TYPE_IS! В момент получения Content-Type сработает твой коллбэк! Из коробки!

В итоге я только укрепляюсь во мнении, что ты бездумно используешь черные ящики лишь потому, что тебе лень разобраться в протоколе, который общается обычным ASCII-текстом.

>>32460

>недружелюбно по отношению к серверу


Лол! Серьезно?! TCP вообще похуй, когда ты закроешь сокет. Закрыл, досвидос. Ах да, если ты не знал, сервер обязан выполнить все те же действия при запросе HEAD, что и при запросе GET. Даже сходить куда-нибудь в MySQL-базу за океан. Потому что код не знает, вдруг, если в базе небо == аллаху, то где-то дальше добавится заголовок X-Allah: Bicycle.
А вот контента ты не получишь. Представляешь как недружелюблюбно?

>тут для Guzzle 6


>можно костылем передать нужные опции для curl


Лол, да что ж тебя на подвиги-то тянет. Из коробки (повторяю - из ко-роб-ки!) можно открыть сокет, функцией stream_get_meta_data прочитать только хидеры и исключительно хидеры, и закрыть сокет! Из коробки! Три строчки кода! fopen, stream_get_meta_data, fclose!

>>32462

>Нет, чтобы получить просто заголовки, тебе придется писать код, чтобы добавить таймаут, еще какой-то код и так далее.


Это уже не смешно. Вы чего, стандартную либу не знаете? Три строки кода, три! fopen, stream_get_meta_data, fclose! Таймаут задается параметром в stream context!

>он умеет делать так: http://example.com/a/b + ../file.txt = http://example.com/file.txt


Да ладно!
if (strpos($href, '/') !== 0) { $url = realpath(dirname('http://example.com/a/b') . '/' . $url); } else { // да, для абсолютного пути придется пересобрать хост через parse_url с учетом возможного порта и даже логина-пароля }
Минута программирования. Нет, надо подтянуть библиотеку.

Кстати, спешу огорчить. Есть тег <base>, который переопределяет, от какой директории строить url. Твой скрипт это учитывает? А может, учитывает Газл? Ой нет, он просто по ссылочкам ходит. Что же делать? Нужно срочно искать библиотеку!

> Не вижу в чем выгода тратить время на переизобретение того, что уже написано.


Изобретение чего? Конкатенации директорий? Тебе нужен jQuery, чтобы сложить 2 + 2?

>И что я теряю, используя готовую библиотеку.


Если в готовой библиотеке находится уязвимость, тоби пизда. У тебя тоже могут быть уязвимости, но здесь работает теория неуловимого Джо - ты никому не нужен.

Вы просто клепаете веб-приложушки из готовых модулей, а за моими плечами база. Мои абстракции - это голый PHP, ваши - библиотечки, чтобы склеивать директории.
Если мне дать микроволновку, где будет крутиться Java Micro Edition и в либе только сокеты, я смогу сделать http-реквест и получить ответ, а вы не сможете ничего.
14969423748560.png285 Кб, 1000x800
786 1133258
>>32459

>interval это интервал, чаще которого нельзя посылать запросы к одному домену.


И в чем его смысл, если этот интервал может истечь до завершения текущего запроса?

>я не сталкивался пока с кодом 203, и никто мне не писал про этов Issues


Лол. У меня тут на проекте с посещалкой 4к уников/день месяца два назад, оказывается, отвалилась фича, не покрытая тестами. Багрепорт я получил только вчера. Никто никогда не напишет тебе issue про такие вещи.

>обнаружение припаркованных (то есть потерянных или проданных владельцем) доменов


Обходим все ссылки первый раз. Здесь придется проверить глазками, отдают ли ссылки то, что отдавали ранее. Пишем таймстамп последней проверки, пишем eTag, если имеется, Last-Modified, если имеется, Content-Length, если имеется. Делаем запрос whois, записываем expire-date.
Алгоритм последующих проверок:
Отправляем запрос с Etag / If-Modified-Since. Получаем 304? Ссылка живая.
Делаем запрос. Content-Length прежний? Ссылка живая.
Expire-date < now? Делаем запрос в whois. Домен перерегистрирован? Подозрительность ссылки +1.
Днс поменялись на днс из словаря доменных парковок? Подозрительность ссылки +1.
На странице присутствуют вхождения $domainParkingMarkers = ['parking', 'for sale', 'domain owner']? Подозрительность ссылки +1.
site.com/dsfjklsjfklsjdf отдавало 404, а теперь отдает 200, и Content-Length плюс-минус одинаков на любой странице? Подозрительность ссылки +1.
Ответы в твоем же вопросе.

>Другая проблема - некоторые домены не любят ботов (а я честно подписываю User-Agent)


Если 403, либо редирект на локалхост, делаешь второй запрос с юзер-агентом браузера. А вообще веб должен быть доступен для любого клиента, поэтому можешь слать к черту такие ссылки. Btw, если ты претендуешь на честность, тебе нужно уважать robots.txt.

>Третья проблема - проверка ссылок вроде mega.nz/#12345


Ну да, здесь придется писать правила. Btw, ргхост отдает мне 404.

>Надеюсь, что Гузл это сам обработает


Проблемы черных ящиков.

>Странно, мне кажется, что обязательно


>Можешь дать пример страницы, где есть 3xx но это не редирект?


Пожалуйста. Запусти да проверь.
https://pastebin.com/VAmaBpLQ
Ты увидишь "Есть два стула". Редиректа не произойдет.
А еще 304 не редирект.
А еще 305 deprecated.
А еще 306 зарезервирован. А еще все коды, начиная с 309. Ты обязан игнорировать Location у таких кодов.
Итого, безусловных редиректов пять - 301, 302, 303, 307, 308. А у тебя - сотня.

>Ну и как я понимаю, большинство браузеров отредиректит пользователя


Неправильно понимаешь, не отредиректит. Ты споришь со мной, хотя можешь открыть первую ссылку в гугле и почитать RFC.
https://tools.ietf.org/html/rfc7231#section-6.4.1

> The user agent MAY use the Location field value for automatic redirection.


> MAY



>> Сервер не обязан отсылать Content-Type.


>Не уверен.


А RFC уверен.
https://tools.ietf.org/html/rfc7231#section-3.1.1.5

> A sender that generates a message containing a payload body SHOULD


> generate a Content-Type header field in that message unless the


> intended media type of the enclosed representation is unknown to the


> sender. If a Content-Type header field is not present, the recipient


> MAY either assume a media type of "application/octet-stream"


> ([RFC2046], Section 4.5.1) or examine the data to determine its type.


Напомню, что SHOULD это не MUST. Должен, но не обязан. Юзер-агент может посмотреть данные, чтобы определить тип.

>Мне не пришлось писать свой HTTP клиент


file_get_contents

>объекты для представления HTTP запросов и ответов


Для запросов из коробки stream context. Для ответов обертка хидеров и контента пишется за 5 минут.

>Не пришлось изучать кучу тонкостей, про которые ты написал (про 203 я например не знал)


Одну секунду, причем тут 203? Газл тебе возвращает ответ, а дальше, чем делать с этими кодами - твой геморрой. Газл тебя от этого не избавляет.

>4 строчки про то, зачем писать HTTP-клиент


Действительно зачем, если есть file_get_contents, который даже из коробки, мать его, через stream notification callback может рассказать тебе о переадресациях согласно RFC, и так же из коробки ты можешь запретить ходить по переадресациям.
Но лучше я возьму Газл, он лучше, и напишу свой велосипед, предполагая, что все 3хх коды - переадресации. Вместо использования того, что решает задачу из коробки! Ты не поверишь, можно даже подписаться на STREAM_NOTIFY_MIME_TYPE_IS! В момент получения Content-Type сработает твой коллбэк! Из коробки!

В итоге я только укрепляюсь во мнении, что ты бездумно используешь черные ящики лишь потому, что тебе лень разобраться в протоколе, который общается обычным ASCII-текстом.

>>32460

>недружелюбно по отношению к серверу


Лол! Серьезно?! TCP вообще похуй, когда ты закроешь сокет. Закрыл, досвидос. Ах да, если ты не знал, сервер обязан выполнить все те же действия при запросе HEAD, что и при запросе GET. Даже сходить куда-нибудь в MySQL-базу за океан. Потому что код не знает, вдруг, если в базе небо == аллаху, то где-то дальше добавится заголовок X-Allah: Bicycle.
А вот контента ты не получишь. Представляешь как недружелюблюбно?

>тут для Guzzle 6


>можно костылем передать нужные опции для curl


Лол, да что ж тебя на подвиги-то тянет. Из коробки (повторяю - из ко-роб-ки!) можно открыть сокет, функцией stream_get_meta_data прочитать только хидеры и исключительно хидеры, и закрыть сокет! Из коробки! Три строчки кода! fopen, stream_get_meta_data, fclose!

>>32462

>Нет, чтобы получить просто заголовки, тебе придется писать код, чтобы добавить таймаут, еще какой-то код и так далее.


Это уже не смешно. Вы чего, стандартную либу не знаете? Три строки кода, три! fopen, stream_get_meta_data, fclose! Таймаут задается параметром в stream context!

>он умеет делать так: http://example.com/a/b + ../file.txt = http://example.com/file.txt


Да ладно!
if (strpos($href, '/') !== 0) { $url = realpath(dirname('http://example.com/a/b') . '/' . $url); } else { // да, для абсолютного пути придется пересобрать хост через parse_url с учетом возможного порта и даже логина-пароля }
Минута программирования. Нет, надо подтянуть библиотеку.

Кстати, спешу огорчить. Есть тег <base>, который переопределяет, от какой директории строить url. Твой скрипт это учитывает? А может, учитывает Газл? Ой нет, он просто по ссылочкам ходит. Что же делать? Нужно срочно искать библиотеку!

> Не вижу в чем выгода тратить время на переизобретение того, что уже написано.


Изобретение чего? Конкатенации директорий? Тебе нужен jQuery, чтобы сложить 2 + 2?

>И что я теряю, используя готовую библиотеку.


Если в готовой библиотеке находится уязвимость, тоби пизда. У тебя тоже могут быть уязвимости, но здесь работает теория неуловимого Джо - ты никому не нужен.

Вы просто клепаете веб-приложушки из готовых модулей, а за моими плечами база. Мои абстракции - это голый PHP, ваши - библиотечки, чтобы склеивать директории.
Если мне дать микроволновку, где будет крутиться Java Micro Edition и в либе только сокеты, я смогу сделать http-реквест и получить ответ, а вы не сможете ничего.
787 1133265
>>33258
Ой, мне нужно признать обосрамс. Ложился спать и вспомнил про функцию get_headers. Так что хедеры получаются в пхп одной строкой.
788 1133266
Аноны, если вы изучаете линукс, вам пригодится сайт https://explainshell.com

Он для введенной команды находит мануал и показывает объяснение каждой опции, например: https://explainshell.com/explain?cmd=x11vnc+-rfbport+4544+-rfbauth+/tmp/vncpass+-display+:44+-forever+-auth+/tmp/xvfb.auth

Также, вы можете щелкнуть правой кнопкой по полю поиска там, выбрать "добавить как поисковую систему", задать ключевое слово и открывать подсказку прямо из адресной строки браузера.

Добавил также эту информацию в урок по cli.
789 1133271
>>33266
Годнота. Спасибо.
790 1133308
>>33266
Не понял смысл этого сайта. Там же просто выводится строка из справки. Не проще ли и не полезней, раз уж вы ИЗУЧАЕТЕ линукс, читать справку по программе programma_name --help?
791 1133351
>>33258

> И в чем его смысл, если этот интервал может истечь до завершения текущего запроса?


Смысл в том, чтобы не перегружать сторонний сервер запросами и тем самым снизить вероятность получения бана моего бота. Я хочу, чтобы запросы к определенному домену отправлялись бы не чаще, чем раз в N (сейчас N=3) секунд, если интервал будет больше - ничего страшного.

По факту, это да, интервал не между окончанием одного запроса и началом следующего, а между началом одного и второго. Пусть пока так будет.

> Никто никогда не напишет тебе issue про такие вещи


Значит, это никого не беспокоит.

> таймстамп последней проверки, пишем eTag, если имеется


Это будет вызывать ложные срабатывания, особенно если контент динамический и last modified нету или он постоянно увеличивается. Content-length будет меняться при изменении где-то в шапке, сайдбаре и тд.

У меня кстати была мысль интереснее: многие припаркованные домены подгружают ссылки через JS и их можно детектирвоать по отсутствию (или маленькому количеству) текста в HTML.

Про whois - да, вариант, хотя это требует подключать стороннюю библиотеку и разбираться с протоколом whois.

> Домен перерегистрирован? Подозрительность ссылки +1.


Это надо где-то держать историю проверок домена. Это снижает автономность инструмента.

> Днс поменялись на днс из словаря доменных парковок? Подозрительность ссылки +1.


Согласен, это можно.

> site.com/dsfjklsjfklsjdf отдавало 404, а теперь отдает 200, и Content-Length плюс-минус одинаков на любой странице?


Да, это тоже рабочий вариант, только не хочется слать запросы подряд на все домены, это надо как-то сначала отобрать "подозрительные" ссылки и их уже тщательнее проверять.

> А вообще веб должен быть доступен для любого клиента, поэтому можешь слать к черту такие ссылки


Не, я не хочу прикидываться браузером. Да и тот же cloudflare все равно не пропустит браузер без JS.

> Btw, если ты претендуешь на честность, тебе нужно уважать robots.txt.


Есть в TODO.

> Пожалуйста. Запусти да проверь.


> https://pastebin.com/VAmaBpLQ


> Ты увидишь "Есть два стула".


Это интересно, но я пока с такой проблемой все равно не сталкивался. Так да, можно повнимательнее разобрать 3xx коды.

> Из коробки! Три строчки кода! fopen, stream_get_meta_data, fclose!


А где объекты Response? Где разбор заголовков? Где задание корневых SSL-сертификатов? В Guzzle я просто пишу $response->getHeader() или $response->getStatusCode(), корневые сертификаты получаю другой библиотекой.

Ты бы код Гуззле открыл и посмотрел, что там понаписано. Она конечно местами переусложненная, но свои задачи решает, так что я не против.

> стандартную либу не знаете?


Она такая страшная, что к ней подходить лишний раз не хочется. И к тому же в исключения не умеет.

>>он умеет делать так: http://example.com/a/b + ../file.txt = http://example.com/file.txt


> Да ладно!


> if (strpos($href, '/') !== 0) { $url = realpath(dirname('http://example.com/a/b') . '/' . $url); } else { // да, для абсолютного пути придется пересобрать хост через parse_url с учетом возможного порта и даже логина-пароля }



Ну то есть надо изучать RFC про относительные ссылки и писать код. А я могу взять готовый код и ничего не писать. Какая мне выгода выбрать первый вариант? У меня есть вполне конкретные аргументы:

- экономия времени на написании кода и комментариев/документации к нему
- надежда, что код в библиотеке протестирован (в случае с Guzzle, у них есть тесты и подключен CI сервер, проверяющий коммиты)
- надежда, что сообщество будет править баги, закрывать уязвимости и поддерживать библилотеку. Я ничего не делаю, а баги исправляются. Разве это не прекрасно?

А завтра мне может понадобится параллельная отправка запросов (которая вроде как есть в Гуззл), это мне тоже все самому написать?

Какие у тебя есть аргументы за написание велосипеда? Не из серии "мне не нравится" или "надо RFC изучать", а объективные преимущества написания своего велосипеда в данном случае? Что я выигрываю?

> Если в готовой библиотеке находится уязвимость


То может быть, ее исправят без меня.

> Вы просто клепаете веб-приложушки из готовых модулей, а за моими плечами база.


У меня просто ограниченное количество времени.

> Если мне дать микроволновку, где будет крутиться Java Micro Edition и в либе только сокеты, я смогу сделать http-реквест и получить ответ, а вы не сможете ничего.


Я смогу, но не понимаю, зачем мне это нужно.

Вот кстати, я сейчас несколько часов угробил, пытаясь запустить firefox 3.5.19 под xvfb (он падает на старте скорее всего из-за современной версии glib), вот тебе бы, как любителю во всем разбираться, наверно было бы интересно исследовать проблему? Я конечно подумываю просто попрбовать еще другие версии фаерфокса. Или найти способ поставить как-то ему старый glib.

Там все настолько плохо, что даже отладочные символы для этой старой версии непонятно где искать. gdb малополезен, нужно разбираться с breakpad (или брать где-то Visual Studio, хотя дампы линуксовые), причем новый, естественно, не читает старые дампы, а старый еще замучаешься собирать. Про менеджеры пакетов сишники и не слышали (по задумке, надо использовать apt-get, но попробуй им поставь старую версию библиотеки или что-то, чего нет в репозитории). Ох, как просто с PHP работать в сравнении с этим сишно-яваскриптовым монстром.
791 1133351
>>33258

> И в чем его смысл, если этот интервал может истечь до завершения текущего запроса?


Смысл в том, чтобы не перегружать сторонний сервер запросами и тем самым снизить вероятность получения бана моего бота. Я хочу, чтобы запросы к определенному домену отправлялись бы не чаще, чем раз в N (сейчас N=3) секунд, если интервал будет больше - ничего страшного.

По факту, это да, интервал не между окончанием одного запроса и началом следующего, а между началом одного и второго. Пусть пока так будет.

> Никто никогда не напишет тебе issue про такие вещи


Значит, это никого не беспокоит.

> таймстамп последней проверки, пишем eTag, если имеется


Это будет вызывать ложные срабатывания, особенно если контент динамический и last modified нету или он постоянно увеличивается. Content-length будет меняться при изменении где-то в шапке, сайдбаре и тд.

У меня кстати была мысль интереснее: многие припаркованные домены подгружают ссылки через JS и их можно детектирвоать по отсутствию (или маленькому количеству) текста в HTML.

Про whois - да, вариант, хотя это требует подключать стороннюю библиотеку и разбираться с протоколом whois.

> Домен перерегистрирован? Подозрительность ссылки +1.


Это надо где-то держать историю проверок домена. Это снижает автономность инструмента.

> Днс поменялись на днс из словаря доменных парковок? Подозрительность ссылки +1.


Согласен, это можно.

> site.com/dsfjklsjfklsjdf отдавало 404, а теперь отдает 200, и Content-Length плюс-минус одинаков на любой странице?


Да, это тоже рабочий вариант, только не хочется слать запросы подряд на все домены, это надо как-то сначала отобрать "подозрительные" ссылки и их уже тщательнее проверять.

> А вообще веб должен быть доступен для любого клиента, поэтому можешь слать к черту такие ссылки


Не, я не хочу прикидываться браузером. Да и тот же cloudflare все равно не пропустит браузер без JS.

> Btw, если ты претендуешь на честность, тебе нужно уважать robots.txt.


Есть в TODO.

> Пожалуйста. Запусти да проверь.


> https://pastebin.com/VAmaBpLQ


> Ты увидишь "Есть два стула".


Это интересно, но я пока с такой проблемой все равно не сталкивался. Так да, можно повнимательнее разобрать 3xx коды.

> Из коробки! Три строчки кода! fopen, stream_get_meta_data, fclose!


А где объекты Response? Где разбор заголовков? Где задание корневых SSL-сертификатов? В Guzzle я просто пишу $response->getHeader() или $response->getStatusCode(), корневые сертификаты получаю другой библиотекой.

Ты бы код Гуззле открыл и посмотрел, что там понаписано. Она конечно местами переусложненная, но свои задачи решает, так что я не против.

> стандартную либу не знаете?


Она такая страшная, что к ней подходить лишний раз не хочется. И к тому же в исключения не умеет.

>>он умеет делать так: http://example.com/a/b + ../file.txt = http://example.com/file.txt


> Да ладно!


> if (strpos($href, '/') !== 0) { $url = realpath(dirname('http://example.com/a/b') . '/' . $url); } else { // да, для абсолютного пути придется пересобрать хост через parse_url с учетом возможного порта и даже логина-пароля }



Ну то есть надо изучать RFC про относительные ссылки и писать код. А я могу взять готовый код и ничего не писать. Какая мне выгода выбрать первый вариант? У меня есть вполне конкретные аргументы:

- экономия времени на написании кода и комментариев/документации к нему
- надежда, что код в библиотеке протестирован (в случае с Guzzle, у них есть тесты и подключен CI сервер, проверяющий коммиты)
- надежда, что сообщество будет править баги, закрывать уязвимости и поддерживать библилотеку. Я ничего не делаю, а баги исправляются. Разве это не прекрасно?

А завтра мне может понадобится параллельная отправка запросов (которая вроде как есть в Гуззл), это мне тоже все самому написать?

Какие у тебя есть аргументы за написание велосипеда? Не из серии "мне не нравится" или "надо RFC изучать", а объективные преимущества написания своего велосипеда в данном случае? Что я выигрываю?

> Если в готовой библиотеке находится уязвимость


То может быть, ее исправят без меня.

> Вы просто клепаете веб-приложушки из готовых модулей, а за моими плечами база.


У меня просто ограниченное количество времени.

> Если мне дать микроволновку, где будет крутиться Java Micro Edition и в либе только сокеты, я смогу сделать http-реквест и получить ответ, а вы не сможете ничего.


Я смогу, но не понимаю, зачем мне это нужно.

Вот кстати, я сейчас несколько часов угробил, пытаясь запустить firefox 3.5.19 под xvfb (он падает на старте скорее всего из-за современной версии glib), вот тебе бы, как любителю во всем разбираться, наверно было бы интересно исследовать проблему? Я конечно подумываю просто попрбовать еще другие версии фаерфокса. Или найти способ поставить как-то ему старый glib.

Там все настолько плохо, что даже отладочные символы для этой старой версии непонятно где искать. gdb малополезен, нужно разбираться с breakpad (или брать где-то Visual Studio, хотя дампы линуксовые), причем новый, естественно, не читает старые дампы, а старый еще замучаешься собирать. Про менеджеры пакетов сишники и не слышали (по задумке, надо использовать apt-get, но попробуй им поставь старую версию библиотеки или что-то, чего нет в репозитории). Ох, как просто с PHP работать в сравнении с этим сишно-яваскриптовым монстром.
792 1133352
>>33256

Первый способ требует ведь наличия аннотации для ParamsConverter? А так, используй, что тебе нравится.

>>33245

Зачем у тебя там quote, если ты ничего в БД не вставляешь? Ради чего ты экранируешь текст?

strlen не работает с кириллицей в utf-8, используй mb_strlen: https://github.com/codedokode/pasta/blob/master/php/strings-utf8.md

Перехватывать исключения (try/catch), чтобы распечатать, не нужно - можно просто включить display_errors = 1.

PDO использован неправильно ($category->execute), почитай статью по PDO. А то ощущение, что ты частично наугад код пишешь, так оно не заработает.

Вместо strftime лучше исопльзовать date().

>>33165

У тебя переусложнен код поиска элемента в массиве. ЧТобы найти значение элемента, имея ключ, надо сделать так: $value = $array[$key], цикл городить не надо.

>>33014

Там есть для этого пагинатор, который как-то хитро видоизменяет запрос: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/pagination.html (аналогичные статььи наверно можно найти на русском).

Но я ему не довряю, так как боюсь, что он там нагородит что-то сложное. Проще просто выбирать нужные тебе сущности без джойнов (то есть вместо SELECT x, y просто писать SELECT x). Да, там написано, что с джойном оно должно выбираться быстрее, но ты померяй - я наблюдал ровно обратную ситуацию.

Если тебе не нужны полные сущности (а например только id), то проще вообще SQL запрос сделать.
792 1133352
>>33256

Первый способ требует ведь наличия аннотации для ParamsConverter? А так, используй, что тебе нравится.

>>33245

Зачем у тебя там quote, если ты ничего в БД не вставляешь? Ради чего ты экранируешь текст?

strlen не работает с кириллицей в utf-8, используй mb_strlen: https://github.com/codedokode/pasta/blob/master/php/strings-utf8.md

Перехватывать исключения (try/catch), чтобы распечатать, не нужно - можно просто включить display_errors = 1.

PDO использован неправильно ($category->execute), почитай статью по PDO. А то ощущение, что ты частично наугад код пишешь, так оно не заработает.

Вместо strftime лучше исопльзовать date().

>>33165

У тебя переусложнен код поиска элемента в массиве. ЧТобы найти значение элемента, имея ключ, надо сделать так: $value = $array[$key], цикл городить не надо.

>>33014

Там есть для этого пагинатор, который как-то хитро видоизменяет запрос: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/pagination.html (аналогичные статььи наверно можно найти на русском).

Но я ему не довряю, так как боюсь, что он там нагородит что-то сложное. Проще просто выбирать нужные тебе сущности без джойнов (то есть вместо SELECT x, y просто писать SELECT x). Да, там написано, что с джойном оно должно выбираться быстрее, но ты померяй - я наблюдал ровно обратную ситуацию.

Если тебе не нужны полные сущности (а например только id), то проще вообще SQL запрос сделать.
793 1133353
>>32986

> А свойство с объектом PDO означает, что экземпляр имеет состояние?


нет, это не мешает ему быть "сервисом".

> >Фабрику можно внедрить в маппер через DI.


> вот так?


Нет, тогда уж так

$dbMapperFactory = new DBMapper($container['DBMapperFactory']);

>> почему я не предлагаю вместо фабрики внедрить в маппер сразу DI контейнер.


> Наверное потому, что JsonMapper'y не нужно создавать ничего кроме потомков определенного класса, и передача контейнера означала бы передачу большей ответственности, чем необходимо.


Да, и вообще, это нарушение идеи DI container, так как объекты о контейнере знать ничего не должны и не должны от него зависеть.

>>32945

Пользователей.

>>32922

Я думаю, можно просто посмотреть инструкции по установке в symfony-demo, скорее всего надо просто запустить композер и может что-то в конфиге подправить. Ну если ставить обычный шаблон (как тут http://symfony.com/doc/current/setup.html ) то примерно то же получишь. Я думаю, там тоже будет public/index.php и примерно те же классы.

>>33308

Справки бывают огромные, а тут нужные части уже найдены и вырезаны.
793 1133353
>>32986

> А свойство с объектом PDO означает, что экземпляр имеет состояние?


нет, это не мешает ему быть "сервисом".

> >Фабрику можно внедрить в маппер через DI.


> вот так?


Нет, тогда уж так

$dbMapperFactory = new DBMapper($container['DBMapperFactory']);

>> почему я не предлагаю вместо фабрики внедрить в маппер сразу DI контейнер.


> Наверное потому, что JsonMapper'y не нужно создавать ничего кроме потомков определенного класса, и передача контейнера означала бы передачу большей ответственности, чем необходимо.


Да, и вообще, это нарушение идеи DI container, так как объекты о контейнере знать ничего не должны и не должны от него зависеть.

>>32945

Пользователей.

>>32922

Я думаю, можно просто посмотреть инструкции по установке в symfony-demo, скорее всего надо просто запустить композер и может что-то в конфиге подправить. Ну если ставить обычный шаблон (как тут http://symfony.com/doc/current/setup.html ) то примерно то же получишь. Я думаю, там тоже будет public/index.php и примерно те же классы.

>>33308

Справки бывают огромные, а тут нужные части уже найдены и вырезаны.
794 1133387
Че, пацаны, когда бросаем PHP? Или все же он хорош, а не так как о нем говорят?
795 1133423
Чем отличается инструкция error_reporting(-1) от error_reporting(E_ALL)?
796 1133428
Функция принимает https://en.wikipedia.org/wiki/Mask_(computing)
-1 это битовая операция https://en.wikipedia.org/wiki/Ones'_complement

Лучше использовать E_ALL.
Посмотреть в живую:
echo decbin(E_ALL) . PHP_EOL;
echo decbin(-1) . PHP_EOL;
797 1133430
1229457489247.jpg233 Кб, 1000x819
798 1133624
>>25519
У меня случился отпуск. Хочу походить по собеседованиям. Но для этого, для начала, нужно откликнуться на вакансии. Вопрос: с моим уровнем (за полтора года смог немного выучить html, css, js, php, yii, mysql, git) можно откликаться только на самые днищевакансии стажёров, или уже можно чуть повыше? Какой примерно должна быть адекватная вакансия по требованиям и условиям?

Код работающего проекта:

>https://github.com/tsubaku/flights.yii



(Из того, что посоветовали на прошлом ревью, успел выполнить только треть, поэтому новых советов пока не прошу.)
799 1133631
>>33624
Папку scrinshots => screenshots. Просто первое что в глаза бросается. Сразу все "английский на уровне понимания документации" под вопросом.
800 1133632
>>33631
Ох лол, вот это обосрался. Но вообще да, английский знаю плохо.
801 1133644
>>33624
походи по собесам, поймешь что нужно будет подучить. я бы пошел на 60к посмотрел (в дс), если совсем не потянешь, то снижать планку. плюс определись, какие технологии тебе интересны и не разбрасывайся на остальные (очевидно в твоем случае это yii).

по проекту, по моему опыту такие проекты на собеседованиях никто особо не смотрят, может поставят галочку в голове типа "учится-интересуется", но вообще всем похуй. еще вариант: могут ткнуть в случайное место, увидеть какой-то один косяк и сделать по нему преждевременные выводы.

если будешь показывать этот проект, удали все ненужные комментарии в коде, их там больше половины от всего проекта. все "было-стало" видно по коммитам, такие комменты бессмысленны. также в качестве коммит-меседжей пишут "добавил штуку такую-то", а не номер версии. еще отформатируй ридми, в одной строке текст и картинка не комильфо.
802 1133654
>>33631

>scrinshots => screenshots


Исправил.
>>33644

>"было-стало" видно по коммитам, такие комменты бессмысленны


Это где такие комменты? Хотя, наверное есть. Завтра на свежую голову всё прогляжу и удалю лишнее.

>в качестве коммит-меседжей пишут "добавил штуку такую-то", а не номер версии


Ты прав, надо будет начать писать более содержательные месседжи.

>еще отформатируй ридми


Отформатировал.

>я бы пошел на 60к


Окей, от этой цифры и буду отталкиваться.
803 1133666
>>33624
Откликайся на всё. Я без опыта откликнулся на вакансию на 70к, написал тест, мне еще сказали, что по результатам я опытный мидл, лол. Приняли без вопросов.
Единственно, что я все-таки полупридумал предыдущее место работы. Два года назад написал сайт для организации, прямо как ты, и написал - опыт работы два года, ООО Ромашка.
804 1133669
>>33666

>опыт работы два года


>>33631

>"английский на уровне понимания документации" под вопросом.


Откуда вы это взяли? Я ведь оставлял только гитхаб, а не резюме на хх? Там именно это и написано, но ссылку же не оставлял, откуда ни знают?!
805 1133670
>>33624

> $row_content['fakticheskij_srok_dostavki']



Pozhalujsta, vyuchi anglijskij.
806 1133673
>>33669

>Там именно это и написано


Осторожнее с этим дерьмом. У меня было указано то же самое. И мне дали тест на английском. А когда приняли, посадили на мультиязычный проект, где надо писать все строковые литералы на русском, и на английском. Пишу на ломаном английском, тимлид пока не доебывается.
807 1133696
>>33670

>$row_content['faktu4eskuu_crok_doctabku']

808 1133698
>>33654

>Это где такие комменты? Хотя, наверное есть. Завтра на свежую голову всё прогляжу и удалю лишнее.



завтра тебя ждет сюрприз
809 1133713
>>33673
Дословно там стоит галочка на "Английский — читаю профессиональную литературу". И это правда. Читать-то я могу. А вот писать...
>>33698
Что там не так? Если там прям бомба, то может напишешь мне но почту r54Oa]52ANUSmai>^1lPUNCTUMrM1au о ней?
810 1133764
>>33713
там ничего секретного, просто ОЧЕНЬ много комментариев вида
#$arr1 = 22;
//$arr2 - вчера работало

и прочего. на работе твой код будет проверяться по строчке и по символу (если ты не будешь работать в дизайн-студии, конечно). если есть кодстайл, то по нему ебут даже за переводы строк в неправильных местах. так что учитывай, что это будут смотреть такие вот чуваки.

для джуна это все конечно придирки,
но и возможность заработать плюсик
811 1133770
>>33764
Уф, анон, ты даже не представляешь, на какую измену я подсел. Думал уже, в репу пробралось что-то из продакшен-версии. А там реальные фамилии, названия фирм заказчиков и прочая ботва. И вроде все данные в базе были, но а вдруг...

Надо и вправду причесать всё хоть как-то. Когда один пишешь, все эти комменты таки помогают. Хотя бы уже тем, что можешь быстро вспомнить, где какие косяки. Но для показа, лучше будет хотя бы создать видимость, что с этим можно работать коллегиально.
812 1133789
>>33770
это не значит, что ничего не просочилось. просто я посмотрел три класса и там везде было вот такое. при твоем вольном отношении к коду возможно, что где-то лежит

>//Кротов Сергей 4500 224331 перезвонить по телефону 3215411



надо разок так обосраться, чтобы потом поменять отношение. я когда первый аудит проходил, вообще не понимал нахуй он нужен - у меня же все нормально! оказалось, я похерил все, что можно было похерить.
813 1133839
Мой очередной нубский вопрос про предназначение middleware. Сейчас делаю задачку на файлообменник на слиме и думаю, как лучше проверять файлы, приходящие из формы. Создавать класс-валидатор, который будет смотреть сколько файлов было отправлено, их размер и т.д. , или все это через middleware можно сделать?
814 1133963
Анон, я тут копаюсь в MODX.

Есть шаблон сайта, который юзает контора. CMS нужно указать, где находится папка core от корня.

Как мы делаем: закидываем файл с выводом результата команды <? __DIR__; ?> в public_html и потом дописываем до конца.

Короч, если ты не понял, что я несу, то сам вопрос таков:
Есть ли какая-то встроенная функция, чтобы от результата __DIR__ можно было отрезать часть пути с конца?
815 1133973
>>33963

Изучи мануал по

basename
dirname
realpath

Также, можно использовать в пути .., который значит "подняться на папку вверх": http://phpfaq.ru/newbie/paths
816 1133975
>>33973
Благодарствую.
817 1134247
Осваиваю WordPress, хочу разобраться с правильным редактированием тем (то есть, через дочерние темы), чтобы изменения не слетали при обновлении темы. Но вот какая беда: не могу найти старую версию какой-нибудь темы, которая предложила бы мне обновиться. Скачал с гита Chronus Версия: 1.1, WP через каталог предлагает установить 1.2.3, но при этом предложения обновиться нет.

ЧЯДНТ? Скиньте мне, пожалуйста, какую-нибудь тему, которая желала бы обновиться, чтобы я смог изучить этот вопрос.
818 1134333
>>34247
Здесь обсуждается программирование, а не вордрес. Лучше зайди в /web и там спроси в вордпрес треде
819 1134363
>>34333

Не, вопрос вполне нормальный. Он же спрашивает для того, чтобы протестировать сценарий обновления.

>>34247

Попробуй зайти на сайт темы и поискать раздел вроде releases. Может там есть старые версии.

Ну вот я например взял эту тему https://ru.wordpress.org/themes/belise-lite/ и нажал ссылку "Просмотреть в Trac" - https://themes.trac.wordpress.org/browser/belise-lite/ и тут есть папочки с разными версиями.

Они используют при разработке систему контроля версий (svn), гигантский репозиторий со всеми темами ( https://themes.svn.wordpress.org/belise-lite/ ). Наверно из нее как-то можно вытянуть старую версию, если разобраться. Вот тут что-то такое описывают: https://wordpress.stackexchange.com/questions/65056/how-to-get-themes-from-wordpress-com-per-svn

Также, тут описан другой способ: https://www.competethemes.com/blog/download-older-version-plugins-themes/
820 1134540
Если бы не подсказки к задачам я бы хуй сделал что-то сам.
821 1134546
>>34540
это норма. я так же делал. сейчас уже эти задачки кажутся простыми. просто делай дальше и больше.
822 1134547
>>34540

Если ты чувствуешь, что не до конца разобрался в какой-то теме, можно попросить усложненную задачку, чтобы ты мог убедиться, что ты с ней справишься и не беспокоиться.
823 1134788
Друзья, подскажите, что можно почитать по теме распарсивания выражений типа "(((ID = 14) OR ((COUNTRY = USA) AND (ID < 4)))" в исполняемый код.

Имеется в виду как правильно распарсить вложенные скобки, преобразовать в простые логические условия, провалидировать в корректном ли порядке они идут и т.д.
824 1134792
>>34788
И еще вопрос: есть же наверное какие-то библиотеки, которые этим занимаются? Или может бандлы для Симфони?
825 1134979
Пользовался кто AWS? Жалко платить за платные VPN, думаю арендовать AWS и поднять там на докере OpenVPN + ещё для всяких тестов будет тачка практически личная.
Из минусов - стремаюсь на свою карточку регать аккаунт после статьи https://geektimes.ru/post/247794/ , что скажете?
https://github.com/TheSidSpears/testhub/ 826 1135039
>>1118051
>>18558

Я увидел, что там используется KnpPagination, описание у него подозрительное, решил посмотреть его код и как чувствовал - нашел сомнительное место (использование $_GET):

- https://github.com/KnpLabs/knp-components/blob/master/src/Knp/Component/Pager/Paginator.php#L98
- https://github.com/KnpLabs/knp-components/blob/master/src/Knp/Component/Pager/Event/Subscriber/Sortable/ArraySubscriber.php#L48
- https://github.com/KnpLabs/knp-components/blob/master/src/Knp/Component/Pager/Event/Subscriber/Sortable/Doctrine/ORM/QuerySubscriber.php

Впрочем, они уже о проблеме знают: https://github.com/KnpLabs/knp-components/issues/160

А что там подозрительного? А подозрительно то, что они в ридми в примере кода указывают на возможность сортировки, но 1) нигде не передаются параметры сортировки и 2) белый список полей: https://github.com/KnpLabs/KnpPaginatorBundle

То, что параметр сортировки не передается из Request - значит, они сами откуда-то его берут (из $_GET в данном случае). Если не задан белый список полей - значит, что это может создать уязвимость, позволяющую злоумышленнику угадывать значеия скрытых полей в таблице.

Поясню. Допустим, у нас на сайте есть список пользователей с возможностью сортировки, и мы можем делать сортировку по любому полю. Допустим, мы хотим узнать email пользователя, который не выводится на сайте. Мы регистрируем аккаунты {QPaANUSexampleZckPUNCTUMcPNjom, n>CnANUSexaF[SmplePUNCTUMcCQhom, zl^3ANUSesZ$xamplePUNCTUMcrp!om и используя сортировку списка по email, определяем, в каком диапазоне (a-n или n-z) лежит первая буква списка. Затем сужаем диапазон и так примерно за сотню-две попыток получаем нужный email.

Разумеется, этот же принцип можно применить для подбора значения любого другого скрытого поля, включая хеш пароля, если нам известен механизм хеширования. Если он не известен, можно подбирать какой-нибудт токен или что-нибудь еще.

То есть сортировка без белого списка полей, если она там включена по умолчанию - это уязвимость.

Плюс, вот такой вот issue нашелся: https://github.com/KnpLabs/KnpPaginatorBundle/issues/386

-----

https://github.com/TheSidSpears/test_hub/blob/master/src/Controller/TestController.php#L38
Не стоит так экономить на строчках, получение $searchForm лучше сделать отдельной строкой.

https://github.com/TheSidSpears/test_hub/blob/master/src/Entity/Tag.php#L57
Вроде бы на такой случай есть аннотация iterable: http://php.net/manual/ru/language.types.iterable.php

Тестов что-то совсем не добавилось.

https://github.com/TheSidSpears/test_hub/blob/master/src/Entity/User.php#L74
Вот это гиблая идея, парсить на коленке имена. Бывают наверно имена более чем из 2 слов. Лучше сделать так: public function setName($firstName, $lastName). Или хранить данные как введены.

https://github.com/TheSidSpears/test_hub/blob/master/src/Entity/User.php#L84

> public function __toString()


Я бы советовал избегать __ToString. Он помогает скрыть информацию об ошибке, молча преобразуя объект в строку. В ситуациях вроде:

function doStmh(string $email) { }
doSmth($user)

или echo "Email = " . $user;

Если метода __toString нет, то оба примера выше выдадут ошибку.

https://github.com/TheSidSpears/test_hub/blob/master/src/Repository/TagRepository.php#L19

> SELECT t FROM ' . Tag::class . ' t');


Не удобнее ли писать 'SELECT t FROM Tag t' ?

https://github.com/TheSidSpears/test_hub/blob/master/templates/tags/list.html.twig#L28

> {% if tags.getTotalItemCount == 1 %}


> {% set tagWithSuffix = 'tag' %}


Может тебе посмотреть в расширения для локализации? Там должен быть синтаксис для форматирования строк с учетом особенностей языка. Например, в расширении Intl используется такой немного громоздкий синтаксис:

http://userguide.icu-project.org/formatparse/messages

>"{num_guests, plural, offset:1 "


> "=0 {{host} does not give a party.}"


> "=1 {{host} invites {guest} to her party.}"


> "=2 {{host} invites {guest} and one other person to her party.}"


> "other {{host} invites {guest} and # other people to her party.}}}"



903 килобайта JS в build/app.js - не слишком ли много?
https://github.com/TheSidSpears/testhub/ 826 1135039
>>1118051
>>18558

Я увидел, что там используется KnpPagination, описание у него подозрительное, решил посмотреть его код и как чувствовал - нашел сомнительное место (использование $_GET):

- https://github.com/KnpLabs/knp-components/blob/master/src/Knp/Component/Pager/Paginator.php#L98
- https://github.com/KnpLabs/knp-components/blob/master/src/Knp/Component/Pager/Event/Subscriber/Sortable/ArraySubscriber.php#L48
- https://github.com/KnpLabs/knp-components/blob/master/src/Knp/Component/Pager/Event/Subscriber/Sortable/Doctrine/ORM/QuerySubscriber.php

Впрочем, они уже о проблеме знают: https://github.com/KnpLabs/knp-components/issues/160

А что там подозрительного? А подозрительно то, что они в ридми в примере кода указывают на возможность сортировки, но 1) нигде не передаются параметры сортировки и 2) белый список полей: https://github.com/KnpLabs/KnpPaginatorBundle

То, что параметр сортировки не передается из Request - значит, они сами откуда-то его берут (из $_GET в данном случае). Если не задан белый список полей - значит, что это может создать уязвимость, позволяющую злоумышленнику угадывать значеия скрытых полей в таблице.

Поясню. Допустим, у нас на сайте есть список пользователей с возможностью сортировки, и мы можем делать сортировку по любому полю. Допустим, мы хотим узнать email пользователя, который не выводится на сайте. Мы регистрируем аккаунты {QPaANUSexampleZckPUNCTUMcPNjom, n>CnANUSexaF[SmplePUNCTUMcCQhom, zl^3ANUSesZ$xamplePUNCTUMcrp!om и используя сортировку списка по email, определяем, в каком диапазоне (a-n или n-z) лежит первая буква списка. Затем сужаем диапазон и так примерно за сотню-две попыток получаем нужный email.

Разумеется, этот же принцип можно применить для подбора значения любого другого скрытого поля, включая хеш пароля, если нам известен механизм хеширования. Если он не известен, можно подбирать какой-нибудт токен или что-нибудь еще.

То есть сортировка без белого списка полей, если она там включена по умолчанию - это уязвимость.

Плюс, вот такой вот issue нашелся: https://github.com/KnpLabs/KnpPaginatorBundle/issues/386

-----

https://github.com/TheSidSpears/test_hub/blob/master/src/Controller/TestController.php#L38
Не стоит так экономить на строчках, получение $searchForm лучше сделать отдельной строкой.

https://github.com/TheSidSpears/test_hub/blob/master/src/Entity/Tag.php#L57
Вроде бы на такой случай есть аннотация iterable: http://php.net/manual/ru/language.types.iterable.php

Тестов что-то совсем не добавилось.

https://github.com/TheSidSpears/test_hub/blob/master/src/Entity/User.php#L74
Вот это гиблая идея, парсить на коленке имена. Бывают наверно имена более чем из 2 слов. Лучше сделать так: public function setName($firstName, $lastName). Или хранить данные как введены.

https://github.com/TheSidSpears/test_hub/blob/master/src/Entity/User.php#L84

> public function __toString()


Я бы советовал избегать __ToString. Он помогает скрыть информацию об ошибке, молча преобразуя объект в строку. В ситуациях вроде:

function doStmh(string $email) { }
doSmth($user)

или echo "Email = " . $user;

Если метода __toString нет, то оба примера выше выдадут ошибку.

https://github.com/TheSidSpears/test_hub/blob/master/src/Repository/TagRepository.php#L19

> SELECT t FROM ' . Tag::class . ' t');


Не удобнее ли писать 'SELECT t FROM Tag t' ?

https://github.com/TheSidSpears/test_hub/blob/master/templates/tags/list.html.twig#L28

> {% if tags.getTotalItemCount == 1 %}


> {% set tagWithSuffix = 'tag' %}


Может тебе посмотреть в расширения для локализации? Там должен быть синтаксис для форматирования строк с учетом особенностей языка. Например, в расширении Intl используется такой немного громоздкий синтаксис:

http://userguide.icu-project.org/formatparse/messages

>"{num_guests, plural, offset:1 "


> "=0 {{host} does not give a party.}"


> "=1 {{host} invites {guest} to her party.}"


> "=2 {{host} invites {guest} and one other person to her party.}"


> "other {{host} invites {guest} and # other people to her party.}}}"



903 килобайта JS в build/app.js - не слишком ли много?
827 1135041
>>18712

Нужно знание линукса и основных команд.

>>18828

Использовать тип позиционирования, для которого размер по умолчанию определяется содержимым. Например:

- display: inline-block без заданных размеров
- float: left
- position: absolute
- display: table

>>18958

Это зависит от того, как ты настроишь. В контейнере может быть много процессов.

> Или посоветуйте что-то для быстрого деплоя/развертывания одного проекта на N-нод


Деплой PHP кода или деплой нгинксов? Второе можно поручить админу, для первого использовать ansible.

>>19604

Ты не написал, какой командой ты пытаешься ее создавать, что пишет эта команда. По идее конечно должно работать и с аннотациями. Также, не забыл ли ты правильно указать use при использовании аннотаций? Он иведь тоже в неймспейсах находятся.

>>19631

PDO занимается только соединением с БД и отправкой в нее запросов. Надо дописать свой код, который будет брать полученные из формы данные и формировать на их основе SQL запрос.

>>19912

Нужен супервизор, который будет перезапускать скрипт при падении. Ловить исключение и перезапускать функцию - плохая идея, так как состояние программы может быть неправильным и будет накапливаться ошибки.
827 1135041
>>18712

Нужно знание линукса и основных команд.

>>18828

Использовать тип позиционирования, для которого размер по умолчанию определяется содержимым. Например:

- display: inline-block без заданных размеров
- float: left
- position: absolute
- display: table

>>18958

Это зависит от того, как ты настроишь. В контейнере может быть много процессов.

> Или посоветуйте что-то для быстрого деплоя/развертывания одного проекта на N-нод


Деплой PHP кода или деплой нгинксов? Второе можно поручить админу, для первого использовать ansible.

>>19604

Ты не написал, какой командой ты пытаешься ее создавать, что пишет эта команда. По идее конечно должно работать и с аннотациями. Также, не забыл ли ты правильно указать use при использовании аннотаций? Он иведь тоже в неймспейсах находятся.

>>19631

PDO занимается только соединением с БД и отправкой в нее запросов. Надо дописать свой код, который будет брать полученные из формы данные и формировать на их основе SQL запрос.

>>19912

Нужен супервизор, который будет перезапускать скрипт при падении. Ловить исключение и перезапускать функцию - плохая идея, так как состояние программы может быть неправильным и будет накапливаться ошибки.
828 1135042
>>19932

Я не очень разбираюсь в диаграммах, но мне кажется, у тебя ошибка. Ты используешь ER диаграмму в нотации crow's foot (кроме нее есть еще другие способы обозначать отношения: https://en.wikipedia.org/wiki/Entity–relationship_model#Cardinalities ). На ней мы отображаем сущности и связи между ними. bridge - это не сущность, это промежуточная таблица, которая нужна для реализации связи многие-ко-многим в SQL.

На всякий случай, вот тут есть хорошее объяснение, что значат разные пометки: http://www2.cs.uregina.ca/~bernatja/crowsfoot.html

У тебя пометка около tag не соответствует перечисленным.

Соответственно, на диаграмме должно быть 2 сущности, Пост и Тег и связь (Пост) "отмечен" (Тегами).

Какие свойства этой связи?

- Пост может быть отмечен 0, 1 или многими Тегами
- у Тега может быть 1 или более постов. Тега без постов не существует.

>>19939
>>19947
>>19954

Объяснение тут: http://www2.cs.uregina.ca/~bernatja/crowsfoot.html

Две палочки значат "от 1 до 1". Одна палочка может быть в сочетании с кругом (снаружи) - от 0 до 1 или с лапкой (внутри) - от 1 и более.
829 1135043
>>20065

Можно было бы в setRank() поставить защиту от установки неправильного ранга с выбрасыванием исключения (если ранг < 1 или > 3).

Давай, ради расширения кругозора, ты попробуешь сделать максимально параноидальный код, который проверяет все параметры на разумность. Ну например, чтобы нельзя было попытаться выставить отрицательную зарплату или удалить работника, который не работает в этом департаменте.

Это поможет тебе увидеть, как ООП и инкапсуляция (закрытие доступа к полям извне) позволяют сделать защищенный от ошибок код, который в любой ситуации работает корректно, даже при попытке подать на вход некорреткные данные.

Говоря о корретности программы, есть еще один интересный подход - Value Objects. Суть его в том, что мы могли бы для отдельных значений в нашей программе вроде ранга создать классы - класс Rank, который оборачивает число (то есть это класс с единственным неизменяемым приватным полем rank, которое задается в конструкторе. Он должен быть неизменным после создания). В чем плюс?

- мы можем гарантировать корректность значения. Например, прямо в конструкторе Rank поставить проверку, что он должен быть от 1 до 3 и не позволять создавать некорректный ранг. В этом случае, если у нас есть объект Rank, то это значит, что ранг в нем 100% корректный.
- мы можем задать допустимый набор действий с значением с помощью методов. Ну например, мы можем не выдавать ранг как число наружу, а сделать только методы вроде $rank->isEqual(1) и $rank->increase(2) и тем самым запретить перемножать ранги (с обычным числом по ошибке это можно сделать). При изменении ранга через методы мы можем предоставратить получение неправильных значений (повысить 3-й ранг до 4-го)
- мы можем ставить тайп-хинты и писать например setRank(Rank $rank) и это не позволит передать в функцию что-то, кроме ранга (зарплату например). В случае int $rank такой защиты нет. Также такие тайп-хинты делают код еще понятнее.
- мы можем защищаться от ошибок, связанных с единицами измерения. Если у нас время выражено числом, то в чем оно измеряется? В часах, минутах, секундах, миллисекундах? Если длина, то в метрах или футах? Если момент времени, то в каком часовом поясе? В случае с ValueObject единица измерения известна и мы можем сделать методы $time->getAsSeconds(), $time->getAsHours(), защищая себя от ошибок при ручной конвертации.
- мы можем делать полезные вспомогательные методы, например, для времени мы можем сделать метод $time->diff($otherTime), вычисляющий разницу между 2 точками во времени.

В чем минус?

- сильно раздувается объем кода

Иммутабельность нужна, чтобы защититься от ошибок, когда мы меняем использующийся в нескольких местах объект.

Может, ты захочешь тут применить этот паттерн. Он обычно применяется для простых знаечний вроде Денег, Времени, Точек (координат), Цветов. В PHP есть классы DateTimeImmutable и DateImmutable.

- http://design-pattern.ru/patterns/value-object.html
- https://martinfowler.com/bliki/ValueObject.html (сложно)

> public function getWorker(int $key): AbstractWorker


> public function deleteWorker(int $key): void


Это не очень удачные методы, так как непонятно, где брать этот key. У работника ведь нет метода getKey(). Но он и не нужен - работник сам по себе имеет идентичность и можно просто передавать объект в deleteWorker.

> public function selectWorkers(string $profession): array


Не хочешь подумать над универсальной функцией поиска по произвольным критериям?

> $workersOfCertainProfession = array();


Можно просто $result.

> public function changeBoss(int $oldBoss, int $newBoss)


Та же проблема. Передаются какие-то непонятные инты, которые непонятно где брать.

> class HiringWorkers


Этот класс мог бы хранить в себе (или принимать через конструктор) базовые значения зарплат, чтобы не дублировать их многократно.

> $department->selectWorkers("Engineer");


Лучше Engineer::class

> for ($i = 0; $i < count($workersOfCertainProfession) - 2; $i++){


> if ($workersOfCertainProfession[$i]->getRank() > $workersOfCertainProfession[$i+1]->getRank()){


> $buf = $workersOfCertainProfession[$i];


> $workersOfCertainProfession[$i] = $workersOfCertainProfession[$i+1];



Сортировка пузырьком??? Во-первых, ее надо выносить в отдельный метод (чтобы не ухудшать читабельность кода и не раздувать функцию), во-вторых, используй usort с анонимной функцией.

> ceil(count($workersOfCertainProfession) / 2.5));


В задании было написано 40%, а ты заменил его на 2.5, в итоге я секунд 10 думал, откуда тут эта цифра. Лучше было умножать на 0.4 или на $engineerCutPercent.

Цикл удаления переусложнен из-за того, что твой код требует определить key работника, а это просто не сделать. Код мог бы быть проще и короче.

> changeDataAnalytics


Тут отбор аналитиков можно было сделать функцией. Также, функцию смены босса можно было спроектирвоать более удачно и код был бы проще и аккуратнее. Попробуй написать прототип (заголовок) функции замены босса, не думая о том, как устроен Департамент внутри и как там хранятся работники. Как бы ты ее записал?

> $worker->setRank($worker->getRank()+1);


Возможно, есть смысл сделать метод повышения работника.

В общем, для упрощения антикризисного кода я бы советовал улучшить:

- функцию поиска работников
- функцию увольнения
- функцию замены босса
- переделать сортировку
829 1135043
>>20065

Можно было бы в setRank() поставить защиту от установки неправильного ранга с выбрасыванием исключения (если ранг < 1 или > 3).

Давай, ради расширения кругозора, ты попробуешь сделать максимально параноидальный код, который проверяет все параметры на разумность. Ну например, чтобы нельзя было попытаться выставить отрицательную зарплату или удалить работника, который не работает в этом департаменте.

Это поможет тебе увидеть, как ООП и инкапсуляция (закрытие доступа к полям извне) позволяют сделать защищенный от ошибок код, который в любой ситуации работает корректно, даже при попытке подать на вход некорреткные данные.

Говоря о корретности программы, есть еще один интересный подход - Value Objects. Суть его в том, что мы могли бы для отдельных значений в нашей программе вроде ранга создать классы - класс Rank, который оборачивает число (то есть это класс с единственным неизменяемым приватным полем rank, которое задается в конструкторе. Он должен быть неизменным после создания). В чем плюс?

- мы можем гарантировать корректность значения. Например, прямо в конструкторе Rank поставить проверку, что он должен быть от 1 до 3 и не позволять создавать некорректный ранг. В этом случае, если у нас есть объект Rank, то это значит, что ранг в нем 100% корректный.
- мы можем задать допустимый набор действий с значением с помощью методов. Ну например, мы можем не выдавать ранг как число наружу, а сделать только методы вроде $rank->isEqual(1) и $rank->increase(2) и тем самым запретить перемножать ранги (с обычным числом по ошибке это можно сделать). При изменении ранга через методы мы можем предоставратить получение неправильных значений (повысить 3-й ранг до 4-го)
- мы можем ставить тайп-хинты и писать например setRank(Rank $rank) и это не позволит передать в функцию что-то, кроме ранга (зарплату например). В случае int $rank такой защиты нет. Также такие тайп-хинты делают код еще понятнее.
- мы можем защищаться от ошибок, связанных с единицами измерения. Если у нас время выражено числом, то в чем оно измеряется? В часах, минутах, секундах, миллисекундах? Если длина, то в метрах или футах? Если момент времени, то в каком часовом поясе? В случае с ValueObject единица измерения известна и мы можем сделать методы $time->getAsSeconds(), $time->getAsHours(), защищая себя от ошибок при ручной конвертации.
- мы можем делать полезные вспомогательные методы, например, для времени мы можем сделать метод $time->diff($otherTime), вычисляющий разницу между 2 точками во времени.

В чем минус?

- сильно раздувается объем кода

Иммутабельность нужна, чтобы защититься от ошибок, когда мы меняем использующийся в нескольких местах объект.

Может, ты захочешь тут применить этот паттерн. Он обычно применяется для простых знаечний вроде Денег, Времени, Точек (координат), Цветов. В PHP есть классы DateTimeImmutable и DateImmutable.

- http://design-pattern.ru/patterns/value-object.html
- https://martinfowler.com/bliki/ValueObject.html (сложно)

> public function getWorker(int $key): AbstractWorker


> public function deleteWorker(int $key): void


Это не очень удачные методы, так как непонятно, где брать этот key. У работника ведь нет метода getKey(). Но он и не нужен - работник сам по себе имеет идентичность и можно просто передавать объект в deleteWorker.

> public function selectWorkers(string $profession): array


Не хочешь подумать над универсальной функцией поиска по произвольным критериям?

> $workersOfCertainProfession = array();


Можно просто $result.

> public function changeBoss(int $oldBoss, int $newBoss)


Та же проблема. Передаются какие-то непонятные инты, которые непонятно где брать.

> class HiringWorkers


Этот класс мог бы хранить в себе (или принимать через конструктор) базовые значения зарплат, чтобы не дублировать их многократно.

> $department->selectWorkers("Engineer");


Лучше Engineer::class

> for ($i = 0; $i < count($workersOfCertainProfession) - 2; $i++){


> if ($workersOfCertainProfession[$i]->getRank() > $workersOfCertainProfession[$i+1]->getRank()){


> $buf = $workersOfCertainProfession[$i];


> $workersOfCertainProfession[$i] = $workersOfCertainProfession[$i+1];



Сортировка пузырьком??? Во-первых, ее надо выносить в отдельный метод (чтобы не ухудшать читабельность кода и не раздувать функцию), во-вторых, используй usort с анонимной функцией.

> ceil(count($workersOfCertainProfession) / 2.5));


В задании было написано 40%, а ты заменил его на 2.5, в итоге я секунд 10 думал, откуда тут эта цифра. Лучше было умножать на 0.4 или на $engineerCutPercent.

Цикл удаления переусложнен из-за того, что твой код требует определить key работника, а это просто не сделать. Код мог бы быть проще и короче.

> changeDataAnalytics


Тут отбор аналитиков можно было сделать функцией. Также, функцию смены босса можно было спроектирвоать более удачно и код был бы проще и аккуратнее. Попробуй написать прототип (заголовок) функции замены босса, не думая о том, как устроен Департамент внутри и как там хранятся работники. Как бы ты ее записал?

> $worker->setRank($worker->getRank()+1);


Возможно, есть смысл сделать метод повышения работника.

В общем, для упрощения антикризисного кода я бы советовал улучшить:

- функцию поиска работников
- функцию увольнения
- функцию замены босса
- переделать сортировку
830 1135044
>>20112

Тайп хинты есть с 5 версии, в 7 значительно улучшены: http://php.net/manual/ru/functions.arguments.php#functions.arguments.type-declaration

>>20286

Давай по частям.

> свойства, которое хранится как массив, а в БД как json.


Это надо делать не в форме, это надо делать в Доктрине. В ней создаешь свой кастомный тип данных, ставишь его полю и пишешь, как преобразовывать значения поля при загрузке/записи в БД. Может даже такой тип уже написан кем-то.

Но конечно я бы тут применил ООП и сделал массив объектов Property. В этом случае может быть это даже работало бы с CollectionType без преобразований.

Что касается форм, то да, Data Transformer тут бы подошел. Либо можно написать свой FormType для работы с таким типом данных.

>>20332

Есть в мануале https://dev.mysql.com/doc/refman/5.5/en/optimizing-innodb-bulk-data-loading.html

>>20355

Вообще не, внутри [] круглые скобки не имеют специального значения.

>>20471

Это наверно не совсем то, что ты хотел, но:

1) http://php.net/manual/ru/language.basic-syntax.phpmode.php
2) https://github.com/codedokode/pasta/blob/master/php/templates.md
830 1135044
>>20112

Тайп хинты есть с 5 версии, в 7 значительно улучшены: http://php.net/manual/ru/functions.arguments.php#functions.arguments.type-declaration

>>20286

Давай по частям.

> свойства, которое хранится как массив, а в БД как json.


Это надо делать не в форме, это надо делать в Доктрине. В ней создаешь свой кастомный тип данных, ставишь его полю и пишешь, как преобразовывать значения поля при загрузке/записи в БД. Может даже такой тип уже написан кем-то.

Но конечно я бы тут применил ООП и сделал массив объектов Property. В этом случае может быть это даже работало бы с CollectionType без преобразований.

Что касается форм, то да, Data Transformer тут бы подошел. Либо можно написать свой FormType для работы с таким типом данных.

>>20332

Есть в мануале https://dev.mysql.com/doc/refman/5.5/en/optimizing-innodb-bulk-data-loading.html

>>20355

Вообще не, внутри [] круглые скобки не имеют специального значения.

>>20471

Это наверно не совсем то, что ты хотел, но:

1) http://php.net/manual/ru/language.basic-syntax.phpmode.php
2) https://github.com/codedokode/pasta/blob/master/php/templates.md
831 1135045
>>21098

Не знаю, в чем проблема. А что, если открыть страницу в браузере, потом открыть ее исходный HTML код (меню или Ctrl + U) и сравнить с первоначальным HTML?

Также, доктайп бы не помешал.

>>22056

есть, погугли drag and drop file upload

>>22230

https://repl.it/repls/NippyGraciousCrayfish

Подсказка: getNormalHours проще посчитать как общее число часов минус переработка.

А так, решено верно.

>>22272

ВЫзовом внешней программы-проигрывателя.

>>22460

Можно попробовать выставить какие-то агрессивные параметры кеширования для страницы и ресурсов к ней - тогда браузер сможет открыть ее из кеша, если она там будет лежать. Но это не гарантированно.
832 1135047
>>22782

> Я тебя правильно понял? https://github.com/TheSidSpears/test_hub/commit/48de6c290d05ca63a48a5aa7bf8fbf67fb67fb5f


Да.

> В этом файле стандартные переменные APP_ENV и DATABASE_URL. Зачем их переименовывать и как их система прочтет? (в этом разобраться самому)


ну я предлагал добавить префиксы, чтобы было видно, от какого приложения эти переменные и чтобы они не конфликтоваи с другими. Может, и не стоит заморачиваться конечно.

> Нужно тестировать репозитории на копии основной БД? А как держать эту БД актуальной? Это ж нужно миграции и там и там проводить. Как-то не удобным это кажется



В идеале - тестовая БД, которая заполняется перед тестами. Миграции руками проводить не надо, надо все автоматизировать.

Да, это сложновато, ну а как без этого тестировать код, завязанный на БД? Не делать же полноценную эмуляцию всей SQL-базы данных. Ну и без этого тебе ведь руками все тестировать придется.

Это ты еще до браузерного тестирования и селениума не дошел, там еще сложнее.

> Нет, эти 2 ф-ии используются исключительно для заполнения Fixtures


Тогда ок.

> Я попытался разобраться https://drive.google.com/file/d/1Gvt38WwASpFcdFU3z9ZDuvrZ3pfaWbun/view?usp=sharing


> Видимо, не подойдёт


А ты попробуй код написать ;)

Например, $repo->findBy(['tag' => $tags]) или findByTag($tags) и посмогтреть что он найдет и какой SQL запрос сформирует.

> В нём определяется какой-то persister


Судя по названию, это объект для сохранения (persist) сущностей в БД.

> Видим, что класс зависит от `InheritanceType`. Названия классов намекают, будет ли проходить поиск по конкретной таблице или по объединенной (joined)


Да, это для разных вариантов наследования таблиц вроде http://design-pattern.ru/patterns/class-table-inheritance.html .

>> Вот это мне не нравится. У тебя переменная может быть передана, а может не быть. Как писать надежный код в такой ситуации?



> А как быть то? Передавать isMainRoute во всех контроллерах избыточно, а как-то определять, что "вид вызван из MainController" надо



Тут надо подумать логически. Вот у нас есть серединка страницы, которая разная и формируется контроллерам, а есть шапка/меню/подвал/сайдбар (лейуат), которые везде одинаковые. Но им тоже нужны данные. Надо искать варианты, например:

- сделать отдельный "контроллер" (или контроллеры) для сбора данных для лейаута. Или оформить их как "виджеты".
- добавить свои переменные в {{ app }}
- добавить глобальные переменные в твиг
- сделать, чтобы эти части вызывали какие-то функции или методы и получали нужные им данные
- внедриться в событие, которое срабатывает до запуска контроллера и куда-нибудь что-нибудь передает
- сделать наследование контроллера и формировать данные для шапки в базовом контроллере

То есть поискать варианты, лучшие практики.

Вот например:

- https://symfony.com/doc/current/templating/global_variables.html
- https://stackoverflow.com/questions/21094888/symfony2-how-to-retrieve-data-from-database-globally-in-every-page

> использовать синтаксис для переводимых строк? Это как?


Смотри например класс MessageFormatter в расширении Intl, смотри средства локализации в Симфони:

http://userguide.icu-project.org/formatparse/messages

>"{num_guests, plural, offset:1 "


> "=0 {{host} does not give a party.}"


> "=1 {{host} invites {guest} to her party.}"


> "=2 {{host} invites {guest} and one other person to her party.}"


> "other {{host} invites {guest} and # other people to her party.}}}"



>> Почему пагинатор передается в аргументы метода контроллера? Это такой DI?


> Как я понял, нужно в конструкторе его определять?


Не, наверно надо оставить DI. Тут нет проблемы, я ошибся.

>> А зачем else?


> При переходе на следующую страницу, условие $form->isSubmitted() уже не выполняется, поэтому я беру $searchString из get-параметра


Это какой-то косяк в твоем использовании формы. Если форма GET, то она дложна брать данные из GET.
832 1135047
>>22782

> Я тебя правильно понял? https://github.com/TheSidSpears/test_hub/commit/48de6c290d05ca63a48a5aa7bf8fbf67fb67fb5f


Да.

> В этом файле стандартные переменные APP_ENV и DATABASE_URL. Зачем их переименовывать и как их система прочтет? (в этом разобраться самому)


ну я предлагал добавить префиксы, чтобы было видно, от какого приложения эти переменные и чтобы они не конфликтоваи с другими. Может, и не стоит заморачиваться конечно.

> Нужно тестировать репозитории на копии основной БД? А как держать эту БД актуальной? Это ж нужно миграции и там и там проводить. Как-то не удобным это кажется



В идеале - тестовая БД, которая заполняется перед тестами. Миграции руками проводить не надо, надо все автоматизировать.

Да, это сложновато, ну а как без этого тестировать код, завязанный на БД? Не делать же полноценную эмуляцию всей SQL-базы данных. Ну и без этого тебе ведь руками все тестировать придется.

Это ты еще до браузерного тестирования и селениума не дошел, там еще сложнее.

> Нет, эти 2 ф-ии используются исключительно для заполнения Fixtures


Тогда ок.

> Я попытался разобраться https://drive.google.com/file/d/1Gvt38WwASpFcdFU3z9ZDuvrZ3pfaWbun/view?usp=sharing


> Видимо, не подойдёт


А ты попробуй код написать ;)

Например, $repo->findBy(['tag' => $tags]) или findByTag($tags) и посмогтреть что он найдет и какой SQL запрос сформирует.

> В нём определяется какой-то persister


Судя по названию, это объект для сохранения (persist) сущностей в БД.

> Видим, что класс зависит от `InheritanceType`. Названия классов намекают, будет ли проходить поиск по конкретной таблице или по объединенной (joined)


Да, это для разных вариантов наследования таблиц вроде http://design-pattern.ru/patterns/class-table-inheritance.html .

>> Вот это мне не нравится. У тебя переменная может быть передана, а может не быть. Как писать надежный код в такой ситуации?



> А как быть то? Передавать isMainRoute во всех контроллерах избыточно, а как-то определять, что "вид вызван из MainController" надо



Тут надо подумать логически. Вот у нас есть серединка страницы, которая разная и формируется контроллерам, а есть шапка/меню/подвал/сайдбар (лейуат), которые везде одинаковые. Но им тоже нужны данные. Надо искать варианты, например:

- сделать отдельный "контроллер" (или контроллеры) для сбора данных для лейаута. Или оформить их как "виджеты".
- добавить свои переменные в {{ app }}
- добавить глобальные переменные в твиг
- сделать, чтобы эти части вызывали какие-то функции или методы и получали нужные им данные
- внедриться в событие, которое срабатывает до запуска контроллера и куда-нибудь что-нибудь передает
- сделать наследование контроллера и формировать данные для шапки в базовом контроллере

То есть поискать варианты, лучшие практики.

Вот например:

- https://symfony.com/doc/current/templating/global_variables.html
- https://stackoverflow.com/questions/21094888/symfony2-how-to-retrieve-data-from-database-globally-in-every-page

> использовать синтаксис для переводимых строк? Это как?


Смотри например класс MessageFormatter в расширении Intl, смотри средства локализации в Симфони:

http://userguide.icu-project.org/formatparse/messages

>"{num_guests, plural, offset:1 "


> "=0 {{host} does not give a party.}"


> "=1 {{host} invites {guest} to her party.}"


> "=2 {{host} invites {guest} and one other person to her party.}"


> "other {{host} invites {guest} and # other people to her party.}}}"



>> Почему пагинатор передается в аргументы метода контроллера? Это такой DI?


> Как я понял, нужно в конструкторе его определять?


Не, наверно надо оставить DI. Тут нет проблемы, я ошибся.

>> А зачем else?


> При переходе на следующую страницу, условие $form->isSubmitted() уже не выполняется, поэтому я беру $searchString из get-параметра


Это какой-то косяк в твоем использовании формы. Если форма GET, то она дложна брать данные из GET.
833 1135048
>>23914

Смотри что есть тут https://developer.microsoft.com/en-us/microsoft-edge/tools/

Либо виртуалка с виндой (майкрософт дает лицензионные), либо сайты-скриншотеры.

>>23925

Можно просто циклом foreach пройти по массиву и по очереди каждый элемент поменять. Если не пытаться проверить все телефоны за 1 заход, то будет проще.

>>24213

Могу дать в помощью статью про ИЕ: https://github.com/codedokode/pasta/blob/master/html/markup-for-ie.md

>>24496

есть варианты

- inline-block
- float: left
- display: table-cell/table-row/table
- flexbox

>>24948

Про наследование написано немного тут

- http://design-pattern.ru/patterns/single-table-inheritance.html
- http://design-pattern.ru/patterns/class-table-inheritance.html
- http://design-pattern.ru/patterns/concrete-table-inheritance.html

>>Ключом в event_type наверно лучше сделать id. Он меньше места занимает.


> А если в таблице появится поле owner_user_id, то ключом можно сделать сочетание type и owner_user_id? Или id будет удобнее?


Можно использовать любой вариант.

> Если периодичность перенести в таблицу Events, то это поле будет или дублироваться или придется каждый раз указывать периодичность. Насколько приемлемо дублирование, нужно выбрать то, которое будет приоритетное?



Наверно, тогда лучше назвать поле в Event_type is_annual_by_default, и использовать его только для начального значения в галочке. Дублирования не будет.

>>34979

AWS недешевый. Подозреваю, что если и есть бесплатный тариф, он с какими-то подвохами. Не вариант завести виртуальную карточку от того же qiwi или яндекс-денег? Они правда могут ее не принять, DO например не принимает.

Для дешевых VPS есть poiskvps.ru, но там в основном сервисы с русскими или СНГ-шными корнями.

Также, открою секрет за 1 евро в мес. можно у арубы арендовать.
833 1135048
>>23914

Смотри что есть тут https://developer.microsoft.com/en-us/microsoft-edge/tools/

Либо виртуалка с виндой (майкрософт дает лицензионные), либо сайты-скриншотеры.

>>23925

Можно просто циклом foreach пройти по массиву и по очереди каждый элемент поменять. Если не пытаться проверить все телефоны за 1 заход, то будет проще.

>>24213

Могу дать в помощью статью про ИЕ: https://github.com/codedokode/pasta/blob/master/html/markup-for-ie.md

>>24496

есть варианты

- inline-block
- float: left
- display: table-cell/table-row/table
- flexbox

>>24948

Про наследование написано немного тут

- http://design-pattern.ru/patterns/single-table-inheritance.html
- http://design-pattern.ru/patterns/class-table-inheritance.html
- http://design-pattern.ru/patterns/concrete-table-inheritance.html

>>Ключом в event_type наверно лучше сделать id. Он меньше места занимает.


> А если в таблице появится поле owner_user_id, то ключом можно сделать сочетание type и owner_user_id? Или id будет удобнее?


Можно использовать любой вариант.

> Если периодичность перенести в таблицу Events, то это поле будет или дублироваться или придется каждый раз указывать периодичность. Насколько приемлемо дублирование, нужно выбрать то, которое будет приоритетное?



Наверно, тогда лучше назвать поле в Event_type is_annual_by_default, и использовать его только для начального значения в галочке. Дублирования не будет.

>>34979

AWS недешевый. Подозреваю, что если и есть бесплатный тариф, он с какими-то подвохами. Не вариант завести виртуальную карточку от того же qiwi или яндекс-денег? Они правда могут ее не принять, DO например не принимает.

Для дешевых VPS есть poiskvps.ru, но там в основном сервисы с русскими или СНГ-шными корнями.

Также, открою секрет за 1 евро в мес. можно у арубы арендовать.
Конец треда 834 1135058
Этот тред закрыт. Переходите в новый тред >>1135053 (OP)

Если я кому-то не ответил, напомните, пожалуйста, о себе в новом треде.
835 1135478
>>30599

> Ошибку выдает такую: String could not be parsed as XML. Как и что тогда передавать итератору?


Ты уверен, что ошибка на строке с итератором, а не на строке simplexml_load_file? Скорее всего там просто некорретный XML, можно проверить его валидатором XML, например, тут: https://www.xmlvalidation.com/ или в любом другом.

>>30614

Ок, спасибо за помощь.

>>30625

MVC - это архитектура, у меня есть про нее урок: https://github.com/codedokode/pasta/blob/master/arch/mvc.md

>>31257

У каждого треда можно определить время последнего поста в нем (lastBumpDate). Если отсортировать треды по убыванию этого времени, то получится как раз то, что нужно.

А дальше уже идут нюансы. Например, бамп лимит - если в треде более 500 постов, то при расчете lastBumpDate берется время 500-го поста, а не последнего. Закрепленные треды - идут всегда раньше, чем незакрепленные.

Ты знаком с SQL? Это там не так сложно сделать.

Архивирование делается примерно так: раз в час, минуту, сутки или как-то еще запускаем скрипт, который сортирует треды и находит те, что находятся ниже определенной позиции. Они архивируются. Это может быть как просто добавление пометки в таблицу, так и перемещение в отдельную таблицу (чтобы основная таблица оставалась маленькой и быстрее работала).

Вот еще, не знаю, поможет ли, урок про нормализацию БД: https://github.com/codedokode/pasta/blob/master/db/normalization.md

При проектировании лучше всего сначала спроектирвоать БД в нормализованном виде. Позже для оптимизации допустимо применить денормализацию, то есть дублирование данных.

> что значит поле bump


Где ты увидел это поле? В каком-то уроке или в каком-то движке?
835 1135478
>>30599

> Ошибку выдает такую: String could not be parsed as XML. Как и что тогда передавать итератору?


Ты уверен, что ошибка на строке с итератором, а не на строке simplexml_load_file? Скорее всего там просто некорретный XML, можно проверить его валидатором XML, например, тут: https://www.xmlvalidation.com/ или в любом другом.

>>30614

Ок, спасибо за помощь.

>>30625

MVC - это архитектура, у меня есть про нее урок: https://github.com/codedokode/pasta/blob/master/arch/mvc.md

>>31257

У каждого треда можно определить время последнего поста в нем (lastBumpDate). Если отсортировать треды по убыванию этого времени, то получится как раз то, что нужно.

А дальше уже идут нюансы. Например, бамп лимит - если в треде более 500 постов, то при расчете lastBumpDate берется время 500-го поста, а не последнего. Закрепленные треды - идут всегда раньше, чем незакрепленные.

Ты знаком с SQL? Это там не так сложно сделать.

Архивирование делается примерно так: раз в час, минуту, сутки или как-то еще запускаем скрипт, который сортирует треды и находит те, что находятся ниже определенной позиции. Они архивируются. Это может быть как просто добавление пометки в таблицу, так и перемещение в отдельную таблицу (чтобы основная таблица оставалась маленькой и быстрее работала).

Вот еще, не знаю, поможет ли, урок про нормализацию БД: https://github.com/codedokode/pasta/blob/master/db/normalization.md

При проектировании лучше всего сначала спроектирвоать БД в нормализованном виде. Позже для оптимизации допустимо применить денормализацию, то есть дублирование данных.

> что значит поле bump


Где ты увидел это поле? В каком-то уроке или в каком-то движке?
836 1148574
Реквестирую гайд по пхп для не новичка в программировании. Чтобы не поясняли 5 минут что такое переменная, а сразу к сути. Желательно видосик, хотя врядли такое существуют.
Тред утонул или удален.
Это копия, сохраненная 6 марта 2018 года.

Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее

Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
« /pr/В начало тредаВеб-версияНастройки
/a//b//mu//s//vg/Все доски