Это копия, сохраненная 14 февраля 2018 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
Похоже, это новогодний тред! С праздником, акеоме, котоёро, готовьтесь, что в начале января все будут отдыхать и замечаний по задачкам придется подождать.
Пожалуйста, пишите один большой пост вместо нескольких маленьких и не флудите не по теме.
Это тред для начинающих. Не написал за свою жизнь ни одной программы и имеешь тройку по математике? Ты наш человек.
Предыдущий тред был тут: >>1097438 (OP). Остальные треды есть в архиве: http://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? — Да, однозначно. Посмотри любую вакансию.
Если тебе лень выравнивать код руками, закачай его на 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
и вот я думаю как лучше это сделать. из кажущихся вменяемыми пока придумал только такой вариант (упрощенно): одна таблица custom_columns(id, user_id, type, title) и вторая соответственно custom_columns_values(id, column_id, value) и потом делать запрос типа
select * from custom_columns_values v inner join custom_columns c on v.column_id = c.id where c.user_id = :user что-то такое
есть еще какие-то варианты, как такое сделать?
Это чтобы придать тебе уверенности в себе перед задачами на ООП и про студентов, чтобы ты не сдался сразу, прочитав условия.
Как по мне - лютый говнокод. Есть же класс для паботы с ФС, зачем ты велосипед пишешь?! Тем более без try/catch.
Во-первых, нечитаемая колбаса. Ты строчки экономишь? Во-вторых, зачем ты переопределяешь DOCUMENT_ROOT? Это поле, которое заполняет интерпретатор PHP, а не ты.
добавлю к другим ответам, что есть правило "очевидное лучше неочевидного", оно в этих двух строках нарушается несколько раз.
Вообще, изящность решения обычно заключается в его архитектуре, комбинации различных практик, своевременно и правильно примененном паттерне и многом другом, но точно не в компактно написанном куске кода, который по сложности равен сложению двух чисел. Т.е. чтобы оценить изящность решения, это решение должно решать какую-то более-менее серьезную задачу. Считать задачу присвоения строки изящно решенной может только студент, который вчера дочитал книгу "Языкнейм за 21 день".
Но если тебя интересует безотносительно размера задачи, то я бы сказал так - существуй критерии изящности решения, то читабельность и наглядность были бы далеко не последними критериями.
вообще конструкция if-elseif редко подразумевает изящность. есть подозрение, что это троллинг, но в любом случае ознакомься вот с книгой по теме https://github.com/jupeter/clean-code-php
У нас появился https протокол https://phpclub.tech
Менять ссылку в шапке не обязательно, потому что http перенаправиться на https
Сап, анончики. Вопрос такой, есть те кто работал с Amiro.CMS?
> этот код в консоли выполняется, а там doc_root неопределён.
Логично, это ведь параметры, которые приходят от веб-сервера. Значит, не надо его использовать вообще тогда.
Блэт, аноны. Где я обсераюсь? Чому только с одним сравнивает?
http://archive-ipq-co.narod.ru/ у меня в последнем хроме в разрешении 1920 на 1080 не жмутся кнопки меню. уменьшаю размер окна до половины стола по ширине и все становится ок
Ну смотри.
$key = 1;
$str1 = 'Number: $key'; //на выходе ты получишь такую же строку, т.е. Number: $key
$str2 = "Number: $key"; //тут на выходе получишь Number: 1
блядь, хули вы отвечаете как кокетливые девки на вписке. алсо, "интерпретация"
>>10481
https://secure.php.net/manual/ru/language.types.string.php
>В отличие от синтаксиса двойных кавычек и heredoc, переменные и управляющие последовательности для специальных символов, заключенных в одинарные кавычки, не обрабатываются.
то есть echo "$bar"; выведет значение $bar, а echo '$bar'; выведет дословно название переменной со знаком доллара.
также про внутренности языка тут вот https://habrahabr.ru/company/mailru/blog/318008/ есть про двойные кавычки в php7, ищи по словам "encapsed-строки". если вкартце, в семерке двойные кавычки - уже не такая дорогая операция и можно переставать писать конструкции вида echo $foo . ' blah blah ' . $bar;
Да не за что, антош :3
И тебе спасибо!
Они были недорогой операцией и в PHP5, если только конечно основная суть твоей программы не в выводе миллионов строк текста.
В данном случае у нас сперва вычисляется первое выражение конструкцию if ($handle = fopen($source, 'w')), а потом $handle сравнивается с FALSE?
Тут ошибка в скобках. Должно быть
if (($handle = fopen(...) !== false)
А вообще, мне такое не нравится и лучше записать это в 2 строчки, вынеся присваивание из if.
И сам сделал ту же ошибку. Должно быть if (($handle = fopen(...)) !== false)
Вот видите, почему надо писать в 2 строчки.
Теперь понял, мерси за ответ.
Есть разные обфускаторы, но я бы не советовал их использовать. Потому что потом, если будет какая-то ошибка, то невозможно понять ее причину.
Если ты не доверяешь своим клиентам (почему?) то лучше всего делать не программу, а сервис, который хостится у тебя и который доступен через браузер. Ну или программу с API.
По запросу пользователя формировать несколько xlsx документов, иногда больше 50 за один раз. Потом архивировать и архив отдавать пользователю.
Всё это, безусловно, нужно делать в параллельных потоках иначе ждать можно очень долго.
Как это будете делать в php?
Версия php - 7.1, куда pthreads не завезён.
В Яндексе вроде раньше тоже так было, но потом у них что-то поменялось. Или, может проблема в недружелюбном https://github.com/robots.txt . Что же, жаль, что пользователи Яндекса не увидят эту статью.
Нужно выполнять некое действие при наведении на линк.
У меня получился вот такой говнокод, как его оптимизировать с использованием циклов или подобного? Линков будет много.
...
<section data-mouseover0> линк </section>
...
<section data-mouseover1> линк </section>
...
скрипты:
var object0 = document.querySelector("[data-mouseover0]");
object0.addEventListener("mouseover", mouseOver0);
var object1 = document.querySelector("[data-mouseover1]");
object1.addEventListener("mouseover", mouseOver1);
function mouseOver0()
{
object0.innerHTML="<h2>Событие mouseover0</h2>"
}
function mouseOver1()
{
object1.innerHTML="<h2>Событие mouseover1</h2>"
}
Спасибо.
а какие есть аналоги у Gearman? я смотрю, там документации нормальной нет, да и наверняка уже что-то новое появилось
Я считаю, что было бы очень удобно, если бы в репозитории pasta были хотя бы ссылки на гисты про тестхаб, автоматизированное тестирование, задачи на js. Навигация в gist.github.com очень неудобная + PR отправлять нельзя
Спасибо за помощь в обучение.
gist это вообще такое временное хранилище. Я их планировал переносить на гитхаб, но руки пока не дошли. Ну и их поисковой выдачи они тогда могут выпасть, увы.
.hidemenu
{
display:none;
margin-right:-1111px;
background-color: yellow;
Opacity: 1;
z-index 100;
}
>>10511
Я бы сделал так: список xlsx-файлов на генерацию храним у клиента в js. На каждый файл создаём ajax-запрос и отправляем серверу, сервер делает xlsx и где-то временно хранит, отвечает юзеру об успешной генерации. На js показываем юзеру прогрессбар, название текущего файла, процент выполнения, etc. Так мы и сервак не перегрузим, и пользователь будет знать, что происходит.
неактуально
Как эту задачу автор решил?
Анон, ты просто спаситель. Благодарю тебя. Я понимал, что foreach и if должны быть связаны, но не понимал, как.
сам решил наглым и лютобешенным копипастом с мануала по пхп, но перед этим усердно думал над решением
Вот так бывает ребятки. Кстати IQ по HTML у меня 120. Думаю изучив JS вместе с прилагательными он повысится до 300.
Алсо я тут колесил по всяким дизайнерским сайтам чтобы стырить у них сайт, одна большая компания, захожу в консоль и смотрю разметку, а там BEM, прикольно, не зря практикую. В остальных случаях все сайты попадались то без семантики, то без понятных имен, в общем ясно о чем говорит ОП, действительно самому противно на это смотреть.
Ладно я свалил верстать, удачного дня кто там проснется.
функция array_rand() возвращает ключ случайного элемента массива (или нескольких элементов, зависит от второго аргумента).
Соответственно, в переменную $random ОП заносит ключ случайного элемента, а в $answer надо засунуть значение этого элемента, например, так:
$answer=$answers[$random];
Ты в твоем варианте по сути сократил код, вынеся конструкцию $answers[$random] прямо в эхо
Что-то уже чёрт знает сколько пытаюсь всё куда-то вкатиться, но пока что безуспешно. Если подумать, возможно, проблема в отсутствии конкретных целей и задач. Но самая очевидная цель — походить по гвоноконторам и устроиться джуном — практически недостижима в мухосранских реалиях. А "планы" уровня "буду чего-то там писать-писать вилкой, выкладывать на гитхаб, а потом, может, какой заказ чудом где урву, и вот так и вкачусь потихоньку", — это, наверное, говно, а не планы...
В суши-шопе есть ассортимент из 10 роллов. Сколько всего можно сетов сосавить из этих ролов, что бы роллы в сете не повторялись? Если по 3 ролла в сете. Если по 4 ролла в сете.
sushi = lambda x : len(list(itertools.combinations(range(10), x)))
Если считать, что ролл ABC == ролл ACB == ролл CAB и т.д., то количество сетов= n!/(k!*(n-k)!), где n – ассортимент роллов, а k – количество роллов в сете.
Таким образом, из 10 роллов можно составить 120 трехролльных сетов или 210 четырёхролльных
Нахуй ты сюда приперся, выблядок? Нахуй нам твое нытье? Чего ты хочешь? Сьеби пожалуйста и не надоедай своими биопроблемами, вон в б дохуя места, иди туда поной.
за 16к норм план обучения или такие знания можно самому за 2 месяца подтянуть на хорошем уровне?
Сам я учу js и перспектива за полтора месяца получить базу по php+sql меня радует.
Клиентам не доверяю потому что для них будет дешевле нанять студента если потребуется какой-нибудь допил, чем обратиться к разработчику за дополнительную плату. К тому же софт уникальный и шанс прибрать его к рукам и сделать на его основе свой - очень велик. В данный момент одна компания пользуется им в качестве сервиса (сервер располагается у нас), но это только в качестве обкатки. Дальнейшее распространение предполагается в качестве готового продукта в виде собранного устройства с софтом.
дерево:
autoload.php
--Namespace
----Class.php
----ClassTwo.php
-Class.php:
Namespace Namespace;
class Class
{
public function __construct()
{
new ClassTwo;
}
}
-ClassTwo.php:
Namespace Namespace;
class ClassTwo {}
-autoload.php:
spl_autoload_extensions('.php');
spl_autoload_register();
$Class = new Namespace\Class;
>Fatal error: spl_autoload(): Class Namespace\ClassTwo could not be loaded in C:\Apache24\htdocs\Programm\Namespace\Class.php on line 7
Если убрать из конструктора создание второго класса, ошибки нет.
дерево:
autoload.php
--Namespace
----Class.php
----ClassTwo.php
-Class.php:
Namespace Namespace;
class Class
{
public function __construct()
{
new ClassTwo;
}
}
-ClassTwo.php:
Namespace Namespace;
class ClassTwo {}
-autoload.php:
spl_autoload_extensions('.php');
spl_autoload_register();
$Class = new Namespace\Class;
>Fatal error: spl_autoload(): Class Namespace\ClassTwo could not be loaded in C:\Apache24\htdocs\Programm\Namespace\Class.php on line 7
Если убрать из конструктора создание второго класса, ошибки нет.
Ой всё я довен. Все работает, я просто делал как тут рекомендуют и забыл про то что нахожусь в другой папке из которой инклюдю это всё. (http://php.net/manual/ru/function.include.php#116522)
У меня было:
>require_once . '../autoload.php';
а должно быть
>require_once __DIR__ . '../autoload.php';
Не думал что это так важно.
Это что-то из этого раздела https://ru.wikipedia.org/wiki/Комбинаторика , лень искать что именно.
Анон, мне кажется, или я написал калькулятор лучше и проще, чем в учебнике? Сюда можно в теории любые действия вообще добавить, включая степени и синусы-косинусы, надо только регэксп править.
И да, я не юзаю for each, меня в ВУЗе джва года Дельфи и Матлабу учили, привык каждый раз длину массива определять.
>Gearman
Под винду какой-то пердолинг страшный и не факт, что заработает с окружением данного мне сервера.
Есть ли аналоги под винду и версию пхп 7.1?
> в $answer надо засунуть значение этого элемента
> $answers[$random];
Спасибо, что пояснил за это.
Ну, неплохой вариант вроде бы. У меня с клиента отправляется только один запрос с id - по этому id из базы уже выбираются id зависимых сущностей (те самые 50) и к базе уже идут запросы на выборку данных по этим id и после уже формируются файлы.
Получается мне нужно вернуть на клиент эти 50 id. Не очень красиво, конечно.
>о продукта в виде собранного устройства с софтом.
вообще странно, что вы сначала разработали продукт, а потом задумались о его защите.
так-то в твоем случае нормальный вариант один - saas. тем более ты говоришь, что этот вариант у вас уже работоспособен
рассказывать, что ты там козырный тип в вузе лучше после того, как ты решил задачу правильно, а велосипедно-костыльными методами в стиле php4. твое отличие от "обычного" решения в том, что ты применил регулярки и зачем-то сам считаешь индексы у массивов. оба решения неудачные, т.к. повышают вероятность ошибок при усложнении программы.
если ты такой крутой образованный программист, тебе по идее должно быть легче освоить новый язык и писать на нем в соответствии с его современными практиками, а не "как на дельфи научили".
for ($i = 0; $i < count($znaki); $i++) объясни, в чем плюс такого подхода перед foreach? попробуй по приколу написать тесты или замерить скорость выполнения в цикле из 1000 запросов для такого решения и нормального foreach
>повышают вероятность ошибок при усложнении программы.
Так вообще про любой код сказать можно. Не понимат как программировать калькулятор так чтобы потом из него СУБД для заказчика сделать.
мимокрокодил.
не нужно делать СУБД, просто допустим добавить еще 4 действия, которые являются более сложными, чем арифметические (которые не выполнить внутренними функциями языка).
есть такой принцип https://en.wikipedia.org/wiki/Open/closed_principle говорящий о том, что для добавления нового функционала в хорошо спроектированном приложении нужно будет дописывать новые методы и классы, а не менять (или по минимуму менять) существующие. понятно, что калькулятор - это не "приложение", а просто задачка на основы языка, но нужно хотя бы следовать принципу наименьшего удивления и стремиться к читаемости кода, а вынос логики программы в регулярку не добавляет читаемости (пример как повысить читаемость регулярки, кстати: https://github.com/jupeter/clean-code-php#use-searchable-names-part-2)
Да сначала вообще не предполагалось так все развивать. Просто выполнили один заказ. С энтузиазмом. Настолько с энтузиазмом что решили в свободное время этот проект развивать, и в конечном итоге получился довольно универсальный продукт, у которого нет аналогов. Ну и было решено его продавать так или вместе с монтажом под ключ.
Есть картинки разного размера, запханные в таблицу из 1 ячейки со стилем, почему они меняют размер?
td
{
height: 300px;
width: 400px;
text-align:center;
}
<table>
<tr>
<td><img class="img-responsive" src="upload/img_<?php echo $row['id_model'];?>.jpg"></td>
</tr>
</table>
Не, под линухи нормально всё. На гитхабе репозиторий активный.
Потому что в таблицах по умолчанию height/width задают минимальный, а не точный размер (в спеке это называют preferred width). Меняется каким-то свойством, отключающим подстройку размера.
Где-то тут описано https://www.w3.org/TR/css-tables-3/#width-distribution-algorithm
Нет. col просто задает preferred width, но не окончательное значение. Отключить подстройку размера можно по моему через table-layout: fixed
autoload.php
--Namespace
----Class.php
----ClassTwo.php
--public
----index.php
index.php:
require_once __DIR__ . '/../autoload.php';
Та же ошибка
>Fatal error: spl_autoload(): Class Namespace\ClassTwo could not be loaded in C:\Apache24\htdocs\Programm\Namespace\Class.php on line 7
вопрос открыт, не могу разобраться с этими реквайрами.
Угу, спасибо. Там height: auto; стоял, а я чекнуть дефолтный бустраповский даже не подумал.
Спать пора :-(
>козырный тип
Лол, ни разу, просто мне это кажется проще, чем решение в учебнике. А осваивать и правда легче, я прошёл учебник за две недели, занимаясь на работе в свободное время. Но дальше там ООП, у меня всего несколько семинаров по нему было всего. В моём ВУЗе упор был на вычисление интегралов, численные методу и подобную шнягу, ибо я у мамы инженер потому и решил вкатиться в ит, зарплаты инженеров не радуют, а за бугор перекатываться сложно
>for ($i = 0; $i < count($znaki); $i++) объясни, в чем плюс такого подхода перед foreach
Лично мне это кажется универсальнее, чем for each. Идти по массиву простым циклом - в этом есть унификация некоторая.
>применил регулярки
Это разве плохо? Очень мощный метод работы с текстовыми данными, мне понравился в Дельфи такого не было, например
Че ты несешь блять.
>Всмысле там
Я же писал - дефолтный бустраповский.
>у тебя не должно быть повторяющихся параметров
Не понял? Что мне мешает переписать в последнем подключенном файле стилей параметры предыдущего?
Тебе - не нужно, мне - нужно.
Расскажи, как ты не переписывая стили скроешь инпуты на нужной странице?
Будешь весь файл стилей копировать, менять 1 строчку и подключать?
если вкатываешься в айти, то тут есть определенные промышленные стандарты, грубо говоря с таким кодом ты бы не прошел аудит (или не получил бы хорошую оценку от препода).
использовать for вместо foreach для массивов тебе никто бы не дал из-за того, что foreach сто раз оптимизирован для работы с массивами и жрет для одинаковых операций намного меньше ресурсов. также, массивы в php - это одна из самых его привлекательных составляющих из-за ассоциативных индексов и огромного количества функций и конструкций для них. почему бы их не использовать?
также ты искусственно привязываешь цикл for к конкретному массиву манипуляциями с индексами и высчитывая количество элементов для него. foreach делает все за тебя.
вызывать каждый раз count($znaki) невыгодно с т.з. опять же скорости, такие вещи надо сохранять в переменную.
понятно, тут можно сказать "ну это калькулятор, там не будет миллион элементов в массиве", но также как ты в вузе решаешь задачки, их нужно делать правильно, то есть по существующим bp. foreach для массивов - bp наверное с момента создания языка.
регулярки - это хороший инструмент валидации, если его использовать правильно. в твоем случае правильным было бы написать валидатор, при котором проходят только те знаки, которые реально работают как знаки в
коде. что будет, если кто-то захочет возвести число в степень, а у тебя нет такого действия?
лучше разделить обработку инпута на собственно валидатор и парсер, чтобы это были раздельные действия.
также лучше заменить if elseif на switch case. вместо == НАДО использовать ===. не мешать английские слова с русскими. ну еще [] и форматирования по psr, но это мелочи.
не путать что за массив как называется. почему в znaki[1] лежат цифры и ты им присваиваешь $znaki = $znaki[1] ?
в целом я бы при решении задачи сконцентрировался на читаемости кода. также очень рекомендую книгу https://github.com/jupeter/clean-code-php
Как скажешь.
Ты лучше расскажи, отчего у меня лишний перенос строки образовался на другой странице?
Стили и код подключаются идентично.
это вопрос из серии "зачем ноты учить, музыка же из души должна идти!1". немного непрогрессивный, так скажем, подход. смысл книжки в том, в чем и смысл всех других книжек - учиться и развиваться.
а смысл чистого кода в том, что ты придешь на собеседование в хорошую контору, а тебе скажут "покажите ваш код". и ты откроешь код, где написано $numberKolonki или что-то подобное, а тебе скажут "спасибо, до свидания". а если пишешь какие-то опенсорс библиотеки с таким вот кодом и вложенными циклами, другие разработчики не будут их дописывать. а следование и понимание bp позволяет работодателю понять, что ты стремишься развиваться, даже если пока ничего серьезного не умеешь.
>>10994
У тебя задан стиль для всех td элементов, это изначально плохая практика, лучше создавать стили для дефолт-HTML элементов если ты хочешь создать свой дефолт стиль для страницы, и не тот что с крутыми свистульками, а тот, что отобразится даже на Нетскейпе.
Сами создатели семантики HTML говорят, что родитель должен определять контент потомка и не выползать за рамки своего родителя и так до дедушки.
Такими соображениями руководствуются не просто так, дабы не засрать посыл кода для другого разработчика. Создатели семантики говорят, что нужно для каждого элемента задавать внутренний контекст, его предназначение. Сделать это можно путем добавочного аттрибута который называют классом, он задает свою семантику и сохраняет стиль дабы его можно было пихать куда нибудь еще и таким образом ты создаешь двойной смысл для элемента, например td это ячейка для инфы, а если дать ему класс td__picture-container то любому будет понятно, что это ячейка контейнер для картинки. Клево да? Приходим сюда: http://bem.ru
То есть создаешь элементы со смыслом, и потом к любому HTML элементу просто добавляешь готовый класс, который можешь использовать когда захочешь и проблем с изменением значения каждый раз элементу не возникнет. А бутстрап содержит уже готовые элементы.
>>11013
Мне бы код. Я не знаю какое говно толкает бутстрап, но мне кажется это из-за кнопки, с этими кликопарашами проблемы даже без фрейма. Скинь гит, посмотрю.
>>11016
Да не я не говорил такого, я спросил про то что зачем читать книжки, когда сами мануалы и книжки орут о том, что нужно соблюдать чистописание, а вам книжки какие то для этого нужны. Говнокодит как правило тот, кто забивает хуй, потому что правильно кодить не получается или опыта не хватает.
>Да не я не говорил такого, я спросил про то что зачем читать книжки
а. ну именование переменных не транслитом - это простой пример, понятно для этого не надо книгу читать (хотя в целом по именованию тоже много нюансов и умные люди пишут статьи типа http://www.yegor256.com/2015/09/01/redundant-variables-are-evil.html и http://www.yegor256.com/2015/03/09/objects-end-with-er.html).
просто в этой книге описано много хороших кейсов, которые редко очевидны новичкам (и не только новичкам).
Кратко говоря, там почти пересказывают то, что написано на WhatWG, только предлагают удобный способ наименовании дабы код не повторялся и как мне показалось повышает производительность.
Правда на самом WG все расписывают даже для слепых, мол, Всегда юзайте alt! Слепые тоже серфят!
>>11025
А понял, передается ценный опыт, полезно тогда.
Есть три строки: id, name, alias.
Где ошибка в запросе?
>У тебя задан стиль для всех td элементов, это изначально плохая практика
Это для конкретной страницы, на которой таблиц скорей всего больше не будет. А если будет - то разделю на классы.
>лучше создавать стили для дефолт-HTML элементов если ты хочешь создать свой дефолт стиль для страницы, и не тот что с крутыми свистульками, а тот, что отобразится даже на Нетскейпе.
Очень много времени занимает верстка.
Я дольше сижу и красоту навожу, чем продумываю и пишу реализацию. А если с нуля делать, так вообще зашиться можно.
>>11021
>Скинь гит, посмотрю.
Нету гита.
Могу так кинуть, только тут смотреть ну очень неудобно по причине не работающего php.
http://plnkr.co/edit/skqNk6nRalrK5YjxEjbt?p=preview
Скрины выше были сделаны с индекса и продукта, подключаются к ним стили (виднов отвечает за окно логина) и хидер + райт сайд (сам код окна)
То, что в учебнике - не обязательно идеальное решение. Конечно, можно написать лучше (но это не точно, так как ОП очень уверен в своих способностях).
> for ($i = 0; $i < count($znaki); $i++){
Тут надо использовать foreach так как твой код тяжелее воспринимать и он многословнее.
> $znaki = $znaki[1];
Ты тут используешь одну переменную для разных типов массивов и это сбивает с толку и может быть причиной ошибки. Условно говоря. я вижу там preg_match_all($separ, $calc, $znaki); и думаю, что в $znaki всегда будет результат preg_match_all, а он позже перезаписывается.
Не надо использовать одну переменную для разных типов данных.
Желательно не называть переменные транслитом. Не znaki, а tokens или parts.
> if ($actions[$i] == "+"){
> } elseif ($actions[$i] == "-"){
> } elseif ($actions[$i] == "*"){
Не надо копипастить выражение несколько раз, надо завести новую переменную.
И наконец, что, если в выражении есть ошибка? Ну например,
12+z+2=
хорошо бы это обнаруживать.
В использовании preg_match_all, конечно, нет ничего плохого. Еще есть вариант делать preg_split по знакам с флагом PREG_SPLIT_DELIM_CAPTURE и получим последовательность токенов (цифр и знаков).
То, что в учебнике - не обязательно идеальное решение. Конечно, можно написать лучше (но это не точно, так как ОП очень уверен в своих способностях).
> for ($i = 0; $i < count($znaki); $i++){
Тут надо использовать foreach так как твой код тяжелее воспринимать и он многословнее.
> $znaki = $znaki[1];
Ты тут используешь одну переменную для разных типов массивов и это сбивает с толку и может быть причиной ошибки. Условно говоря. я вижу там preg_match_all($separ, $calc, $znaki); и думаю, что в $znaki всегда будет результат preg_match_all, а он позже перезаписывается.
Не надо использовать одну переменную для разных типов данных.
Желательно не называть переменные транслитом. Не znaki, а tokens или parts.
> if ($actions[$i] == "+"){
> } elseif ($actions[$i] == "-"){
> } elseif ($actions[$i] == "*"){
Не надо копипастить выражение несколько раз, надо завести новую переменную.
И наконец, что, если в выражении есть ошибка? Ну например,
12+z+2=
хорошо бы это обнаруживать.
В использовании preg_match_all, конечно, нет ничего плохого. Еще есть вариант делать preg_split по знакам с флагом PREG_SPLIT_DELIM_CAPTURE и получим последовательность токенов (цифр и знаков).
Ты уверен, что там надо кавычки? Я не знаток msqli, но php.net говорит, что надо делать так
/ Select запросы возвращают результирующий набор /
if ($result = $mysqli->query("SELECT Name FROM City LIMIT 10")) {
printf("Select вернул %d строк.\n", $result->num_rows);
Отвыкай.
>>10846
А сделал бы фоновую задачу на gearman или аналогичной библиотеке - было бы красиво. И не ломалось бы при пропадании связи браузера с сервером например.
>>10875
Из PHP программы? Надо использовать библилотеку-HTTP клиент вроде Guzzle.
Алсо надо ознакомиться с теорией по HTTP https://github.com/codedokode/pasta/blob/master/network/http.md
>>10914
Вероятность ошибок во многом зависит от понятности кода. Если ты с первого взгляда видишь логику выполнения кода, или например что делается с переменной, то это хорошо. Если нет, то можно сделать ошибку.
То есть при написании кода можно закладывть мины замедленного действия, на которые потом кто-то наступит. Ну например, побочные эффекты: функция назвыается getProductCount, но параллельно она обновляет процент скидки у некоторых товаров.
Есть такое понятие, как "defensive programming", книга "совершенный код" если тебе хочется разобраться дальше. Есть небольшой сборник советов https://github.com/codedokode/pasta/blob/master/good-code.md
foreach читабельнее, так как содержит меньше знаков. Когда я вижу foreach, я понимаю с 1 взгляда на это слово, что у нас перебор массива. В случае с for, надо распарсить глазами все эти точки с запятой, посмотреть как дальше используется переменная - времени нужно больше (согласен?)
foreach короче.
Ты пишешь, что тебе понятнее for, но может ли быть, что ты просто к нему привык, а к foreach пока нет?
Регулярки это мощный инструмент, спора нет.
Используя чужой опыт, можно развиваться быстрее. Или ты предлагаешь все с нуля переизобретать?
>>11047
HTML/CSS это такой же код и нужно его организовывать, чтобы не запутаться потом. В том числе вводить какие-то правила, а не писать кто как хочет.
> Это для конкретной страницы, на которой таблиц скорей всего больше не будет.
Выглядит как оправдание нежеланию разбираться в БЭМ.
> Очень много времени занимает верстка.
А ты ее хорошо знаешь? То есть можешь написать CSS, не тестируя в браузере, потом открыть, исправить пару мелких косяков и готово? Если постоянно перепроверять код в браузере, то много времени будет уходить. Нужно уметь "рендерить" страницу в уме.
Это хорошо, когда есть свободное время для этого.
А не тогда, когда панически гуглишь, как же реализовать нужное действие.
Все таки мне кажется новичкам в этом деле трудновато рендерить в голове. Ты можешь иметь представление о том что будет, но уже машинальное представление придет с опытом как мне кажется.
мимокрок
--
Учите консоль сука, чем раньше тем лучше, благо я вовремя это понял и то случайно
autoload.php
--Namespace
----Class.php
----ClassTwo.php
-Class.php:
Namespace Namespace;
class Class
{
public function __construct()
{
new ClassTwo;
}
}
-ClassTwo.php:
Namespace Namespace;
class ClassTwo {}
-autoload.php:
//spl_autoload_extensions('.php');
//spl_autoload_register();
require_once __DIR__ . '/Namespace/Class.php';
require_once __DIR__ . '/Namespace/ClassTwo.php';
$Class = new Namespace\Class;
autoload.php
--Namespace
----Class.php
----ClassTwo.php
-Class.php:
Namespace Namespace;
class Class
{
public function __construct()
{
new ClassTwo;
}
}
-ClassTwo.php:
Namespace Namespace;
class ClassTwo {}
-autoload.php:
//spl_autoload_extensions('.php');
//spl_autoload_register();
require_once __DIR__ . '/Namespace/Class.php';
require_once __DIR__ . '/Namespace/ClassTwo.php';
$Class = new Namespace\Class;
Брейки поубирай.
><span id="_close" onclick="openbox('windowLogin')">Закрыть</span>
<br>
<br>
<br>
линк на восстановление пароля
<br>
линк на регистрацию
Нельзя. Это ненормально, что переменная может передаваться, а может не передаваться. Как в таких условиях писать корректно работающий код?
> может передаться переменная со значением null
Ты ничего не путаешь? Переменная со значением null нотиса не вызывает, ошибка именно при обращении к несуществующей переменной.
> When a security configuration does not behave as expected, enable logging (with the Monolog extension for instance) as the Security Component logs a lot of interesting information about what it does and why.
Я правильно понял, что волшебной настройки "enable logging" для Security component не существует, и нужно ручками прописывать $logger->info('...') внутри методов внутри классов внутри интересующих компонентов? Или сделать свой EventListner и подписать его на все события security component, который будет писать их в лог?
Нет, думаю, что надо просто подключить логгирование стандартным способом и Security начнет в него писать.
Настоящие профессионалы смогут. Код слишко интепрайзный чтобы его светить.
Спасибо, действительно, пишет само.
я ни разу не видел и не слышал, чтобы такое было в реальности. и из моих знакомых никто не видел и не слышал.
в теории может быть, просто это как купить мотоцикл и использовать его в бизнесе для перевозок цемента. где-то может такое и есть, но думаю не от хорошей жизни, а из-за каких-то исторических факторов.
Ну хз. У нас превалируют спермо сервера на работе и я не чураюсь юзать иис в связке с эрэнэр через фастсиджиай. Ничего зазорного в этом не вижу. Работает как надо.
ты в этом вопросе (вопросе винды на проде) явно опытнее, так что поинтересуюсь:
1. что делать, если понадобится сервер очередей? герман или rabbitmq встанут?
2. нет проблем с установкой расширений для php?
3. сфинкс и elasticsearch работают под винду?
4. скрипты по крону запускаете?
5. какая бд?
Ответы на все свои вопросы ты найдешь в гугле. Ибо я не занимался такими вещами какие тебе интересны. Связка эрэнэр и sqlite/mysql работает спокойно, с либами для эрэнэра проблем не было, они все идут скомпилированные. В конфиг пыха просто добавляешь их имя и кладешь либу в стандартную папку. Есть небольшой гемор при работе с иис с чпу т.к. надо ставить доп модуль url rewrite. А при работе под спермой с апачем/энджинкслм таких проблем не встречал. Короче, я думаю гемора не возникнет.
Если уж всякие связки iis+php+mysql позволяют под спермой wordpress/joomla запускать...
Проблемы будут, так как многие расширения, библиотеки никто не тестирует и не разрабатывает под винду.
я примерно представляю ответы на эти вопросы, но хотел поинтересоваться у человека, знакомого со стеком.
вообще ты, судя по ответу, и подтверждаешь мою теорию о том, что php на винде бывает только из-за того, что так исторически сложилось в конкретном случае (уже стояли сервера и никто не заморочился, либо запускали проект по приколу, а он выстрелил и переносить уже накладно и т.д.).
если я не прав, можешь привести плюсы такого стека перед линуксом, будет интересно.
>>11497
для хайлоада. это и был вопрос про мимо или не мимо, т.к. в теории любое публичное приложение может стать хайлоадом однажды.
Не, я пых сам разворачивал, нам под внутренние цели более чем. Тебе скорее всего лучше под линупсом все делать. Я далек от мира погроммирования (сис одмин я).
Хуясе
<input span id="_enter" ... ></span>
интепрайз, ага.
position: absolute;
Зачем? У тебя стандартнейшие элементы, почему ты не даешь им просто идти друг за дружкой?
position absolute тут плохо годится, он обычно используется для закрепления одного блока относительно другого. Элементы с PA не влияют на раскладку соседних блоков, и потому они плохо подходят для твоей ситуации.
если у нас в таблице всего два столбца, например order_id и item_id, сочетание которых будет уникально, нужно ли добавлять еще столбец id и делать его первичным ключом или можно в кач-ве первичного ключа задать комбинацию этих двух столбцов?
есть таблица с товарами, там их айдишки и названия.
планирую добавть таблицу зaказов, где будет айди зaказа и в каждом зaказе должно быть несколько товаров. соответственно для того чтобы соблюсти правила первой нормальной формы, я не могу захуярить несколько айдишек через запятую для одного заказа.
я делаю еще одну таблицу типа ordered_items, где будут поля order_id и item_id. и для одного order_id может быть хоть миллион item_id. а если мне нужно будет запросить данные по зaказу, буду писать запрос типа https://ideone.com/AVv3Y8 (бд - постгрес)
это корректный подход? есть еще какие-то общепринятые варианты?
Какое изменение окна? Я сделал у меня все ровно. Поставь фиксированную ширину и все.
https://greghove.github.io/Test/login.html
Ток держи в секрете. Нам тут вытекших не надо.
Мне удалось успешно написать правило, которое выделяет посты со ссылками
2ch.hk##:xpath(//div[@class='post-wrapper' and descendant::a[contains(text(), 'http')]])
теперь я пытаюсь написать правило для выделения постов без ссылок. Перепробовал уже около 5 вариантов, не заработал ни один.
Буду благодарен помощи.
А если у него пара методов с бд тоже вшивать?
А если у него очень много методов с бд тоже не вшивать?
Таблица (id|user_id|main_user_id)
дублирование - это плохо, можно убрать его:
for($i = 1; $i <= 6; $i++) {
$name = 'word' . $i;
echo array_rand($$name);
if (0 === $i % 3) {
echo "/n";
}
};
можно еще решить с помощью функций или ООП, но ты их скорее всего еще не проходил, так что это потом
если у тебя в контексте вызова объекта всегда одна БД и одни параметры подклюдчения, то передавай в конструктор.
Спасибо.
Однако после
"echo array_rand($$name);"
он выписывал лишь значения ключа, а не слова, дописал:
$result = array_rand($$name);
echo $$name[$result];
и заработало как нужно.
это я специально ошибся, чтобы проверить твои способности, лол
если хочешь побыстрее найти работу, yii2. если хочешь серьезных проектов и готов больше заебываться, симфони. ларавел хуй знает в каком случае гыгы
> хочешь серьезных проектов
> симфони
Это только симфонисты думают что у них проекты серьёзные. На самом деле любой проект симфони можно переписать на любом другом фрэймворке и получится раза в 2 быстрее и производительнее. Вообще не понимаю откуда этот фап на симфони пошёл.
Я не профи, но знаний на уровне джуна имею, и программирую периодически на PHP уже года 2 как, всё по стандартам из шапки. Думал про себя что довольно хорошо пишу, и даже код написанный год назад могу прочитать и разобраться в нём за 10-15 секунд. Но на днях показал код синьору с опытом овер 9000 лет, и он обоссал код со всех сторон, за кавычки, за переносы строк, даже добавил за обработку событие которое может случиться при ошибке, мол лишний код написал же. И как-то меня это даже демотивировало сильно код писать и вообще как-то двигаться дальше.
>И как-то меня это даже демотивировало сильно код писать и вообще как-то двигаться дальше.
Думаю он добился чего хотел. Тупо самоутвердился за счет новичка, который подвержен влиянию "авторитетов". То что кто-то пишет на пхп 9000 лет не значит что он делает это хорошо, он может быть тем еще говнописцем со времен пхп 4, и всё что написано не так как ему привычно стало быть == говнокод. Хуй забей и не показывай больше ничего ему. Лучше сюда приноси. А вообще если тебя волнуют кавычки и отступы, то изучи стандарты psr или прочее.
Спасибо анон. Не так грустно теперь.
Читай больше хорошего кода и подражай.
Критика синьоров - это нормально. Вполне вероятно, что твой код кошмарен, но ты по неопытности этого не понимаешь. Продолжай работать, копи опыт, сам станешь синьором.
сенкс
>>12047
https://github.com/jupeter/clean-code-php
покажи конкретно код и его замечания, мы тоже посмотрим и обоссым этого синьора если что
Я нахуй шлю любого долбоеба который меня пытается как то критиковать, а не помогать исправить.
Чувак представь что ты маленькая анимешная девочка и тебя обидели мимокрокодилы-долбоебы харчком по твоему песочному замку и сказали мол, это говно, это гавно. А другие типа ОПа сказали тебе, почему это говно, только не харкали.
Так это, посоны, с помощью каких инструментов вы бы решали задачи где требуется распараллеливание процессов ВНЕЗАПНО под виндой?
Под линух есть Gearman. Или может тупо в питон передавать эту задачу? Там вообще никакой ебли с параллельными процессами нет. Эх…
Привет, Опи чан. Хотелось бы спросить, что из себя представляет программист PHP или как ВАС называть. ВЫ дизайнеры? Есть карьерный рост?
тут недавно обсуждали php на винде, постов 10 назад, только один анон признался, что у него пхп под виндой.
ну насколько я знаю, герман не совсем распараллелирвает процессы, он грубо говоря запускает демоны, которые ждут задачи и выполняют их не скопом, а оптимизируя нагрузку. во всяком случае, таков был мой опыт
https://secure.php.net/manual/en/intro.pthreads.php там перекомпилировать правда надо
>>12347
толсто
>тут недавно обсуждали php на винде, постов 10 назад, только один анон признался, что у него пхп под виндой.
Так я и есть тот анон, лол. Pthreads не подойдут из-за проблем с пхп версии 7.1
Без сажи, конечно же
if (foo) return bar;
1) Допустимо.
2) Возврат из оператора условия внутри функции может быть запрещён в некоторых языках (но не в похапэ).
>Так я и есть тот анон, лол. Pthreads не подойдут из-за проблем с пхп версии 7.1
а в чем проблема обновить?
если серьезнее, то пхп программист это либо тоже самое, что любой другой программист для высокоуровневых языков (ооп, куча технологий, много абстракций), либо веб-макака, которая подверстывает и прикручивает шаблоны к вордпрессу или пилит виджеты для битрикса. к сожалению, исторически так сложилось, что язык очень лоялен к говнокоду. но в то же время современный пхп достаточно пиздат для больших приложений и прост для изучения. а еще он очень быстро развивается (развиваться в контексте пхп - это пиздить удачные вещи из других языков)
Анон, есть обычный хостинг не выделенный сервер, composera там нет, есть FTP, MySQL и PHP 5.4. Какие фреймворки можно использовать в этом случаешь? Как их ставить, если нет composera?
Сказал бы проще, что так же как и везде есть ленивые хуесосыТипа тебя рождающие стереотипы об хорошем языке, которым все пользуются и не пиздят.
Сап. Придумываю механизм сессий.
1. время жизни сессии: 1 час
2.время жизни куки: 1 час
3. привязка сессии к юзер-агенту и ип ххх.ххх.?.?
4. в сессии хранится пароль (не мд5) чтоб когда юзер сменит пароль старая сессия не работала
5. при авторизации генерация нового ид сессии и при смене пароля (без удаления старой)
6. если без авторизации серфишь сессия не запускается
7. если чел вышел или неправильно ввел пароль удаляю ему куки чтоб не грузил мне серв
8. каждые 20 минут генерация нового ид сессии (без удаления старой сессии для предотвращения потери сессии при большом кол-ве запросов)
время выставил для примера. по итогу сессию хуй спиздишь + сервак не засирается файлами сессий.
какие подводные?
>Какие фреймворки можно использовать в этом случаешь?
Те которые поддерживают версию PHP <= 5.4
>Как их ставить, если нет composera?
Перекинуть папку vendor через FTP
Чот стереотип на стереотипе и стереотипом погоняет. Виджеты для битрикса, шаблоны для вордпресс (где там PHP то?).
> пиздить удачные вещи из других языков
Пиздят в основном потому-что всякие нытики заваливают форумы своим нытьём. Потом выясняется что новые функции нужны в 0.00000000001% случаев в 1 проекте, но это можно было сделать и по другому. Просто нытик привык что в жабе так.
Вон, возьми анонимные функции которые в 7.1 добавили. И посмотри где на практике их стали использовать? Да нигде. Только спустя год начали хоть как-то что то делать на них. Но при этом впринципе все кто писал про PHP у себя в блогах упоминали что это ооочень большой недостаток.
p.s. и потери сессии нет. идеально же блять
>3. привязка сессии к юзер-агенту и ип ххх.ххх.?.?
Зачем?
>4. в сессии хранится пароль (не мд5) чтоб когда юзер сменит пароль старая сессия не работала
Лучше уничтожить и хранить все таки мд5
https://secure.php.net/manual/ru/function.session-destroy.php
>5. при авторизации генерация нового ид сессии и при смене пароля (без удаления старой)
Зачем?
>если чел вышел или неправильно ввел пароль удаляю ему куки чтоб не грузил мне серв
Куки хранятся у пользователя
А сессия - не уверен что она способна нагружать сервер
>8. каждые 20 минут генерация нового ид сессии (без удаления старой сессии для предотвращения потери сессии при большом кол-ве запросов)
Не уверен что сессия может просто взять и потеряться
При этом с С++ также. Возьми 2011 год, когда все ныли про утечки памяти, про небезопысность, про это вот всё. Вышел новый стандарт и... Хоть кто-нибудь использует новые наработки? Нееееет. Давайте будем ковырять говно мамонта.
привязка по айпи не обязательно. люди с мобилок сидят с разных инетов айпи разные. а юзер агент обязательно, чтоб снизить вероятность кражи сессии (сам пиздил уязвимостями, знаю).
сессион дестрой сволочь удаляет сессию настолько что она потом после запуска в заголовках новые куки не шлет
генерация нового ид чтоб старый если был украден (даже без авторизации сессия) не мог быть заюзан.
куки пользователь шлет мне в заголовках, а если сессии врублены то механизм будет искать по файлам есть ли такая то сессия
потеря сессии:
написано в описании функции session regenerate in с решением из костылей, но попробую объяснить.
допустим у меня хуевый инет 10 кбит/с. обновляю сразу 2 вкладки одного сайта. на одной вкладке мне выписало новую сессию, а другая еще не может отправить запрос на сервер из за пинга 20000, и вот отправила со старой кукой сессией ебать а ее нахуй на сервере нет уже. по итогу на 1 вкладке авторизация есть а на другой нет.
короч, все это паранойя, но делается просто и надежности прибавляет.
вот для чего нужна регенерация при авторизации, один из примеров:
Подмена сессии (Session Fixation)
Для подмены сессии злоумышленнику не нужен идентификатор чужой сессии, достаточно установить идентификатор своей сессии легальному пользователю, прошедшему авторизацию. Логика такого типа атаки противоположна по отношению к краже сессии, но в обоих случаях создается ситуация, при которой злоумышленник и легальный пользователь имеют один и тот же идентификатор сессии.
только в примере неточность есть. если чел прошел авторизацию и ему подменили куки, он что, из аккаунта не вылетит будто?
Отсутствие прав администратора на сервере. Надо работать с тем, что есть. Так ты можешь привести альтернативы gearman под шинду?
они может везде и есть, только за другие языки пусть говорят те, кто с ними плотно работает.
я-то как раз работаю в нормальной конторе на 7.1 с tdd и bp.
>>12485
пиздят - это хорошо. то, что используют не все сразу - это инерция, которой в пхп на мой взгляд больше, чем в других языках. опять же из-за легаси на phpnuke и прочем говне (утрирую).
эм, анонимные функции в 7.1? может ты путаешь с анонимными классами в 7.0? анонимные функции уже миллион лет есть.
анонимные классы я постоянно использую в тестах - очень удобная вещь для тестирования абстрактных классов
тебя там вообще походу в угол зажали. мало того, что винда, так еще тебе как админу админских прав не дают лол. посмотри rabbitmq, это тоже типа сервер очередей, может он работает в винде.
у меня только возникает сомнение, что ты сможешь его установить, если у тебя нет админских прав на сервере.
Админы отказываются обновлять php потому что там не только мой сервис и обновление php чревато непредсказуемыми последствиями. А вот какую-то отдельную приблуду поставить - которая бы не затрагивала php в целом и настройки сервера - они согласны.
Бамп.
ну вообще у меня на локальной машине стоит 3 версии php. они лежат в /etc/php/7.* и не конфликтуют друг с другом. в нжинксе явно указывается, какую версию использовать для конкретного сайта, а для cli можно прописать явно, какую версию использовать при вызове команды php.
более того, думаю можно версию, скомилированную с флагом, нужным для pthreads можно положить в отдельную папку и использовать по необходимости.
>Админы отказываются обновлять php потому что там не только мой сервис и обновление php чревато непредсказуемыми последствиями.
ЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯСНО.
Скажи этим пидорам, что они пидоры блять. И поставили тебе еще один пхп паралельно, нужной версии.
$action = isset($_POST["action"]) ? $_POST["action"] : null;
Так норм? Или правильные пацаны как-то иначе записывают?
>Вот это OCHE круто. А в апаче есть такая возможнсоть?
в нжинксе это делается одной строчкой в конфиге. в апаче не без танцев с бубном, но можешь попробовать https://stackoverflow.com/questions/42696856/running-two-php-versions-on-the-same-server
правда, это достаточно рискованное дело на проде.
алсо, в контексте нашего разговора о стеках, изначально ты сказал, что пользуешься виндой и тебя все устраивает. через несколько дней ты уперся в ограничения стека. я не злорадствую и желаю тебе успехов в борьбе с другими админами, но этот случай, считаю, для всех анонов поучителен - пхп под виндой это костыль и невозможность роста проекта.
на первый взгляд это кажется довольно бессмысленным, т.к. если в посте по ключу action значение не будет давать true на isset, оно будет либо равно 0, либо '', либо null. то есть смысл твоей конструкции в том, чтобы заменять 0 на null, но зачем это надо - непонятно.
если надо (зачем?), оставляй так (либо воспользуйся оператором ?? в семерке:
$action = $_POST["action"] ?? null;), либо можно просто напиши
$action = $_POST['action'];
>алсо, в контексте нашего разговора о стеках, изначально ты сказал, что пользуешься виндой и тебя все устраивает.
Не, такого не говорил. Кокрастыке я сам страдаю от этого. Но это сторонний проект, сервак не мой я просто разместил объяву. Щито поделать.
>$action = $_POST['action'];
Пикрелейтед. Я понимаю, что notice это даже не warning, но по-хорошему, наверное, их стоит избегать?
ПХП и Мускул из поставки вертригосервера.
Делаю в пхпмайадмин INSERT INTO бла-бла-бла ; SELECT LAST_INSERT_ID() - получаю то, что ожидаю получить. Делаю то же самое из пхп (внутри mysql_query()) - ошибка "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT LAST_INSERT_ID()' at line 1". Пробовал заменить точку с запятой на запятую, амперсанд и на ничего - результат тот же. Обычный инсерт инту (без точки с запятой и SELECT LAST_INSERT_ID()) работает как ожидается. Что делаю не так, как исправить?
1) для одного или нескольких запросов (разделённых ";") используются разные ф-ции, __например__, для устаревшего mysqli мульти-запрос: http://php.net/manual/ru/mysqli.multi-query.php
2) не рекомендую использовать "SELECT LAST_INSERT_ID()" в принципе, т.к. в нагруженном проекте он возвращает ХЗ что. Могу ошибаться, канешн, но ИМХО надёжнее выбрать запись обратно по известным признакам, отдельной процедурой.
ну типа "правильно" инициализировать все переменные и индексы хотя бы нулём, но на практике все забивают, и ничего ужасного не случается
норм.
ну я не уверен, что это хороший порядок причины и следствия
насчет того, что все забивают и ничего не страшного случается, не слушай. за такое отношение в приличных местах по рукам бьют.
$action = $_POST["action"] ?? '';
если совсем правильно хочешь, то надо в строковую переменную по умолчанию делать пустой строкой. тогда можно будет использовать тайп-хинтинг и, если нужно, поиграть в строгую типизацию.
>2) не рекомендую использовать "SELECT LAST_INSERT_ID()" в принципе, т.к. в нагруженном проекте он возвращает ХЗ что. Могу ошибаться, канешн, но ИМХО надёжнее выбрать запись обратно по известным признакам, отдельной процедурой.
Это как? Отдельный запрос ебошить? Может тогда уж лучше count()?
А в каких именно случаях "ХЗ что" вернется? Ну, кроме случая, когда долбоебы удалили запись из таблицы, "забыв" поправить автоинкремент?
>приличные места
в индустрии все просто выёбываются кто как может, а на практике бизнесы гребут бабло совершенно по другим критериям, нежели -- что ты там себе наинициализировал ;)
>для устаревшего mysqli
Ебать. А что сейчас-то используют? я до сих пор, по старинке, mysql_select_db, mysql_query, mysql_fetch_array... Я мамонт?
вообще yii2 поддерживает чуть ли не 5.3.
а это что за хостинг такой, если не секрет? в чем его преимущества?
да, мамонт, новые проекты делай с универсальным PDO (к любой БД) http://php.net/manual/ru/book.pdo.php
Старые оставляй как есть, если всё работает
это если ты подчиняешься напрямую бизнесу (фрилансишь, например). а если есть команда разработчиков, тимлид, аудит и прочее, то такой код не пропустят.
Ну вот смотрите, если я не “одаренный” чел, но который готов упорно работать, которому интересна работа с базами данных и сетямино это не точно ,но не интересна работа с дизайноми это тоже не точно, который хочет иметь карьерный рост и приличные деньги, но который хочет и пожить, то есть не все время тратить на программирование и изучение новых технологий, то PHP можно назвать верным путем, естественно учитывая, что помимо PHP нужно изучить и другие технологии?
не соглашусь. говнокод деморализует как если бы в центре офиса насрали кучу говна. то есть всерьез уже сложно относиться к работе.
если у фирмы есть продукт, который надо поддерживать и развивать (например есть приложение и вы продаете подписки), то качество кода важно, т.к. его читают и дописывают разные люди.
а если нужно сделать сайт автосервиса, то конечно им поебать, какие там нотисы летят. лавешка мутится и заебись
это понятно, просто я подозреваю что ты сам около фриланса крутишься, или в конторе, где полтора фулстека.
Блядь, а нахуй так сложно-то всё? ООП это ебаное (зачем оно мне в скрипте на 50 строк, блядь?), исключения и их перехват вместо mysql_error()
>Если ваше приложение не перехватывает исключение PDO конструктора, движок zend выполнит стандартные операции для завершения работы скрипта и вывода обратной трассировки. В этой трассировке будет содержаться детальная информация о соединении с базой данных, включая имя пользователя и пароль.
Мда, охуительно.
Эм, транзакции теперь обязательны везде, где они поддерживаются? Блджад, что за пиздец? Какой вообще профит от этого всего? Все равно я не могу единообразно работать с мускулом и редисом по определению.
По-моему, моя реакция обусловлена вот этим. Есть какой-нибудь гайд "PDO для дебилов" или урок от ОПа на этот счет? Ну, чтоб было понятно, зачем на все это говно тратить время, и какие профиты в итоге, я хз?
1. использование класса - это еще не ооп.
2. а в чем проблема поймать исключение, добавив четыре строчки кода?
3. в чем проблема автоматических транзакций? тебе же не надо ничего писать, оно там тихо само крутится
https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md там есть чуток про пдо, но
>зачем на все это говно тратить время
с таким подходом возможно тебе лучше дальше сидеть на mysql, правда ее выпилили из 7.0, но можно еще посидеть на 5.4, пока сервера с ней не рассыпятся в пыль.
>2. а в чем проблема поймать исключение, добавив четыре строчки кода?
Нахуй мне этот ПДО, если он сам не может их отлавливать, и мне помимо лишних строчек на ПДО надо добавлять лишние строчки на отлов его исключений (когда раньше строчек было аж две - mysql_query и if(mysql_error))? Зачем вообще что-то, неважно, что, ООП, исключения, что угодно еще, если можно было и без этого?
>3. в чем проблема автоматических транзакций? тебе же не надо ничего писать, оно там тихо само крутится
Оно, судя по мануалу, автоматически откатится, если я его прямо не завершу. В том, что майиасм не поддерживает транзакции, судя по тому же мануалу. И вся эта типа универсальность идет по пизде.
>>12880
>с таким подходом возможно тебе лучше дальше сидеть на mysql, правда ее выпилили из 7.0, но можно еще посидеть на 5.4, пока сервера с ней не рассыпятся в пыль.
Если так рассуждать, то с таким подходом нахуй идет пхп с его фирменным "через жопу, зато лаконично и просто", от которого (в случае с базами данных) нихуя не осталось
Ключевым было "зачем тратить время ЕСЛИ ПРОФИТЫ НЕОЧЕВИДНЫ".
Да я стараюсь, сорри, если мои посты выглядят как-то враждебно или ретроградно, я просто не понимаю, какой должен быть подход к этому ко всему. "О, вышла новая писька, а старую выпиливают, все как раньше без нее, только концептуально более лудше и всего в 5 раз больше кода, пойду скорее осваивать"? Чувствую себя изучающим фреймворк джаваскрипта, а не пхп.
>>12881
>"через жопу, зато лаконично и просто", от которого (в случае с базами данных) нихуя не осталось
ты чего бомбанул? остался примерно такой же mysqli,
но правда-истина в том, что PDO занимает такое же количество писанины, ничего не изменится в твоих скриптах на 50 строк, просто будет больше возможностей. Не бомби, всё в порядке, в 5 раз больше кода тебе писать не нужно -- просто можешь пользоваться дополнительными ООП плюшками, если захочешь.
>>12885
Вот смотри, все методы доступны как статические, тот же самый запрос в одну строчку:
http://php.net/manual/en/pdo.query.php
>1) вкатывальщики не нужны
Ты в общем говоришь или ты имеешь в виду, что с нулевым опытом не берут?
это просто факт, и в общем и в частном, вкатывальщик-2017 просто никому не нужен
исключения выбрасываются программой, а ловишь ты их сам. никто за тебя их ловить не будет.
по транзакциям, действительно странно написано в мануале. я никогда не заканчивал транзакции явно, все работало нормально.
>зачем тратить время ЕСЛИ ПРОФИТЫ НЕОЧЕВИДНЫ
пока профиты тебе неочевидны, то и не нужно. если твое приложение вырастет и надо будет нанять еще чувака для его поддержки, профиты станут очевидными
ну к сожалению, это во всех языках происходит, пакет "mysql" саппортили лет 20, потом расширили его до сих под живым расширенным mysqli, но по мере взросления стало понятно, что нужен универсальный драйвер к SQL базам. Он такой же простой в использовании, в те же пару строчек, ничего фатального не произошло, а возможностей -- больше. Короче, лучше кайфани, вместо бугурта.
2018, извините
Я тебя прекрасно понимаю, честно. Ты не хочешь увеличивать популярность WEB разработки, дабы не палить годноту/не увеличилась конкуренция/профессия не скатилась в хавно (нужное подчеркнуть). Но вот если чисто, между нами, не в общем смысле, а в прямом, профессия норм или есть большие подводные?
>ты чего бомбанул? остался примерно такой же mysqli,
Там еще более дохуя всякого.
>>12885
>но правда-истина в том, что PDO занимает такое же количество писанины, ничего не изменится в твоих скриптах на 50 строк
ООП, которое занимает строки, обработка исключений, которая занимает строки.
>>12887
А в чем разница тогда с всей предыдущей хуйней? Блядь, я запутался. По описанию exec и query примерно одно и то же делают, только результат разный возвращают.
>>12893
>исключения выбрасываются программой, а ловишь ты их сам. никто за тебя их ловить не будет.
Дак а зачем, опять же, в скрипте на 50 строк это, когда была mysql_error?
>>12893
>пока профиты тебе неочевидны, то и не нужно. если твое приложение вырастет и надо будет нанять еще чувака для его поддержки, профиты станут очевидными
А конкретнее?
>>12885
>ты чего бомбанул?
Просто ненавижу, когда что-то работает и всех устраивает, может, не идеально, но работает и всех устраивает, все годами пользуются, а потом какой-нибудь долбоеб решает навернуть пару уровней абстракций, которые нихера на практике даже не абстрагируют ничего (пример из мануала выше с транзакциями), требуют только больше писанины и надо переучиваться ради того, чтобы переучиваться, а толк ото всего этого непонятно какой. Не надо больше эксейпить значения переменных? Так все давно написали себе функцию автоматического добавления-удаления и забили.
>>12894
Пытаюсь, пока не выходит. Может, из-за языка написания документации.
>такой же простой в использовании, в те же пару строчек
Только теперь вместо двух функций обработка исключений (обработчик напиши сам, разумеется, стандартный вывалит логин-пароль при неудачной авторизации). И вместо двух функций 3 класса.
>саппортили лет 20
сэдфрог.жпг
Такс, анон, а если у меня уже таки есть код со старым mysql_connect и всем этим говном, и мне его надо показать прям через час, есть какие-нибудь бесплатные хостинги, где по-прежнему пхп5 стоит, или все уже на 7ую версию перекатились?
это я тебе писал; на тытьё отвечать не буду, захочешь -- попробуешь и сам увидишь, что всё норм.
А хостингов с РНР5 полно.
>Просто ненавижу КОКОКОКО
Просто оставь свои проекты на текущей версии и не бузи, всё будет работать
Как можно узнать о нём?
Т.е. как определяется что пользователь закрыл браузер и нужно сбросить кукисы?
У куки есть атрибут "время жизни", expires: https://ru.wikipedia.org/wiki/Cookie#Атрибуты_куки
Если его не указать, то кука называется "сессионной" и живет до закрытия браузера (или вкладок с сайтом).
Как-нибудь объясняется зачем делать куки сессионными за исключением очевидного, что пользователь может надолго оставить доступ к устройству и злоумышленник может этим воспользоваться?
Бесплатный, с пхп5 и мускулом, куда можно вот уже сейчас, в течение часа, залить и чтоб работало (подразумевается либо выдача домена от хостинга, либо реально быстрое прикрепление бесплатного доменного имени) можете подсказать? zzz.com.ua - пхп 7.1.12, хостингер совсем охуел, то ему мобильник мой нужен, то еще чего-то, не хочет просто дать мне залить проект.
Погодите, это я ебланю, с хуя ли из 7 выпилено-то мое говно мамонта? Работает все, даже ошибками типа "депрекейтед" не сыпет.
ты задал слишком общий вопрос, я так и ответил.
по теме - вкатывальщики нужны в дс, за другие города не скажу. работы без опыта не много, но она есть. главное - быть толковым и знать необходимый минимум: язык, ооп, бд (джоины, индексы), линукс и как вообще веб работает. и еще, не иди в битрикс работать, это карьерный тупик. найди контору с собственным продуктом, поработай там за еду полгода-год и дальше иди на норм зп в норм проект. такой план
ну mysql уже небезопасна, ее и выпилили. и пхп тут не виноват, так как она с 2013 года считается устаревшей.
а в чем проблема написать еще даже и 50 строк кода? это не повлияет на скорость работы или что-то такое. я так понимаю, ты не программист по основной деятельности, так что пиши какие-то вопросы по коду, тут помогут
профессия норм, если тебе нравится писать код. а ты так написал "не хочу тратить все время на изучение", что немного настораживает. то есть, тебя никто не заставляет по 15 часов педалить, но сам подход лучше поменять. главное, чтобы интерес был, а не чтобы сразу защищать свое личное время.
ну это мое мнение, может ты что-то другое имел в виду
это надо phpinfo смотреть. подозреваю, там не 7.1, либо mysql не вызывается
Чтобы не гадать, какой срок жизни поставить. Иногда делают галочку "запомнить меня", которая ставит фиксированный срок.
>>12908
> ООП, которое занимает строки,
Примерно столько же получается, сравни сам:
$result = mysql_query(...);
$result = $pdo->query(...);
Плюс, за счет исключений в PDO не нужно писать if с проверкой наличия ошибки. И экранировать переменные вручную не надо. Даже короче выйдет, я думаю.
> exec и query примерно одно и то же делают, только результат разный возвращают.
Так в этом и разница, exec используется для запросов вроде INSERT, которые ничего не возвращают.
> Только теперь вместо двух функций обработка исключений
Ты бы изучил исключения, прежде чем критиковать. Я даже писать ничего не буду, просто ссылку дам, прочти и пойми где ты ошибаешься https://github.com/codedokode/pasta/blob/master/php/exceptions.md
> стандартный вывалит логин-пароль при неудачной авторизации
Либо у тебя включен display_errors (и ты сам виноват), либо ты написал обработчик ошибок, который вываливает на экран логины и пароли, и опять же, ты сам виноват.
Я тебе советую изучить PHP получше, прежде чем критиковать. Если что, в нашем треде дадут подсказку, как сделать ту или иную вещь, только не надо разводить тут флую на полтреда.
> есть какие-нибудь бесплатные хостинги, где по-прежнему пхп5 стоит
Можно взять VPS (скорее всего небесплатный, цены смотри на poiskvps.ru) и поставить любую версию PHP через phpenv.
>>12894
Причины, почему задепрекейтили mysql, описаны тут https://wiki.php.net/rfc/mysql_deprecation и тут https://stackoverflow.com/questions/16859477/why-are-phps-mysql-functions-deprecated
Чтобы не гадать, какой срок жизни поставить. Иногда делают галочку "запомнить меня", которая ставит фиксированный срок.
>>12908
> ООП, которое занимает строки,
Примерно столько же получается, сравни сам:
$result = mysql_query(...);
$result = $pdo->query(...);
Плюс, за счет исключений в PDO не нужно писать if с проверкой наличия ошибки. И экранировать переменные вручную не надо. Даже короче выйдет, я думаю.
> exec и query примерно одно и то же делают, только результат разный возвращают.
Так в этом и разница, exec используется для запросов вроде INSERT, которые ничего не возвращают.
> Только теперь вместо двух функций обработка исключений
Ты бы изучил исключения, прежде чем критиковать. Я даже писать ничего не буду, просто ссылку дам, прочти и пойми где ты ошибаешься https://github.com/codedokode/pasta/blob/master/php/exceptions.md
> стандартный вывалит логин-пароль при неудачной авторизации
Либо у тебя включен display_errors (и ты сам виноват), либо ты написал обработчик ошибок, который вываливает на экран логины и пароли, и опять же, ты сам виноват.
Я тебе советую изучить PHP получше, прежде чем критиковать. Если что, в нашем треде дадут подсказку, как сделать ту или иную вещь, только не надо разводить тут флую на полтреда.
> есть какие-нибудь бесплатные хостинги, где по-прежнему пхп5 стоит
Можно взять VPS (скорее всего небесплатный, цены смотри на poiskvps.ru) и поставить любую версию PHP через phpenv.
>>12894
Причины, почему задепрекейтили mysql, описаны тут https://wiki.php.net/rfc/mysql_deprecation и тут https://stackoverflow.com/questions/16859477/why-are-phps-mysql-functions-deprecated
Ловить их не требуется, только сделать глобальный обработчик исключений, если нужна красивая страница ошибки. Он пишется где-то в 7 строчек.
> я никогда не заканчивал транзакции явно, все работало нормально.
Значит, ты их неправильно использовал.
>>12886
Иди в тред перезвонивших или в /web наверно с таким вопросом. Тут можно написать пару постов про поиск работы, но полтреда заполнять флудом не надо. Это не тред психологической поддержки.
Что касается вопроса, что нужно знать, и какой спрос на новичков, попробуй открыть сайт с вакансиями вроде hh.ru и сделать исследование вакансий по интересующей тебя технологии. Я не HR.
>>12884
mysql выпиливают уже лет 5, я думаю. Ты где был все это время? тут вот https://wiki.php.net/rfc/mysql_deprecation стоит дата 2012 год. Если ты учился по устаревшему учебнику, то зря. Опять же, никто тебе не запрещает поставить 5.6 и сидеть на нем до конца жизни, код свободный, как хочешь, так и используй.
>>12881
> надо добавлять лишние строчки на отлов его исключений
не надо
> Оно, судя по мануалу, автоматически откатится, если я его прямо не завершу.
В этом и суть транзакции, она не коммитится, пока ты этого не подтвердишь. Если тебе это не нужно - не используй их. Ты вообще теорию изучать пробовал? Ты не разобрался в предмете и полтреда исписал жалобами.
>>12879
Ловить не надо.
Ловить их не требуется, только сделать глобальный обработчик исключений, если нужна красивая страница ошибки. Он пишется где-то в 7 строчек.
> я никогда не заканчивал транзакции явно, все работало нормально.
Значит, ты их неправильно использовал.
>>12886
Иди в тред перезвонивших или в /web наверно с таким вопросом. Тут можно написать пару постов про поиск работы, но полтреда заполнять флудом не надо. Это не тред психологической поддержки.
Что касается вопроса, что нужно знать, и какой спрос на новичков, попробуй открыть сайт с вакансиями вроде hh.ru и сделать исследование вакансий по интересующей тебя технологии. Я не HR.
>>12884
mysql выпиливают уже лет 5, я думаю. Ты где был все это время? тут вот https://wiki.php.net/rfc/mysql_deprecation стоит дата 2012 год. Если ты учился по устаревшему учебнику, то зря. Опять же, никто тебе не запрещает поставить 5.6 и сидеть на нем до конца жизни, код свободный, как хочешь, так и используй.
>>12881
> надо добавлять лишние строчки на отлов его исключений
не надо
> Оно, судя по мануалу, автоматически откатится, если я его прямо не завершу.
В этом и суть транзакции, она не коммитится, пока ты этого не подтвердишь. Если тебе это не нужно - не используй их. Ты вообще теорию изучать пробовал? Ты не разобрался в предмете и полтреда исписал жалобами.
>>12879
Ловить не надо.
Погугли статью на Хабре про PDO. ООП и исключения, конечно, надо понимать, чтобы читать статью.
>>12876
Трассировка выводится на экран, только если включен display_errors.
> транзакции теперь обязательны везде
нет. В mysql по умолчанию включен AUTOCOMMIT, погугли, что это. В других СУБД - не обязательно.
>>12860
Погугли статьи про зарплаты разработчиков. PHP точно не самый прибыльный язык. ну и работу желательно искать где-нибудь в Калифорнии. И не разводи тут столько флуда.
>>12850
Сюда нужно добавить strval, так как иначе могут передать например массив и твой код сломается. Не доверяй данным от пользователя.
>>12824
notice это ошибка в коде. Ее надо исправлять.
>>12845
Ты ошибаешься, last_insert_id как раз самая корректная функция, для каждого соединения last_insert_id свой и проблем не будет.
>>12826
Нужно добавлять strval, так как могут передать массив вместо строки.
Погугли статью на Хабре про PDO. ООП и исключения, конечно, надо понимать, чтобы читать статью.
>>12876
Трассировка выводится на экран, только если включен display_errors.
> транзакции теперь обязательны везде
нет. В mysql по умолчанию включен AUTOCOMMIT, погугли, что это. В других СУБД - не обязательно.
>>12860
Погугли статьи про зарплаты разработчиков. PHP точно не самый прибыльный язык. ну и работу желательно искать где-нибудь в Калифорнии. И не разводи тут столько флуда.
>>12850
Сюда нужно добавить strval, так как иначе могут передать например массив и твой код сломается. Не доверяй данным от пользователя.
>>12824
notice это ошибка в коде. Ее надо исправлять.
>>12845
Ты ошибаешься, last_insert_id как раз самая корректная функция, для каждого соединения last_insert_id свой и проблем не будет.
>>12826
Нужно добавлять strval, так как могут передать массив вместо строки.
count(descendant::...) = 0
>>12485
Если ты не используешь анонимные функции, это не значит, что они не нужны. Я их использую, например. Например, для сортировки по произвольному критерию, вместе с array_map/array_filter, и тд. Добавили их в 5.4.
Анонимные классы - насколько я знаю, типичный пример это обработчики событий в Ява, наверно тут они для той же цели.
>>12491
Session fixation работает тогда, когда посторонний может как-то задать id сессии. Например, если он передается через GET-параметр, злоумышленник дает пользователю ссылку example.com?sid=12345678, пользователь залогинивается (и это записывается в сессию 12345678), после чего злоумышленник сам заходит по такой же ссылке и оказывается тоже залогинен (так как у него тот же id сессии, в которой стоит признако залогиненности).
Потому не надо передавать id сессии через что-то, кроме кук.
>>12490
Еще есть вариант просто не использовать сессии вообще. Не так они и нужны.
>>12483
Рассмотри еще вариант не использовать сессии вообще.
Пароль не надо хранить открытым текстом, храни соленый хеш от него. Иначе злоумышленник, получив доступ к серверу или дискам от него, или бекапам, получает готовые пароли.
> каждые 20 минут генерация нового ид сессии
Непонятно, зачем. Ты приводил ниже пример, но в браузере куки общие для всех вкладок.
count(descendant::...) = 0
>>12485
Если ты не используешь анонимные функции, это не значит, что они не нужны. Я их использую, например. Например, для сортировки по произвольному критерию, вместе с array_map/array_filter, и тд. Добавили их в 5.4.
Анонимные классы - насколько я знаю, типичный пример это обработчики событий в Ява, наверно тут они для той же цели.
>>12491
Session fixation работает тогда, когда посторонний может как-то задать id сессии. Например, если он передается через GET-параметр, злоумышленник дает пользователю ссылку example.com?sid=12345678, пользователь залогинивается (и это записывается в сессию 12345678), после чего злоумышленник сам заходит по такой же ссылке и оказывается тоже залогинен (так как у него тот же id сессии, в которой стоит признако залогиненности).
Потому не надо передавать id сессии через что-то, кроме кук.
>>12490
Еще есть вариант просто не использовать сессии вообще. Не так они и нужны.
>>12483
Рассмотри еще вариант не использовать сессии вообще.
Пароль не надо хранить открытым текстом, храни соленый хеш от него. Иначе злоумышленник, получив доступ к серверу или дискам от него, или бекапам, получает готовые пароли.
> каждые 20 минут генерация нового ид сессии
Непонятно, зачем. Ты приводил ниже пример, но в браузере куки общие для всех вкладок.
Нет, PSR говорит, что надо всегда ставить скобки. Без скобок легко сделать ошибку, плюс другому человеку потом не понравится ставить скобки за тебя.
>>12430
надо опираться на PSR, а не на свое личное мнение. Или хотя бы писать, что это твое, а не общепринятое, мнение.
>>12347
Нет, дизайнер это другая профессия. Рост есть, если развивать кругозор, а не ограничиваьться одной технологией.
>>11861
Не надо писать $$name. Надо использовать массив, а не уродливые ненадежные костыли, в таких случаях.
>>11824
Вместо $$name надо использовать массив. Не учи плохому. Массив специально придуман для случаев, когда надо искать данные в списке по индексу, не надо изобретать кривые костыли.
>>11787
Не понял вопрос. В SQL нет рекурсии.
>>11781
Ты изучал DI? Тут нельзя использовать DI? https://github.com/codedokode/pasta/blob/master/arch/di.md
> или лучше на каждый его метод, который требует бд, передавать бд?
Соединение с БД это зависимость и ее логичнее внедрять через конструктор.
> А если у него пара методов с бд тоже вшивать?
А может ты просто неправильно спроектировал класс? Каждый класс должен заниматься своим делом.
Нет, PSR говорит, что надо всегда ставить скобки. Без скобок легко сделать ошибку, плюс другому человеку потом не понравится ставить скобки за тебя.
>>12430
надо опираться на PSR, а не на свое личное мнение. Или хотя бы писать, что это твое, а не общепринятое, мнение.
>>12347
Нет, дизайнер это другая профессия. Рост есть, если развивать кругозор, а не ограничиваьться одной технологией.
>>11861
Не надо писать $$name. Надо использовать массив, а не уродливые ненадежные костыли, в таких случаях.
>>11824
Вместо $$name надо использовать массив. Не учи плохому. Массив специально придуман для случаев, когда надо искать данные в списке по индексу, не надо изобретать кривые костыли.
>>11787
Не понял вопрос. В SQL нет рекурсии.
>>11781
Ты изучал DI? Тут нельзя использовать DI? https://github.com/codedokode/pasta/blob/master/arch/di.md
> или лучше на каждый его метод, который требует бд, передавать бд?
Соединение с БД это зависимость и ее логичнее внедрять через конструктор.
> А если у него пара методов с бд тоже вшивать?
А может ты просто неправильно спроектировал класс? Каждый класс должен заниматься своим делом.
Есть старая технология RSS, которая позволяет отслеживать обновления на сайте. На странице гитхаба с релизами есть RSS-лента ( https://github.com/composer/composer/releases.atom ), подпишись на нее любым RSS ридером. Также, композер умеет сам проверять свои обновления и обновляться, посмотри справку по нему.
>>11608
Поделюсь с тобой секретом. В магазинах, особенно если страна называется не "Япония", товары имеют свойство менять цену (в Японии затяжной кризис и это происходит раз так в лет 10-20). Вряд ли покупатель будет рад тому, что в его заказе цена будет так же меняться. При заказе надо фиксировать цену и любые другие существенные условия покупки (скидку, цену доставки итд) путем дублирования их в таблице заказов.
Не забудь, что покупатель может купить несколько копий товара.
order_id | item_id | count | ordered_price | ...
Также, нужно предотвратить удаление из БД товара, который упомянут в заказе. Например, за счет внешних ключей. Лучше вообще никогда не удалять товары, а только помечать их скрытыми. Либо перемещать в архивную таблицу с обновлением внешних ключей.
Правильно, что придерживаешься нормализации.
> буду писать запрос типа
А зачем группировка-то? Можно и без нее.
>>11604
Можно. Это называется составной естественный ключ. Это также защищает от вставки одной и той же пары id 2 раза.
Да. Только важно не придумывать замены return там, где он лучше подходит, так писать не стоит:
$validator->validate($user);
$errros = $validator->getErrors();
Тут лучше написать
$errors = $validator->validate($user);
>>12992
>Вместо $$name надо использовать массив. Не учи плохому
сорян. ну это я написал в данных условиях (когда есть несколько переменных не в массиве). если можно переписать входные данные на $words[] = [...] и т.д., то лучше сделать
$i = 1;
foreach ($words as $word) {
echo $word[array_rand($word)];
if (0 === $i++ % 3) {
echo "/n";
}
}
спасибо за секрет - я действительно об этом не подумал (реального опыта работы с интернет-магазинами не было). получилась бы неудобная ситуация, лол
я думаю, лучше в ordered_items дублировать цену для товара на момент заказа, а в самом заказе размер скидки и доставки, и считать это агрегатной функцией опять же.
а почему не использовать группировку? это накладно?
- сокеты, "неумирающий" PHP. По сокетам, да ещё и для PHP-шников, статей как кот наплакал.
- некачественный код в популярных библиотеках/фреймворках. У новичков мало опыта и они впитывают информацию как губки из чужих библиотек, это хорошо. Но бывает библиотека некачественная и прививает плохие практики. Например у этой библиотеки дурацкий API: https://github.com/php-curl-class/php-curl-class
> $curl = new Curl();
> $curl->get('https://www.example.com/')
> if ($curl->error) {
Тут явно напрашивается класс Response и иммутабельный подход в целом. Ещё Yii - это прямо сборник плохих подходов:
- неявное вместо явного (магические методы)
- доступность сервис-локатора отовсюду
- синдром Not Invented Here: https://github.com/yiisoft/yii2-httpclient
Как сделать так, чтобы текст был с боку от картинки?
Как импортировать html через php?
Как начать зарабатывать?
Как заставить себя учить и не быть тупым идиотом?
Это не я, чесслово. Всю рекламу ставит юкоз. Он меня уже поддостал, и я думаю, не перенести ли сайт на гитхаб.
>>1106146
https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2
>Да. Исключение - это способ для функции сообщить о непреодолимой, неожиданной ошибке. А тот, кто ее вызвал, может, если захочет, его обработать, но это не обязательно.
Почему мне тогда просто не поставить try/catch на роутер, а если кто то захочет обрабатывать какую либо ошибку, напишет себе личный try/catch на тот метод, который хочет?
>При оформлении SQL кода стоит придерживаться этого руководства по стилю: http://www.sqlstyle.guide/ru/
вроде сделал
>В дальнейшем тебе стоит также подумать о создании отдельной публичной папки, а сейчас у тебя по сути все файлы вывалены в общий доступ.
я думал у меня только index.php в публичном доступе
>В репозиторий стоит добавить README с кратким описанием проекта и инструкцией по установке. Образцы (можно даже более кратко сделать):
Напишу как сделаю
>>class CheckForm
>> const REG_FORM_SEX_MAN = "Мужской";
>Эту константу уместнее поместить в студента, а не в проверяльщик формы.
Почему?
>Методы checkRegForm() и checkProfileInfo() содержат много одинакового кода. Копипаста кода - это зло. Потому что изучать такой код в 2 раза дольше, править в 2 раза дольше.
Сделал общий. Но по мне он непонятнее и сложнее в изучение чем кучка ифов.
>Папку лучше назвать не Student, а Entity или Model.
почему?
>https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist/blob/master/src/DbConnect/DbConnect.php
>Этот класс не очень-то и нужен, тебе ведь никто не запрещает просто создать PDO через new.
вообще я украл это. ну и как я понимаю, он для того что бы данные для пдо из ини файла брать.
>Тут стоит попробовать применить Dependency Injection: https://github.com/codedokode/pasta/blob/master/arch/di.md
не понимаю. я вроде делаю большинство того что там написано
>> public function SearchStudents($search, table $table)
>Здесь проблема в том, что ты возвращаешь "неполноценные" объекты Student, у которых не заполнена часть полей. Это усложняет код, так как в нем где-то гуляют полностью заполненные объекты, а где-то нет и различить их невозможно. >Получив такой объект, ты не знаешь - у студента пустое название группы или оно просто не загружено. Если ты хочешь вернуть только 4 поля, надо использовать массив или отдельный объект. Но лучше бы вернуть полноценных студентов.
В смысле гулять. Он же используется только в профайле и потом уничтожается. А возвращаться полноценых с хешомпароля, логином и тд не опасней?
>(в роутере) Вместо exit лучше бы поставить return.
почему?
>> header('location: http://localhost:8081/login');
>Тут зря ты прописал домен и порт, как перенести код на другой домен?
То как я дселал сейчас нормально?
>Контроллеры profile и reg наверно можно объединить?
но они же разные
И еще пара вопросов
Я сначала подключая headers, и потом к нему только тело. Это нормально?
Сама реализация стала адевкатной или я все еще делаю "дичь"? В примеру в первой версии я смешал ооп и процедурный код и вообще была полная параша.
Теже контролеры. Приемлимо их так делать? Нормально ли создавать их и вызывать функцию doExecute (что я тоже кстати подсмотрел), когда это можно все в конструктор запихать. Нормально ли создавать в них классы и потом их передавать тем кто нуждаются?
Нужно ли мне использовать интерфейсы и абстракт класы к примеру к контролерам?
А еще я запушил новые файлы и папки а старые так же остались и получилась каша. Как скрыть старые?
>>1106146
https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2
>Да. Исключение - это способ для функции сообщить о непреодолимой, неожиданной ошибке. А тот, кто ее вызвал, может, если захочет, его обработать, но это не обязательно.
Почему мне тогда просто не поставить try/catch на роутер, а если кто то захочет обрабатывать какую либо ошибку, напишет себе личный try/catch на тот метод, который хочет?
>При оформлении SQL кода стоит придерживаться этого руководства по стилю: http://www.sqlstyle.guide/ru/
вроде сделал
>В дальнейшем тебе стоит также подумать о создании отдельной публичной папки, а сейчас у тебя по сути все файлы вывалены в общий доступ.
я думал у меня только index.php в публичном доступе
>В репозиторий стоит добавить README с кратким описанием проекта и инструкцией по установке. Образцы (можно даже более кратко сделать):
Напишу как сделаю
>>class CheckForm
>> const REG_FORM_SEX_MAN = "Мужской";
>Эту константу уместнее поместить в студента, а не в проверяльщик формы.
Почему?
>Методы checkRegForm() и checkProfileInfo() содержат много одинакового кода. Копипаста кода - это зло. Потому что изучать такой код в 2 раза дольше, править в 2 раза дольше.
Сделал общий. Но по мне он непонятнее и сложнее в изучение чем кучка ифов.
>Папку лучше назвать не Student, а Entity или Model.
почему?
>https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist/blob/master/src/DbConnect/DbConnect.php
>Этот класс не очень-то и нужен, тебе ведь никто не запрещает просто создать PDO через new.
вообще я украл это. ну и как я понимаю, он для того что бы данные для пдо из ини файла брать.
>Тут стоит попробовать применить Dependency Injection: https://github.com/codedokode/pasta/blob/master/arch/di.md
не понимаю. я вроде делаю большинство того что там написано
>> public function SearchStudents($search, table $table)
>Здесь проблема в том, что ты возвращаешь "неполноценные" объекты Student, у которых не заполнена часть полей. Это усложняет код, так как в нем где-то гуляют полностью заполненные объекты, а где-то нет и различить их невозможно. >Получив такой объект, ты не знаешь - у студента пустое название группы или оно просто не загружено. Если ты хочешь вернуть только 4 поля, надо использовать массив или отдельный объект. Но лучше бы вернуть полноценных студентов.
В смысле гулять. Он же используется только в профайле и потом уничтожается. А возвращаться полноценых с хешомпароля, логином и тд не опасней?
>(в роутере) Вместо exit лучше бы поставить return.
почему?
>> header('location: http://localhost:8081/login');
>Тут зря ты прописал домен и порт, как перенести код на другой домен?
То как я дселал сейчас нормально?
>Контроллеры profile и reg наверно можно объединить?
но они же разные
И еще пара вопросов
Я сначала подключая headers, и потом к нему только тело. Это нормально?
Сама реализация стала адевкатной или я все еще делаю "дичь"? В примеру в первой версии я смешал ооп и процедурный код и вообще была полная параша.
Теже контролеры. Приемлимо их так делать? Нормально ли создавать их и вызывать функцию doExecute (что я тоже кстати подсмотрел), когда это можно все в конструктор запихать. Нормально ли создавать в них классы и потом их передавать тем кто нуждаются?
Нужно ли мне использовать интерфейсы и абстракт класы к примеру к контролерам?
А еще я запушил новые файлы и папки а старые так же остались и получилась каша. Как скрыть старые?
мне вот лично интересна не конкретная тема, а такая, где человек имеет опыт и ему есть что сказать. плюс у ОПа на любые темы получается интересно писать.
по поводу сокетов: в ютубе есть хорошее видео с какой-то конференции про асинхронный пхп, там все достаточно интересно и подробно рассказано. завтра буду за компом и скину ссылку.
Че?
А чем плох нынешний дизайн? Также, ты недооцениваешь сложность работы. Там куча мелочей вроде отступов и тд.
Нет если ты хочешь сохранить дизайн то дело твое, если хочется держать олдскуль то все ок.
Я бы добавил шрифты читабельные, побольше привлекательности и каких нибудь свистулек, чтобы сайт казался модернизированным.
Я не сторонник "свистулек". Для меня главные критерии, это удобство чтения, удобство пользования и навигации, скорость загрузки и работы.
Выглядеть "современным" - это для меня не является критерием.
Если говорить про реальные недостатки, то это, например, отсутствие адаптированной мобильной версии - это реальная проблема. Идеи, что тут можно сделать, приветствуются.
Насчет шрифтов - я за улучшение читабельности. Но за счет чего? Увеличения размера и межстрочного интервала? Тогда будет неудобно читать на небольших экранах (можно, конечно, увеличить шрифт только для больших экранов - я в общем-то не против, но у меня нет большого монитора, чтобы протестировать).
Или ты намекаешь на веб-шрифты? У меня к ним негативное отношение. Они тяжелые, замедляют загрузку и отображение сайта (текст не рендерится пока не загрузится шрифт), часто они плохо рендерятся под Windows. Я сторонник встроенных в систему шрифтов, благо в Windows много разных стандартных шрифтов.
То есть, если ты хочешь написать про какие-то моменты, которые можно улучшить, я буду рад замечаниям. Если у тебя есть идеи, как должна выглядеть и работать мобильная версия, или версия для огромных мониторов - тоже буду рад. Если ты знаешь, как сделать текст более читабельным - напиши, как.
А если речь о том, чтобы просто поменять стиль и сделать сайт похожим на какой-то другой, то я не очень понимаю, какая мне и читателям от этого выгода. Вот, у Ютуба, напримепр недавно поменяли дизайн на "материальный" и на него теперь больно смотреть (хотя это конечно очень субъективно, кому-то нравится, кому-то нет).
Сделай как на Гите у тебя, там как раз то что я имел ввиду. Простота и сплошная приятность.
Представь что твой сайт это книга или статья. Держи цвета в минимуме и гармонии (Обычно работает 1-4 оттенка), чем больше контраста и округленности - Тем лучше.
Во всем остальном руководствуйся семантикой, она рождает распорядок, когда ставить отступы, создавать элементы и т.д
Ютуб делал опросы, собирал информацию, делал беты и т.д и так уж получилось что количество одобривших оказалось больше, и получилось соответствие логике стандартов
Я тут это... проспорил. Сам не знаю как так вышло.
Суть такова-я за 8 дней изучаю Vue.js и в качестве проверочного задания пишу форму заполнения брифа, которая формирует письмо и отправляет на указанный адрес.
Я проиграл или есть шансы?
Никогда и никому не делай тестовые задания, рыжик.
Тысячу раз ведь уже, в каждом втором треде, ну скокаможна.
Поставил.
>position: static;
Ничего не изменилось, перенос строки все так же идет.
Еще варианты?
<button id="_close" form="none" onclick="openbox('windowLogin')">Закрыть</button>
</div>
линк на восстановление пароля
<br>
линк на регистрацию
</div>
position это не ширина, я имел ввиду параметр width/max-width, поставь там ширину фиксированную: px, em, pt в wrap элементе и ничего не будет изменяться при передвигании окна, как бы ты не старался.
Ты смотрел код по ссылке?
Да, сделал фиксированный размер окна и кнопок.
Но дело не в этом.
Когда я подключаю код в индексе, все нормально.
Когда я подключаю в другой странице этот же код - появляется двойной перенос строки после формы. В этом- проблема.
Почему такое может быть?
>>09863 (OP)
Анон, помоги вот с чем:
хочу, чтобы пользователь вводил страну, а получал её ID из базы данных.
Сейчас запнулся на регулярных выражениях.
https://ideone.com/Q3Gv2P
Не могу взять в толк, как правильно вытаскивать значение, введенное пользователем, чтобы потом скармливать его реквесту SQL.
$_GET[$country] — используй хотя бы htmlspecialchars, и ограничь поле длиной до максимального названия страны - тиинидад и тобаго самое длинное что сейчас приходит в голову.
Регеэкспы делай в самом сиквеле, подключайся через PDO.
Я немного нуб, немного. ха ха и посему отвечу:
1.Там есть всякие "Бермудские острова" + БД может быть расширена. Нет смысла в ограничении на количество символов.
2.
>используй хотя бы htmlspecialchars
Зачем?
3.
>Регеэкспы делай в самом сиквеле, подключайся через PDO.
А в чем профит?
1. Очень хуево спроектированная БД
2. Чтобы не эксплуатировале поле для всяких атак
3. Профит в том, что сверяешь с данными в БД, а не с данными не пойми с чем. У тебя регулярка проверяет поле country с чем? Тебе надо выполнить подклбчение через безопасный объект PDO к БД, осуществить поиск и сверить, после дать ответ.
1.Я взял список стран с id через API json, прошелся в нотпаде автозаменой и залил в БД.
Ну ты понял, что это НЕ ОЧЕНЬ крутая БД?
2.Внутреннее использование и только. Никто из вне сети не должен иметь доступ.
3.
>а не с данными не пойми с
С регуляркой.
>У тебя регулярка проверяет поле country с чем?
$regexp= '/[A-zа-яёА-ЯЁ]{2,}/u';
Ну это тебе делать, а не нам, так что мы тут вряд ли ответим.
>>13701
Не гадай, а освой инструменты разработчика (Ctrl + SHift + I) и посмотри.
>>13746
Ох, какой страшный код, прямо как из учебника 10-летней давности.
Включи у себя локально вывод всех ошибок в php.ini (display_errors = On , error_reporting = -1) и ты увидишь предупреждение по поводу строки 13.
Вместо preg_match_all надо использовать preg_match.
Что ты хотел проверить регуляркой, непонятно. Она просто проверяет что в строке есть хотя бы 2 буквы среди прочих символов.
Ты какие-то странные советы даешь.
htmlspecialchars надо использовать при выводе данных.
Как и зачем использовать регулярку в SQL, я не понял.
>Что ты хотел проверить регуляркой, непонятно. Она просто проверяет что в строке есть хотя бы 2 буквы среди прочих символов.
Ну, чтобы была заполнена хоть чем-то, это "чем-то" не символы или цифры.
Подскажите пожалуйста.
Допустим я хочу сделать свой автозагрузчик для создания объектов, но я не понимаю как сделать чтоб он автозагружал не только сам класс, но и родителя и интерфейсы и примеси для класса, если они есть. В двух словах можно намекнуть?
Не надо ничего специально делать. PHP сам вызовет автозагрузчик для каждого дополнительного класса (родителя, интерфейса итд).
Ах да, забыл сказать, у меня еще неймспейсы, не вызывает.
Cам класс лежит в условном classes/main, его абстрактный родитель в classes/abs, интерфейсы в classes/intefaces, если неймспейс глобальный то и проблем нет, я не спорю, а с "кастом" неймспейсами просто вываливается ошибка что для класса SomeItem не найдем родитель Item и так далее.
Ну либо я дурак и чего-то не догоняю.
Есть разве что мысль чтоб автозагрузчик как-то ловил исключения и по ним подключал нужные интерфейсы и родителей, но я при мысли об этом чувствую как едет крыша.
если у тебя труктура неймспейса дублирует структуру папки, проблем быть не должно. если не дублирует, а все неймспейсы различаются префиксом, то используй автозагрузчик композера и там все их прописывай типа
{
"autoload": {
"psr-4": {
"MyLibrary\\": "src/",
"MyApp\\Plugins\\": "plugins/"
}
}
}
пример отсюда https://github.com/codedokode/pasta/blob/master/php/autoload.md
1. Да, БД не оч, но преобразовать под свои нужды все де можно. Поэтому юзай какую-нибудь тулзу визуальную для редактирования
2. Хорошо
3. У тебя в коде не видно коннекта к БД и не понятно что регулярка проверяет. Шаблон есть, а входных данных не видно.
>>13789
Эта функция экранирует спец символы и как разультат защищает от ввода в поле > <script>touch_my_tra_lya_lya()</script>
По сиквелу еще раз повторяю, для сопоставления данных введенных в поле и взятых из базы.
Не изобретай свои схемы наименования папок, а используй PSR-4, тебе ссылку уже выше дали на урок.
Спасибо, почитаю.
Тут возникают периодами вопросы что нужно знать для прохождения собеса. Я вот хожу на них и вот такой списочек возник.
1. Что такое ооп? Ну и каждый пункт.
2. Как работает сервер.
3. Виды протоколов. http ftp smtp pop
4. Рестфулл апи?
5. SQL. select insert join having вы будите писать запросы на бумажке.
6. Проектирование бд, нормализация.
7. Вы будете писать php код на бумажке тоже!!! Маленькие функции, но все равно будете. Задачки будут на рекурсию точно. Факториал, Фибоначчи. Два раза попались задачки из учебника Опа.
Ни разу не спросили про хтмл и цсс.
Еще возможно будет тестовое. Тут разные вариации. Я делал
приложение с авторизацией и динамической загрузкой страниц с помощью AJAX. Древовидные комментарии.
На самом собесе главное не волноваться. Это очень сложно было для меня. Кроме похода на собес не в девелоп контору. Там было похуй.
Вакансии июнек. Мне кажется это норм, как ты еще подтвердишь что хоть что-то знаешь умеешь? Хули ты три строчки факториала не сможешь написать? Я читал про долбоебов которые заказывают решение тестовых, у которых знаний хуй. И вот чтобы таких отсеять и делают это. Конечно ебаная практика. Я привык хуярить код, а потом тестить его. И с первого раза у меня ничего не работает. Опыта же нуль. Но с другой стороны это просто покажет что ты хоть с синтаксисом знаком.
лечи нервишки
https://ideone.com/6zjEBp
Вот вторая часть кода.
Не могу понять, почему у меня не выводится результат.
Логин/пасс точные при подключении?
В сиквеле у тебя явная ошибка: ты выбираешь id и сравниваешь с именем.
Логи пассы я заменил ололо! дианон1 хотя, кому я нахуй нужен...
>ты выбираешь id и сравниваешь с именем.
В смысле?
Про логин/пасс я уточнил, а то вдруг ты не додумался их заменить.
> $str_sql_query = "SELECT id FROM dbCountries WHERE name LIKE '%$word%' OR alias LIKE '%$word%' ";
После селекта пишешь name вместо id
Меня больше интересует, как выводить значения из $result = mysql_query($str_sql_query, $link);
>Не гадай, а освой инструменты разработчика (Ctrl + SHift + I) и посмотри.
ф12 клацнуть проще.
И что я там должен увидеть?
Всё правильно. Так и должно быть. Если ты хочешь увидеть содержимое ввиде текста, самоое легкое это через var_dump посмотреть
1) расширение mysql устарело, переходи на mysqli или PDO
2) не подставляй переменные в запрос напрямую, будет SQL инъекция, читай урок https://github.com/codedokode/pasta/blob/master/security/sql-injection.md
Там для каждого элемента выводится его размер, паддинги и маргины, примененные CSS праивла. Можно увидеть, в чем проблема.
Прочитай мануал по mysql_query и что она возвращает. http://php.net/manual/ru/function.mysql-query.php
Прости, Анон, но я никак не пойму, что мне нужно сделать, чтобы вытянуть из mysql_query id-шник.
>>13867
Мне его обязательно нужно будет передать.
>>13870
Сейчас для меня это не особо важно, т.к. срок горит.
Обещаю, что в следующей задаче (а это первая на моем счету) постараюсь сделать все "по-взрослому", но вот прям щас хоть на костылях.
Надо читать мануал http://php.net/manual/ru/mysql.examples-basic.php и смотреть код там. Вообще, тебе надо еще учиться.
>Вообще, тебе надо еще учиться
Слушай, я, как бэ, даже не заикался про то, что я там супер-пупер дохуя джедай, который ебет всех в рот.
Просто есть я и задача. И я не понимаю, как добиться результата.
Вот например:
Я посмотрел, что mysql_connect можно подключать напрямую к БД, без mysql_select_db
Написал :
mysql_connect(localhost, Uname, Upass, BDname) и потратил 15 минут, пытаясь понять. почему не работает. Как итог - вернулся назад.
https://ideone.com/N0rYXs
Все! Сделал. Теперь осталось придумать, как вложить это в цикл, где будет sql запрос получать значения из массива.
А есть способ возвращать обычный массив, при использовании регулярного выражения?
>>13908
>бабах
Спасибо, мне очень важно твое мнение.
Я с тобой ничем не делился сука, на тебя мнение тратить хуже быть червем пидором, сьеби отсюда ибо тебе уже никто не поможет, ты потерян сука. Ты хуже спортсмена Гоши который программирует лучше чем ты.
Зачем ты пишешь сюда и засоряешь тред своими мыслями вслух? Нам твое каждое движение не интересно, поверь.
тебе подсказали про mysqli и pdo, а ты такой "ну щас накостылить надо, а учиться потом". после таких слов вряд ли кому-то будет интересно что-то обсуждать. за тебя никто костылить не будет.
иди на фл.ру и там тебе за 300 рублей решат твою задачу как раз с помощью mysql. тут не сайт бесплатных решений
>тебе подсказали про mysqli и pdo
Посоветовали улучшить код, в виде улучшения защиты от взлома.
Вот скажи, нахуя это нужно, если 0-ая угроза взлома?
>за тебя никто костылить не будет.
Лол, и не требуется.
Вон тот анон >>13887 дал мануал, я побился головой и решил задачу.
Сирисли, ты какой-то выебистый. Меньше мни из себя спасителя, к которому приходят с протянутой рукой.
>>13917
Ну это да.
Чё злой такой?
> Также, композер умеет сам проверять свои обновления и обновляться, посмотри справку по нему.
Я только узнал, что после 60 дней необновления он выводит сообщение Warning: This development build of composer is over 60 days old. It is recommend
ed to update it by running "C:\ProgramData\ComposerSetup\bin\composer.phar self-
update" to get the latest version.
Но можно ли его как-то сконфигурировать, например изменить кол-во дней, не смог узнать.
По поводу автообновления, нашел советы по типу добавить в планировщик задач команду self-update.
> На странице гитхаба с релизами есть RSS-лента
Вот это как раз то, что нужно. Подписался
я спаситель треда, лол
плюсы указанных расширений не только в защите от взлома, там тебе вроде еще кинули вот эту ссылку https://stackoverflow.com/questions/16859477/why-are-phps-mysql-functions-deprecated если она тебя не убедила, то и не парься пока. решил задачу и хорошо.
Ну это вообще пиздец какой-то.
php --rf empty/isset
Ну и конечно не забываем, что есть php.net с поиском и документацией...
Спасибо за ответ!
> Зачем в каждой папке лежит пустой gitignore?
Создаётся командами типа make:controller. Поудаляю
> Почему имя файла начинается с подчеркивания?
Подсмотрел у knpuniverse. Без подчеркивания - это страница, с подчеркиванием - какой-то элемент: форма, модуль, и т.п. По-моему удобно. Да и в библиотеках такое встречал (вроде в EasyAdmin)
> "{{ path('tests', {'tag': tag.name}) }}"
> Вот это мне не нравится. Разве не лучше было бы написать getTestsByTagUrl(tag)? Так мы собираем код генерации URL в одном месте, а не размазываем по шаблонам, получаем тайп-хинты, можем делать дополнительные проверки. Можем как-то централизованно влиять на генерацию URL.
Че-то я не понял, о чем ты
> По переменным окружения - не стоит ли добавить им уникальный префикс вроде TH_..., чтобы они были гарантированно уникальными?
И тут тоже не понял, о каких переменных ты говоришь
> https://github.com/TheSidSpears/test_hub/blob/master/templates/tests/list.html.twig#L8
> 'attr': {
> 'value': searchValue
> Что-то выглядит как костыль. Значение в форму в контроллере прописать нельзя?
Я долго искал, как это реализовать. В итоге нашел вариант переопределить поле: $form->add('search', null, ['data' => $searchString]);
Но меня ждал облом: You cannot add children to a submitted form
Как переопределить аттрибут поля, а не всё поле целиком, я найти не смог. Но что-то мне подсказывает, что такая возможность должна быть
> Почему strict_variables включены только в режиме debug?
Почитал issue, понял о чем речь. С тобой согласен, поставил strict_variables: true
А вот в routing.yaml у меня стоит strict_requirements: ~ и я не знаю, что означает тильда
> Роуты в аннотациях
Один проект я уже сделаю с роутами в аннотациях, в этом перенесу в конфиге. По итогу мне будет понятно, что удобней
> Неудачная идея, по моему, делать присваивание внутри if.
В данном случае я исправил и код стал проше. Но в принципе, я не понимаю, что плохого в присваивании внутри if
> https://github.com/TheSidSpears/test_hub/blob/master/src/Migrations/Version20171208191454.php#L18
> Тут charset utf8 стоит, а не utf8mb4
Исправил. А для того, чтобы в миграциях автоматически проставлялась верная кодировка, мне пришлось добавить doctrine.dbal.default_table_options.charset: utf8mb4 и doctrine.dbal.default_table_options.collate: utf8mb4_unicode_ci, не смотря на то, что уже стоит doctrine.dbal.charset: utf8mb4
По-моему, это не круто, что придётся прописывать в каждом проекте настройки, которые для mysql являются дефолтными
> https://github.com/TheSidSpears/test_hub/blob/master/src/Repository/TestRepository.php#L19
> Для не меняющегося запроса, наверно короче будет написать его на DQL.
У меня короче не получилось https://ideone.com/6Wqs9R
Осталось разобраться с тестами. Алсо, выставляю на проверку https://github.com/TheSidSpears/test_hub
Спасибо за ответ!
> Зачем в каждой папке лежит пустой gitignore?
Создаётся командами типа make:controller. Поудаляю
> Почему имя файла начинается с подчеркивания?
Подсмотрел у knpuniverse. Без подчеркивания - это страница, с подчеркиванием - какой-то элемент: форма, модуль, и т.п. По-моему удобно. Да и в библиотеках такое встречал (вроде в EasyAdmin)
> "{{ path('tests', {'tag': tag.name}) }}"
> Вот это мне не нравится. Разве не лучше было бы написать getTestsByTagUrl(tag)? Так мы собираем код генерации URL в одном месте, а не размазываем по шаблонам, получаем тайп-хинты, можем делать дополнительные проверки. Можем как-то централизованно влиять на генерацию URL.
Че-то я не понял, о чем ты
> По переменным окружения - не стоит ли добавить им уникальный префикс вроде TH_..., чтобы они были гарантированно уникальными?
И тут тоже не понял, о каких переменных ты говоришь
> https://github.com/TheSidSpears/test_hub/blob/master/templates/tests/list.html.twig#L8
> 'attr': {
> 'value': searchValue
> Что-то выглядит как костыль. Значение в форму в контроллере прописать нельзя?
Я долго искал, как это реализовать. В итоге нашел вариант переопределить поле: $form->add('search', null, ['data' => $searchString]);
Но меня ждал облом: You cannot add children to a submitted form
Как переопределить аттрибут поля, а не всё поле целиком, я найти не смог. Но что-то мне подсказывает, что такая возможность должна быть
> Почему strict_variables включены только в режиме debug?
Почитал issue, понял о чем речь. С тобой согласен, поставил strict_variables: true
А вот в routing.yaml у меня стоит strict_requirements: ~ и я не знаю, что означает тильда
> Роуты в аннотациях
Один проект я уже сделаю с роутами в аннотациях, в этом перенесу в конфиге. По итогу мне будет понятно, что удобней
> Неудачная идея, по моему, делать присваивание внутри if.
В данном случае я исправил и код стал проше. Но в принципе, я не понимаю, что плохого в присваивании внутри if
> https://github.com/TheSidSpears/test_hub/blob/master/src/Migrations/Version20171208191454.php#L18
> Тут charset utf8 стоит, а не utf8mb4
Исправил. А для того, чтобы в миграциях автоматически проставлялась верная кодировка, мне пришлось добавить doctrine.dbal.default_table_options.charset: utf8mb4 и doctrine.dbal.default_table_options.collate: utf8mb4_unicode_ci, не смотря на то, что уже стоит doctrine.dbal.charset: utf8mb4
По-моему, это не круто, что придётся прописывать в каждом проекте настройки, которые для mysql являются дефолтными
> https://github.com/TheSidSpears/test_hub/blob/master/src/Repository/TestRepository.php#L19
> Для не меняющегося запроса, наверно короче будет написать его на DQL.
У меня короче не получилось https://ideone.com/6Wqs9R
Осталось разобраться с тестами. Алсо, выставляю на проверку https://github.com/TheSidSpears/test_hub
1)Для начала хотел бы избавиться с пробелами и перевести строку $text в нижний регистр, но программа выдает ошибки, в чем проблема?(Код программы https://ideone.com/4ARugv)
2)В каких случаях нужно использовать строку mb_internal_encoding('udf-8')?
>>14273
>>14271
>>14273
1) utf-8 бро. у тебя udf.
Unicode (or Universal Coded Character Set) Transformation Format – 8-bit
2) Короткий ответ - всегда, так как эта кодировка кодирует символы из все алфавитов. Но на ideone не работают mb_ функции. Там до сих пор не поlключили нужный модуль к php.
А так твой код работает как надо.
Скилы:
-Лондон из зе кэпитал оф грейт бурито - 5\10, читаю фанфики, разговорный не качал пока зря, думаю - с ним можно работать без всяких пехапе
-Гуру пейнта, сони вегаса и прочих фотошопов - 4\10
-Администрирование, эникей и прочая "Почему принтер не работает и кто поставил VNC?!" - 4\10
-Матан - 1\10 я у мамки гуманитарий
Стоит ли вкатываться, если планирую рубить трафик с пиратского контента, или РЫНОЧЕК ПОДЕЛЕН? ха-ха не пиздите тут мне Подводных камней не боюсь, если они преодолимы. Работать буду соло. Какие подводные камни? Кроме того, что РОСКОМНАДЗОР щемит благородных господ?
>Иди в воркач или бизнесач. Там все твои друзья.
Таки вы считаете кодинг настолько унылым, или это я не вписываюсь в рамки индуса? Ближайшие полтора года у меня быдлоработка два на два, за это время я постараюсь освоить высшую нервную деятельность, в то время пока спинной мозг будет лепить гвнокод, я буду думать о запиливании/продвижении своих рамок/поисков/экстракторов медиа на чужое добро и конечно приготовлюсь стилить идеи с eng-сектора. Воркач от меня не уйдет он придет сюда
Не трогай ни эту часть «кодинга», ни сам «кодинг» в целом.
Я бы предложил тебе заняться нормальной деятельностью. Зачем делать какие-то незаконные сайты и рисковать, если можно заниматься нормальной легальной работой? Также, наш тред не поддерживает пиратство.
Матан для программирования сайтов не нужен.
Изучай PHP/JS либо верстку + JS и иди занимайся нормальной работой. Если ты умеешь работать с графическими редакторами, а тем более если у тебя есть вкус и понимание, что красиво, а что нет, что модно, какие цвета гармонично сочетаются, то это будет большим плюсом.
Хех не трогать веб своими грязными руками? После гуглов-яндексов-меилрушечек мне эту выебанную шлюху трогать не очень то хочется, однако единственное тело, готовое вкладывать трудочасы в мои концепты и делиться профитом - это я сам, засим избавлю вас от своего общества, извините за беспокойство, но глупо начинать что-то не спросив на двачах смачно рыгает и почесывает яица, вернусь через месяц надеюсь что нет
https://pastebin.com/YuE5zb8d
Этот код не запустится, но может кто глянет глазком почему при каждой итерации внешнего цикла, внутренний каждый раз делает только первую итерацию. Пикрелейтед.
Постараюсь, просто покоптив небо у меня сложилось устойчивое впечатление, что законы и налоговая - это две вещи, мешающие зарабатывать, этот травматический опыт будет сложно преодолеть.
Спасибо, анон!
Спасибо дружище.
На http://sandbox.onlinephpfunctions.com/ все заработало.
Только вот я та и не понял зачем включать mb_internal_encoding(), если без него все работает? Для стиля что ли?) Ну да ладно.
ВСЕХ С НАСТУПАЮЩИМ НОВЫМ ГОДОМ!!!!
Нет, срсли, уже учу.
П — прокрастинация. Книгу пол года назад купил php 7 симдянова и котерова. До нее покупал рнр 5 в далеком 2008. До этого потинкту пытался учить рнр.
Давеча решил позырить тенденции в рнр, охуел он пеар, композер, как все разворачивают, ооп и прочие штуки. В мою бытность бралась ЦМС, и к ней искались/писались плагины. Сейчас проще с фреймворком работать, чем с ЦМС.
Меня больше рнр интересует как расширенный диалект Си. Одно удовольствие на нем писать утилиты для автоматизации. Сайты не мое, хотя я их 10 лет назад делал...
Почему ты знаешь Си, но не знаешь ООП и другие перечисленные тобой вещи, которые можно изучить за пол часа?
Я его когда-то давно учил из интереса. Хотел писать клиент-серверные gui приложения под линух, но из-за уебищности gtk+ скудоумия быстро забросил.
Я по профессии сись одмен, погромировааие хобби
ООП это изи
Придумываешь объект и какие у него свойства и методы могут быть и пишешь класс
Например, User
class User
{
private $name;
private $password;
...
}
Вся суть ООП
Дальше MVC (Model View Controller)
Модель занимается состоянием программы
Отображение выводит его пользователю
Контроллер дирижирует ими двумя
namespace App\Model;
use App\Model\User;
class Database
{
public function addUser(User $user)
{
...
}
public function getUser(int $id): User
{
...
}
public function deleteUser(int $id)
{
...
}
}
namespace App\Model;
class User
{
...
}
namespace App\View;
class View
{
public function render(...)
{
...
}
}
namespace App\Controller;
use App\Model\Database;
use App\View\View;
class Controller
{
//Dependency Injection (DI)
private $db;
private $view;
//DI
public function __construct(Database $db, View $view)
{
$this->db = $db;
$this->view = $view;
}
public function registration()
{
$user = new User(...);
$this->db->addUser($user);
$this->view->render(...);
}
}
index.php
require_once ...;
use App\Model\Database;
use App\View\View;
use App\Controller\Controller;
$db = new Database();
$view = new View();
$controller = new Controller($db, $view);
$controller->registration();
Дальше лучше изучить какой-нибудь фреймворк. Советую slim https://www.slimframework.com/ Его можно изучить за вечер. Он даст представление о том как должно выглядеть приложение в идеале.
Композер тоже изи
Устанавливаешь
Используешь команды require, install, update...
Не забываем под автоподгрузку классов https://getcomposer.org/doc/01-basic-usage.md#autoloading
https://getcomposer.org/doc/00-intro.md
https://getcomposer.org/doc/01-basic-usage.md
Готово! Теперь вы знаете php и вы восхитительны!
Надеюсь ты правда не знал всего этого и я не зря это писал
ООП это изи
Придумываешь объект и какие у него свойства и методы могут быть и пишешь класс
Например, User
class User
{
private $name;
private $password;
...
}
Вся суть ООП
Дальше MVC (Model View Controller)
Модель занимается состоянием программы
Отображение выводит его пользователю
Контроллер дирижирует ими двумя
namespace App\Model;
use App\Model\User;
class Database
{
public function addUser(User $user)
{
...
}
public function getUser(int $id): User
{
...
}
public function deleteUser(int $id)
{
...
}
}
namespace App\Model;
class User
{
...
}
namespace App\View;
class View
{
public function render(...)
{
...
}
}
namespace App\Controller;
use App\Model\Database;
use App\View\View;
class Controller
{
//Dependency Injection (DI)
private $db;
private $view;
//DI
public function __construct(Database $db, View $view)
{
$this->db = $db;
$this->view = $view;
}
public function registration()
{
$user = new User(...);
$this->db->addUser($user);
$this->view->render(...);
}
}
index.php
require_once ...;
use App\Model\Database;
use App\View\View;
use App\Controller\Controller;
$db = new Database();
$view = new View();
$controller = new Controller($db, $view);
$controller->registration();
Дальше лучше изучить какой-нибудь фреймворк. Советую slim https://www.slimframework.com/ Его можно изучить за вечер. Он даст представление о том как должно выглядеть приложение в идеале.
Композер тоже изи
Устанавливаешь
Используешь команды require, install, update...
Не забываем под автоподгрузку классов https://getcomposer.org/doc/01-basic-usage.md#autoloading
https://getcomposer.org/doc/00-intro.md
https://getcomposer.org/doc/01-basic-usage.md
Готово! Теперь вы знаете php и вы восхитительны!
Надеюсь ты правда не знал всего этого и я не зря это писал
Спасибо, анон. В ООП пытался, писал простые классы, в твоём примере смотрю уже даже тип данных User есть, это сахар от какого то фрэймворка?
> public function addUser(User $user)
Все эти поля, пространство имён, приватные поля... сложна :-( и нудно но уж в этом-то году я точно выучу РНР ахахахха
Это имя класса User
Любой класс можно объявить как тайпхинт
https://secure.php.net/manual/ru/functions.arguments.php#functions.arguments.type-declaration
Лихо, даже не знаю, где такое может пригодиться. РНР развился со времен 5.0/5.1 которые я учил оч сильно. Спасибо, антош, за старания.
Скидываю MY JAAAAM
https://youtu.be/dSLcZ4yR-Ck?t=34m55s
https://youtu.be/dSLcZ4yR-Ck?t=36m10s
https://youtu.be/fkYIAdJvP5Q?t=38m45s
https://soundcloud.com/rootkitmusic/rootkit-good-2-go-feat-tylor-maurer
https://soundcloud.com/thisisechelon/ghastly-goldplate-dogs-in-the-house
https://soundcloud.com/mustdiemusic/hellcat-habstrakt-remix
https://soundcloud.com/jadebluemusic/bodyrox-ft-luciana-yeah-yeah-jade-blue-bootleg
Тут почти моя сокровищница, на следующий год еще раскрою. Но только избранный найдет путь дальше.
Если знаете английский - Выучите все остальные языки без проблем и станете полиглотом.
Знаете Си - Знаете все языки программирования.
выброси книги котерова, бро. мой тебе совет. это говно мамонта. читай нормальные книги по ооп-языкам (джаве, например), мануал php и реальный код (симфони, например). еще есть http://www.phptherightway.com/ для ознакомления с тем, что изменилось с 2008.
алсо, странно ты зырил "тенденции". пеар уже давно почил, а композер - "тенденция" уже шесть лет лол
(сорри за нотки иронии)
если ты так думаешь, то ты очевидно не знаешь английский и себя обманываешь типа "вот в этом главная проблема". узнаешь и поймешь, что надо сидеть на жопе и каждый язык учить минимум полгода, погружаясь в хаос новой инфы и чувствуя себя беспомощным и никчемным достаточно долго, прежде чем придет какая-то уверенность.
также очень спорная мысль, что зная процедурный низкоуровневый язык программирования, ты типа легко выучишь высокоуровневый ООП. ну хз. ты сам на каком уровне знаешь си? хорошо? а какие еще языки?
то есть, ты может и знаешь, я хз. я вот знаю и просто читаю инфу на английском. не представляю, как можно быть программистом и не знать английский, а ждать, пока кто-то соизволит перевести. никакой супер форы это не дает, скорее я просто (как и многие тут) имею доступ к той инфе, которая открыта для всего мира (американцев, европейцев, индусов). а ведь по двум из трех самых популярных фреймворков на php даже нет русской документации.
но вот почему знание английского равно знанию всех остальных языков?
Для меня это все стало открытием. Я понятия не имкл про пеар и композер. Я з говорю, брал нуленый цмс а ля DLE и к нему уже писали/искали плагины. Это сейчас composer init, composer install yoba-framework и у тебя почти готовый проект, осталось только пару зависимостей устранить и шаблон под себя в каком-нибудь css-шаблонизаторе переделать.
>если ты так думаешь, то ты очевидно не знаешь английский и себя обманываешь типа "вот в этом главная проблема".
Что? Знаю английский на уровне B2 и это за год с A2. Свободно читаю документацию, использую речь и понимаю диалоги. Пишу каждый день слова, заучиваю и все автоматизированно тащемта, даже грамматика.
>узнаешь и поймешь, что надо сидеть на жопе и каждый язык учить минимум полгода, погружаясь в хаос новой инфы и чувствуя себя беспомощным и никчемным достаточно долго, прежде чем придет какая-то уверенность.
Что? Ничего не понятно что ты пытаешься сказать, такое ощущение что ты проецируешь свои проблемы на меня, попытаюсь ответить. Ну во первых как человек который не говорил, что он ЗНАЕТ английский, а знает на уровне B2 отвечу, что язык не выучить НИКОГДА и НИКАКОЙ, это невозможно, можно выучить его составляющие и ими руководствоваться. (Английский кстати я подтянул только потому, что еще русский начал учить)
>также очень спорная мысль, что зная процедурный низкоуровневый язык программирования, ты типа легко выучишь высокоуровневый ООП.
Не знаю все учат без проблем и не жалуются, опять же как будто свои проблемы проецируешь или придумываешь там что-то, завязывай, тебе не знать что там у других людей.
>ты сам на каком уровне знаешь си? хорошо? а какие еще языки?
Не знаю критерии хорошего в Си, но думаю лапше-код избегаю. Другие языки: Паскаль, Фортран, Си/C++/C#, Java, LUa, Lisp, Go и все другие, ну еще Баш.
Сам Страуструп говорил, что без Си не понять С++, и в своей же книге пишет, что сначала нужно пройти курс Си, дабы понять содержимое, оно и верно, новичок не поймет С++ и зачем он, Си вообще должен быть базой после Фортрана или Паскаля.
>то есть, ты может и знаешь, я хз. я вот знаю и просто читаю инфу на английском. не представляю, как можно быть программистом и не знать английский, а ждать, пока кто-то соизволит перевести. никакой супер форы это не дает, скорее я просто (как и многие тут) имею доступ к той инфе, которая открыта для всего мира (американцев, европейцев, индусов). а ведь по двум из трех самых популярных фреймворков на php даже нет русской документации.
А еще переведенная информация передается не в том контексте в каком ее предоставляют и многие понятные места в русском переводе сложные в силу лексической аутентичности.
>но вот почему знание английского равно знанию всех остальных языков?
Английский язык состоит из Французского, Латинского, Греческого(Чуть-чуть), грамматические правила не имеют никаких исключений, есть единые правила, но например в одном языке, возьмем английский, есть отличные грамматические временные глаголы, сам язык аналитический и страдает дефицитом того, что есть в Русском синтетическом и замещает этот недостаток своими Tense глаголами. Т.е языковые отличия нулевые. Если есть опыт в освоении сути одного языка, то с каждым новым выученным языком все становится проще и проще, выучишь Латинский - Без проблем освоишь Испанский, или Английский, или Немецкий, или Французский. Т.е вся суть лежит в ядре.
>если ты так думаешь, то ты очевидно не знаешь английский и себя обманываешь типа "вот в этом главная проблема".
Что? Знаю английский на уровне B2 и это за год с A2. Свободно читаю документацию, использую речь и понимаю диалоги. Пишу каждый день слова, заучиваю и все автоматизированно тащемта, даже грамматика.
>узнаешь и поймешь, что надо сидеть на жопе и каждый язык учить минимум полгода, погружаясь в хаос новой инфы и чувствуя себя беспомощным и никчемным достаточно долго, прежде чем придет какая-то уверенность.
Что? Ничего не понятно что ты пытаешься сказать, такое ощущение что ты проецируешь свои проблемы на меня, попытаюсь ответить. Ну во первых как человек который не говорил, что он ЗНАЕТ английский, а знает на уровне B2 отвечу, что язык не выучить НИКОГДА и НИКАКОЙ, это невозможно, можно выучить его составляющие и ими руководствоваться. (Английский кстати я подтянул только потому, что еще русский начал учить)
>также очень спорная мысль, что зная процедурный низкоуровневый язык программирования, ты типа легко выучишь высокоуровневый ООП.
Не знаю все учат без проблем и не жалуются, опять же как будто свои проблемы проецируешь или придумываешь там что-то, завязывай, тебе не знать что там у других людей.
>ты сам на каком уровне знаешь си? хорошо? а какие еще языки?
Не знаю критерии хорошего в Си, но думаю лапше-код избегаю. Другие языки: Паскаль, Фортран, Си/C++/C#, Java, LUa, Lisp, Go и все другие, ну еще Баш.
Сам Страуструп говорил, что без Си не понять С++, и в своей же книге пишет, что сначала нужно пройти курс Си, дабы понять содержимое, оно и верно, новичок не поймет С++ и зачем он, Си вообще должен быть базой после Фортрана или Паскаля.
>то есть, ты может и знаешь, я хз. я вот знаю и просто читаю инфу на английском. не представляю, как можно быть программистом и не знать английский, а ждать, пока кто-то соизволит перевести. никакой супер форы это не дает, скорее я просто (как и многие тут) имею доступ к той инфе, которая открыта для всего мира (американцев, европейцев, индусов). а ведь по двум из трех самых популярных фреймворков на php даже нет русской документации.
А еще переведенная информация передается не в том контексте в каком ее предоставляют и многие понятные места в русском переводе сложные в силу лексической аутентичности.
>но вот почему знание английского равно знанию всех остальных языков?
Английский язык состоит из Французского, Латинского, Греческого(Чуть-чуть), грамматические правила не имеют никаких исключений, есть единые правила, но например в одном языке, возьмем английский, есть отличные грамматические временные глаголы, сам язык аналитический и страдает дефицитом того, что есть в Русском синтетическом и замещает этот недостаток своими Tense глаголами. Т.е языковые отличия нулевые. Если есть опыт в освоении сути одного языка, то с каждым новым выученным языком все становится проще и проще, выучишь Латинский - Без проблем освоишь Испанский, или Английский, или Немецкий, или Французский. Т.е вся суть лежит в ядре.
У меня в электронном виде макулатуры по пограмированею отдельный внешний диск на 1 Тб, там асма до всяких бэйсиков... все в свое время пробовал изучать. Котеров и Симдянов мне по душе, стоит заметить, что их труд для уже представляющих что такое программирование. Стиль изложения сложноват, но это потому что книга не для новичков в программировании. В целом неплохая книга, объемная.
Я другие читал, в том числе от расмуса нашего лердорфа.
https://github.com/visavi/rotor
>Паскаль, Фортран, Си/C++/C#, Java, LUa, Lisp
воу-воу, профессор, полехче
>Не знаю все учат без проблем и не жалуются, опять же как будто свои проблемы проецируешь или придумываешь там что-то, завязывай, тебе не знать что там у других людей.
у меня проблем нет, разве что с ленью.
вообще новые ЯП учат без проблем и без знания си, так-то. тем более современные бекенд-ООП-языки все похожи (сужу по php и java) и странно, если будут проблемы с выучиванием нового, если уже один знаешь.
так-то си - полезный язык. просто чем он тебе поможет выучить тот же php больше, чем другой яп - хз.
>Си вообще должен быть базой после Фортрана или Паскаля
нигде уже не используют паскаль как первый ЯП кроме кабинетов информатике в СНГ, т.к. учебные пособия от 1995 года лень переписывать. уже давно и в европе, и везде используют питон или джаву. про фортран я уж не буду говорить, это какие-то стереотипы из перестроечных НИИ.
в остальном мне ход твоей мысли понятен, но по мне так ты сильно теоретизируешь. чтобы выучить английский и испанский, никто не учит сначала латинский. все учат сразу то, что нужно, и нормально живут. также и с ЯП.
да, только проекты пропорционально усложнились и выросли в объеме по сравнению с тем, что было в ранние годы.
>>14557
ну если нравится, то читай, но тогда еще рекомендую изучать реальный код - какие-то простые библиотеки можешь взять для контроля. потому что котеров на мой взгляд в развитии остановился на уровне 5.3 и того стиля, в котором писали тогда.
может ошибаюсь, давно не интересовался его литературой. если актуальные скинешь примеры его кода, будет интересно.
Не я ничего против современных языков не имею, это даже хорошо что преподают как базу их вместо Паскалей и Фортранов, я просто не знаю чему там сейчас учат. Но Питон правда уши за этот год прожужжал, неплохой язык если так посмотреть, интересные вещи выдает. Мне понравилось как с ним ботнет создали для Твиттера.
Ну и Латинский учить не надо, но как пример сойдет. Си это Латинский если подумать. Не обязателен, но без него трудно будет познавать другие языки, чем с ним, что наоборот.
котеров видимо не в курсе, что такое PSR
https://github.com/igorsimdyanov/php7/blob/master/phpdocs/PHP7/Page.php
if(empty($picture)) mail($mail_to, $thm, $msg);
else send_mail($mail_to, $thm, $msg, $picture);
за такое бьют по рукам в конторах, где следят за качеством кода. к сожалению, видимо, котеров о существовании таких контор за 40 лет преподавательской деятельности пока не узнал.
https://github.com/igorsimdyanov/php7/blob/master/mail/handler.php
блин, ну книга по ПХП7, а пишет так, как на ПХП4 писали на моей первой работе. это просто полный пиздец. там в каждой строчке пиздец.
https://github.com/igorsimdyanov/php7/blob/master/exec/dead.php
он упоротый что ли ставить ?>
это я навскидку зашел в три разных файла, везде наплевательское отношение к коду. что можно было бы ожидать от фрилансера васи пупкина из урюпинска, но не от автора книг по ЯП. это все печально.
я прошу прощения, что так реагирую. на мой взгляд это шарлатанство, которое вредит людям, которые покупают его книги.
короче, если тебе нравится, то ты читай конечно, список тем вроде обширный. но учитывай, что писать код как он - не надо.
писать код как он - не надо, а так как программирование - это наука про код, лучше сожги это говно. больше приобретешь
это как учить детей русскому языку и самому на уроках употреблять слова типа "ложить" или "созвОнимся". невежество
Так это код, скорее всего, с 5.0/5.1 версии немного адаптированный местами под 7 версию. На то время это может норма была?
Мне как новичку в 2008 понравилась книга, хоть я её так до конца и не осилил. Ошибок там, кстати, хватало, у Котерова есть форум, где пишут про косяки, их там...
Я тебя услышал, анон. Советуй норм лит-ру for dummies beginners
Я тебя услышал
котеров пытается делать книги а-ля англоязычные по джаве и плюсам (например от герберта шилдта), но не хватает скиллов и желания что-то там изучать. подозреваю, что он последний реальный код писал на заре двухтысячных годов, а потом только учил людей.
прикол в том, что по пхп пока нет нормальных книг, в отличие от той же джавы. с чем это связано - хз, может из-за того, что раньше пхп расматривался не как промышленный язык, а чтобы по-быстрому гостевую наговнякать. поэтому пока увы. если кто-то придет и скажет, что вот есть прямо охуенные англоязычные книги, будет интересно обосрать заценить.
есть учебник ОПа, но там совсем основы. также есть его паста на гитхабе (ссылки вверху темы). я еще рекомендую курсы от pr-of-it, у них есть три курса, внезапно php1, php2 и php3. там по качеству кода и по самой подаче материала все охуенно и хитро построено. если жалко денег, можешь качнуть с торрентов. я сам частично качал, а частично за бабло проходил.
https://github.com/jupeter/clean-code-php вот скорее не книга (очень уж урезана по сравнению с оригиналом), а портированный с джавы сборник best practices, тоже полезно посмотреть.
Спасибо, ещё раз. Не знаю на какой хуй ты на меня воемя тратишь, но тем не менее спачибо. Почитаю.
Чем именно тебя Котеров не устраивает. Читал его последнюю. По моему вполне себе вышло неплохо.
братюнь, вот тут >>14606 примерно ответил. если в последней книге ситуация поменялась, скинь примеры кода, обсудим и сравним с тем, что было раньше (на примере https://github.com/igorsimdyanov/php7)
Какая-то критика уровня батхёрта. За что бьют по рукам. Где конкретно неправильно? А как надо было?
>там в каждой строчке пиздец.
Что конкретно не так? Опять не объяснил.
>он упоротый что ли ставить ?>
В чём неправота то? Так можно делать. Или объясни почему ты считаешь это неправильным?
Я не защищаю Котерова, но такая критика - это просто размещение ссылок на гитхаб и "Фу пидор , код говно." Как-то хочется из треда научиться как кодировать стоит а как нет. А в итоге после таких комментариев сидишь в шоке и думаешь "А что конкретно то не так?"
И да, я понимаю что мб ты работешь в теме лет 10 и для тебя всё очевидно. Но для новичка типа меня нет.
я не 10 лет работаю, но не надо работать 10 лет, чтобы понимать как следовать стандартам.
давай по пунктам, которые есть
1. есть такая штука http://www.php-fig.org/psr/psr-2/ это разработчики языка и некоторых важных вещей в нем (например, популярных фреймворков) собираются и обсуждают гайдлайны, по которым хорошо бы писать код, чтобы каждый не выдумывал свои стили, отступы и прочее. котеров на эти гайдлайны кладет болт https://github.com/igorsimdyanov/php7/blob/master/phpdocs/PHP7/Page.php
посмотри сам и сравни с примером кода
2. у котерова
if(empty($picture)) mail($mail_to, $thm, $msg);
else send_mail($mail_to, $thm, $msg, $picture);
надо
if (empty($picture)) {
mail($mail_to, $thm, $msg);
} else {
send_mail($mail_to, $thm, $msg, $picture);
}
в отличие от js, в пхп для читаемости и очевидности пишут фигурные скобки ВСЕГДА.
3. ставить закрывающий тег в файле, который содержит только php-код (без html), не нужно, т.к. это может привести к появлению лишних пробелов при выполнении и к ошибке во всяких конструкциях include, require, работе с буфером и некоторых других функциях. поэтому его не используют - чтобы не объебаться. котеров на это кладет хуй, т.к. не видел реальный код.
4. по поводу пиздеца в каждой строке, я конечно не буду комментировать каждую строку, но навскидку
> if (!preg_match($pattern, $_POST['mail_to'])) {
exit("Введите адрес в виде s0@zomebodyANUSservern_=PUNCTUMcJA.om");
}
видимо, автор книг по php не слышал про исключения.
> $_POST['mail_subject'] =
>htmlspecialchars(stripslashes($_POST['mail_subject']));
зачем это на разных сточках?
> $_POST['mail_msg'] =
>htmlspecialchars(stripslashes($_POST['mail_msg']));
> $msg = $_POST['mail_msg'];
я может чего-то не понимаю, но почему не сделать $msg = htmlspecialchars ... ?
> if (!$fp) {
> print "Файл $path не может быть прочитан";
> exit();
> }
почему выше написано exit("Введите адрес в виде somebo0d@dyANUSsJjyerverPUNCTUMco(TLm") а тут сначала print, а потом exit без сообщения?
> if(empty($_POST['mail_to'])) exit("Введите адрес получателя");
> if (!empty($_FILES['mail_file']['tmp_name'])) {
> if(!mail($to, $thm, $multipart, $headers))
> {
чем обсуловлено то, что в каждой строчке по-разному написано?
короче и так далее. там много всего. самый главный косяк в файле - это то, что все сделано в стиле "простыня кода", т.е. если функция выполнилась (не вернув нихуя), то идем дальше на header. это полное говно, так в реальности делать нельзя из-за того, что ты такой код будешь отлаживать в 10 раз дольше.
и по другим файлам я не смотрел, просто чувак живет в каком-то параллельном мире, где все пишут код на 486-х и выходят в интернет по модему. мне немного обидно за всю ситуацию, т.к. он позволяет себе учить новичков и берет за это деньги. а новички потом такие "оп, заебись!", и идут работать в битрикс за копейки на всю жизнь, хороня свою карьеру php программиста лол
я не 10 лет работаю, но не надо работать 10 лет, чтобы понимать как следовать стандартам.
давай по пунктам, которые есть
1. есть такая штука http://www.php-fig.org/psr/psr-2/ это разработчики языка и некоторых важных вещей в нем (например, популярных фреймворков) собираются и обсуждают гайдлайны, по которым хорошо бы писать код, чтобы каждый не выдумывал свои стили, отступы и прочее. котеров на эти гайдлайны кладет болт https://github.com/igorsimdyanov/php7/blob/master/phpdocs/PHP7/Page.php
посмотри сам и сравни с примером кода
2. у котерова
if(empty($picture)) mail($mail_to, $thm, $msg);
else send_mail($mail_to, $thm, $msg, $picture);
надо
if (empty($picture)) {
mail($mail_to, $thm, $msg);
} else {
send_mail($mail_to, $thm, $msg, $picture);
}
в отличие от js, в пхп для читаемости и очевидности пишут фигурные скобки ВСЕГДА.
3. ставить закрывающий тег в файле, который содержит только php-код (без html), не нужно, т.к. это может привести к появлению лишних пробелов при выполнении и к ошибке во всяких конструкциях include, require, работе с буфером и некоторых других функциях. поэтому его не используют - чтобы не объебаться. котеров на это кладет хуй, т.к. не видел реальный код.
4. по поводу пиздеца в каждой строке, я конечно не буду комментировать каждую строку, но навскидку
> if (!preg_match($pattern, $_POST['mail_to'])) {
exit("Введите адрес в виде s0@zomebodyANUSservern_=PUNCTUMcJA.om");
}
видимо, автор книг по php не слышал про исключения.
> $_POST['mail_subject'] =
>htmlspecialchars(stripslashes($_POST['mail_subject']));
зачем это на разных сточках?
> $_POST['mail_msg'] =
>htmlspecialchars(stripslashes($_POST['mail_msg']));
> $msg = $_POST['mail_msg'];
я может чего-то не понимаю, но почему не сделать $msg = htmlspecialchars ... ?
> if (!$fp) {
> print "Файл $path не может быть прочитан";
> exit();
> }
почему выше написано exit("Введите адрес в виде somebo0d@dyANUSsJjyerverPUNCTUMco(TLm") а тут сначала print, а потом exit без сообщения?
> if(empty($_POST['mail_to'])) exit("Введите адрес получателя");
> if (!empty($_FILES['mail_file']['tmp_name'])) {
> if(!mail($to, $thm, $multipart, $headers))
> {
чем обсуловлено то, что в каждой строчке по-разному написано?
короче и так далее. там много всего. самый главный косяк в файле - это то, что все сделано в стиле "простыня кода", т.е. если функция выполнилась (не вернув нихуя), то идем дальше на header. это полное говно, так в реальности делать нельзя из-за того, что ты такой код будешь отлаживать в 10 раз дольше.
и по другим файлам я не смотрел, просто чувак живет в каком-то параллельном мире, где все пишут код на 486-х и выходят в интернет по модему. мне немного обидно за всю ситуацию, т.к. он позволяет себе учить новичков и берет за это деньги. а новички потом такие "оп, заебись!", и идут работать в битрикс за копейки на всю жизнь, хороня свою карьеру php программиста лол
алсо, чем плоха простыня кода
согласно PSR-1:
>Files SHOULD either declare symbols (classes, functions, constants, etc.) or cause side-effects (e.g. generate output, change .ini settings, etc.) but SHOULD NOT do both.
там же в одном файле и функция, и объявление переменных, и выходы с сообщениями, и редирект.
если мы представим, что нам запрещено использовать ООП (в учебных целях), то должно быть так: в одном месте все функции, которые выполняют нужные вещи (каждая свой маленький кусок) и возвращают какое-то булево значение. в другом у нас что-то типа контроллера - там мы эти функции вызываем и задаем условия
if (!sendMail($params)) {
throw new Exception(...);
} else {
redirect($address);
}
на здоровье
В PHP делал так:
>C:\prоject\public>php -S 127.0.0.1:9001 rоuter.php
>C:\anоther-prоject\public>php -S 127.0.0.1:9002 rоuter.php
и хорошо. А теперь понадобился PDО, но он требует какой-то драйвер:
>PDOException: could not find driver
Поставил Апач, майэскуэль. Настроил. Если все кинуть в htdоcs (она вроде как корень?), лезут одни фатальные ошибки класс куд нот би лоадед и т.п. Бился, бился с путями, так ничего не заработало.
Как сделать чтобы как в PHP: прописал паблик папку, роутер и все работает?
если задаешь такой вопрос, то да, лучше nginx поставь. там намного гибче можно настраивать конфиги, разные версии пхп для разных сайтов, регулярки в путях папок и прочие радости.
Хорошо, попробую его, спасибо!
Апач не устарел. Подключай РНР к апачу и создавай виртуальные хосты для своих сайтов.
на мой взгляд, тебе лучше взять lamp/denwer и не засирать ветку своими сообщениями
ну я посмотрю ты философ дохуя, а мне интересно что выбрать для разработки, потому что индустрия развивается быстрее, чем я успеваю за ней следить
Изучай перманентно все что в тренде. Либо работай со студией какой-нибудь, которая пилит сайты на своем движке. Ларавел или зенд в штатах в почете. Слим/берд/вордпресс для одностраничников. Никоо всерьез на этой залупе не работает. Будешь до конца дней своих хеллоу ворлды писать на этиц фреймворках.
мне для своих проектов надо, а не на дядю. расклад такой, что для крупного проекта я бы выбрал Ларавел, даже несмотря на то, что он тормозной, но я такие проекты не разрабатываю. чаще это одностраничники, где даже не всегда авторизация есть, но нужны всякие плюшки типа мультиязычности, поэтому совсем уже деревянные фрейморки не подходят. вот и выбираю.
>>14723
какой нахуй денвер? он с 5.3 не обновляется. 5.3 вышел в 2011 году, кажется. на мой взгляд, не надо давать плохие советы
> Одностраничники
> без авторизации
> не на дядю
> мультиязычность, тормоза и т.п.
Ахахаххахахаха спешите видеть кретина итт. Набигаем ололо гнобим и гоним отсюда сраными тряпками.
Дебил или изучай езык погромирования хтмл5, джейси и цэсэс в придачу. Клоун ебаный. Сажи тебе уебку.
этот петушок порвался, выносите его из треда
Я же не знаю какую именно версию пхп учит вопрошающий. Может ему и денвера за глаза хватит. Ну и потом, я же приоритеты расставил на первом месте ламп, чо доебался то до меня?
чтобы придать огласке уебищность денвера, конечно же.
алсо, у денвера есть современный аналог для винды - open server. там пхп вплоть до 7.2 и на выбор нжинкс с апачем. кому лень ставить по-взрослому на линуксе, можно использовать его.
Убедил, антуан
Ну вот смотри. На дваче, если выложить картинку, то текст будет с боку. Без редактирования картинка просто находится в строке и распидорашивает её. Мне нужно чтоб в одном случае картинка была справа как на вики и в другом случае слева как на дваче.
Хитро усмехнуться, погуглить чем их реализация кого-то не устраивает и сделать лучше.
Ладно когда есть один ассоциативный, а когда он многомерный, ещё и вместо индексов имена? Как рогом упёрся и нифига понять не могу.
Какие-то => появляются, а как они работают я понять не могу. Я ведь по обе стороны => вообще любую переменную пишу. Прямо голова взрывается.
что значит "как распарсивать"? в чем проблема-то?
напиши конкретную задачу, что тебе надо с ним сделать.
На самом деле это просто переменные с индексом-переменной.
https://ideone.com/qdHhd0
Ну вот я накидал пример.
И если обработать какой-нибудь одномерный массив просто. Но например из многомерного массива $cars вывести просто имена фирм, например "Nissan" оказалось довольно сложно. Думал над этим часа два наверное. А когда в итоге написал, то понял что скорее методом тыка получилось. И вообще не понимаю как это работает.
Например почему $key распарсивается в итоге на $params и $value? Как он узнаёт что там правильные данные? Какая-то каша в голове от этого. А если например там виесто одного из параметров - массив вложенный?
Потому-что Wordpress выглядит няшно и имеет адекватный интерфейс.
Так появилась Mongo в своё время.
Что-то каша какая-то. У тебя ошибки сыпятся
>лезут одни фатальные ошибки класс куд нот би лоадед и т.п. Бился, бился с путями, так ничего не заработало.
А ты уже в PDO полез. Для начала настрой и выведи хотя-бы helloworld. А лучше просто поставь OpenServer. А уже потом к базе подрубайся.
>там виесто одного из параметров - массив вложенный
А читал ли ты документацию, дружок?
http://php.net/manual/ru/language.types.array.php
>key может быть либо типа integer, либо типа string. value может быть любого типа.
>Массивы (тип array) и объекты (тип object) не могут использоваться в качестве ключей. При подобном использовании будет генерироваться предупреждение: Недопустимый тип смещения (Illegal offset type).
На твоем примере https://ideone.com/7RmzCn
во-первых, посмотри этот пример: https://secure.php.net/manual/ru/function.array-search.php#116635
он показывает, как использовать функцию array_column() в многомерном массиве. ты можешь ее использовать в своей задаче.
также у тебя путаница с названием переменных внутри foreach. там всегда пишут конструкцию $array as $key => $value; в каждом элементе массива $array есть ключ и значение.
>key может быть либо типа integer, либо типа string. value может быть любого типа.
https://secure.php.net/manual/ru/language.types.array.php
то есть, может быть строка, массив, объект или ресурс в качестве значения для ключа.
как он узнает что там правильные значения? ну это задача интерпретатора, можешь посмотреть сишные исходники php и сам выяснить. я не смотрел, как именно это реализовано.
о, братюнь, опередил меня с цитаткой из мануала
Я ж говорю, настроил, ит воркс. Даже PHP подрубил, если смотреть из локалхоста, работает. Но если раньше у меня на каждый урок своя папка была и один вендор на все проект на уровень выше, композером хуяк хуяк зависимости, в цмд одной строчкой запустил урок — холосо! а тут одна папка эштидокс, как мне блджажд разграничить уроки, если он не видит больше мой вендор?
Придумал алгоритм. Беру URL, делаю запрос, получаю данные. Далее, беру только что использованный URL и получаю из него MD5 хэш, использую его в качестве ключа, под которым положу только что полученные данные в memcached. При следующем запросе получаю MD5 хэш из ссылки и спрашиваю memcached, лежит ли в нём что-то под этим ключом. Если да, беру данные из memcached и возвращаю на клиент.
Норм алгоритм? Почему-то меня преследует мысль,
что можно сделать намного проще, но я тупой(
Спиздил и запатентовал твою идею. Единственный вопрос, может ли переполниться memcached? Не, серьезно, идея годная, нужно попробовать.
>может ли переполниться memcached?
Ну я не планирую класть что-то в memcached навсегда. У API есть эндпоинт, позволяющий по IP-адресу клиента определить его город, страну и координаты города. Эти данные я могу положить к кэш на месяц, например. Есть эндпоинт, позволяющий получить среднюю цену на билет из %город_нейм% в %город_нейм% на текущий месяц. Эти данные я планирую класть в кэш на 24 часа. Пока пользователь будет лазить по сайту и периодически запрашивать эти данные, ему они будут отдаваться из кэша. Если цена спустя сутки изменится, то зайдя на сайт повторно клиент уже увидит новые данные, которые сразу же будут опять закэшированы на 24 часа. Щас напишу, кароч.
Заебись, работает.
... В итоге и тебя 9000 ключей, по которым 9000гигов закешированных данных лежит?
Примерно на 78.675% реально. Задавай пожалуйста более конкретные вопросы.
Актуальность некоторых данных не критична. К тому же, я более чем уверен, что API тоже не проводит ежеминутную проверку актуальности данных и тоже отдаёт мне их из кэша. Свой же кэш я пишу только для того, чтобы ускорить загрузку некоторых страниц и как можно скорее отдать пользователю контент. Это важно. Например, есть отрывочек кода, где мне нужно получить данные на год вперёд по каждому месяцу, но API разрешает мне за раз взять данные только за один месяц. на таких страницах колесо загрузки крутится по 2-3 секунды Приходится в цикле отправлять 12 запросов. Чтобы избежать этой бомбёжки API и не получить пизды от моих партнёров, предоставивших доступ к API я и пишу кэш.
>>14866
Ну, сомневаюсь, что там прям так дохуя это всё будет весить. Буду следить за размером кэша. Вдруг что - у моего хостера дополнительный SSD-диск на 50GB стоит 7$.
>Буду следить за размером кэша. Вдруг что - у моего хостера дополнительный SSD-диск на 50GB стоит 7$.
А, я еблан. Memcached же в оперативку всё складывает.
Вот и я про что.
function isArrayEmpty(array $data): bool
{
foreach ($data as $value) {
if (is_null($value)) {
return false;
}
}
return true;
}
Злой пиздец. Была бы возможность, я бы прутом вам по рукам бил за говнокод ведосипедостроительство. Есть же дока, изучайте. Нет блядь, my way... и пусть весь мир подождёт. Поверьте, ваш максимум в программировании на рнр — использование готового кода, функций, который был написан, когда вы представляли из себя семенную субстанцию в тестикулах ваших прородителей.
Вам надо просто взять готовую функцию из стандартной либы рнр и передать ей свои значения.
Всё.
На этом все ваше программирование и закончилось.
От недели до бесконечности. Зависит от того, как ты будешь подходить к процессу. Что именно ты хочешь писать.
Сам язык прост. Сложнее вникать в фреймворки, шаблонизаторы и ООП. Но это практически идентичные базовые вещи для любого ЯП.
Это не на меня ори, я не имею к челу выше отношения, я лишь зашёл в тред помочь, а тут злые
Ты доску перепутал, козлик.
Пых хорош тем, что он многогранен. Не так как низкоуровневые ЯПы, но, например, я себе несколько скриптов написал а ля телефонная книна и напоминалка и запускаю все в терминале. Можно было бы на Си писать, но заняло гораздо больше времени.
А тут тебе и работа с субд, и никакой компиляции и синтаксис как у си... короче плюсов хватает.
Имхо, не самый плохой вариант для вкатывания в программирование.
Довольно много приходится писать и на js, я стараюсь не быть идиотом и изучать инструмент хорошо. С недавних пор вообще загорелся мечтой укатиться в светлые дали js разработки, а конкретно - в Ангуляр.
И вот пришел спросить у вас совета, если найдутся люди шарящие. Я выполнил на сайте ангуляра туториал (tour of heroes), что бы вы дальше мне посоветовали, какие шаги предпринять?
во-первых, отложи свое высокомерие.
во-вторых, почитай, что такое lazy loading. если массив состоит из миллиона элементов, а надо отловить только первое не-null значение, то моя функция завершится при нем же и не будет перебирать остальные элементы. а данные тобой функции не остановятся там, где нужно - ресурсоемко получается. в итоге ты либо невнимательно прочитал задачу, либо не знаешь основ.
ты судя по манере речи и ценности твоих "советов" никакой не опытный, а банально петушок, рисующийся перед анонами. я опытных знаю, они отвечают нормально и по существу, а не "дают удочки". при реальном общении со мной ты бы свою удочку (или прут, что там у тебя в фантазиях) засунул себе в жопу, поверь
да, тема в том (наверняка сам знаешь, если писал на шарпе, но все же), что в программировании тебе платят не за то, что ты знаешь язык, а за то, что ты знаешь, что на нем написано (фреймворки, реальные проекты).
то есть по аналогии с языками, программист - это не чувак, который знает итальянский, а который знает итальянскую прозу и пишет ее сам.
пхп простой, но после других языков немного ломающий мозг. если заебись знаешь шарп и писал реальные проекты, знаешь все смежное говно (sql, git и прочее), то месяц на сам язык (плотненько) и еще месяц на фреймворк, на котором хочешь работать.
Во-первых, не указывай как с вами себя вести
Во-вторых, про lazy loading мне можешь не рассказывать.
В-третьих, если у тебя массив ищ миллиона значений, то ты удостоен медали — говнокодер -2018. Твое место в шапке треда с подписью:
не будь как он.
>>15149
Давай фейкопочту, я тебе предоставлю ирл шанс.
>Доходишь такой до изучения массивов.
>Развитие тебя как программиста останавливается.
>Надо передать данные - В МАССИВ
>Надо обработать - В МАССИВ
>Надо создать ряд элементов - В МАССИВ
>Надо вытереть задницу - МАССИВ
>Надо выйти из-за компа и пойти в магазин покушать купить - МАССИВ
У меня от таких программистов бомбит почему-то. Ещё со времён когда 5 лет назад Java изучал. Там это вообще поголовная болезнь терминальной стадии. Доходит до того, что они не понимают как задачу решать не через массив.
Что то какой-то бред. Там методы обработки разные. Смотри код.
Читайте пожалуйста анализ алгоритмов в худшем случае оно закончится за N операций где N и есть кол-во элементов массива и другого решения этой задачи нет.
Но другой вопрос что ты миллионы данных обрабатываешь массивами, аноны беспокоятся, неужели нельзя использовать базы?
Джуны это не про фреймворки, джуны это про отсутсвие опыта, первое что надо выкинуть из головы джуну это привязываение к фреймворкам, будь готов за короткое время выучить любую хуйню и разобраться в чем угодно
С апачом разбирайся,ровно столько чтобы поднять локальное окружение, а вообще все суровые сайты используют нжынкс в него можешь углубиться по самые гланды, лишним точно не будет.
Кому кроме васянов из колхозов в 2018 приходится nginx настраивать? Обычно всё навтраивает за тебя админ или хостер.
ну когда у тебя наступит такой момент когда тебе например какое то особенное кэширование надо на энжинксе настроить или какой то редирект интересный сделать так станет ясно кому оно надо, а так хорошо что тебе его настраивать не приходится, но понимать что там к чему крайне полезно.
> особенное кэширование надо на энжинксе настроить
Делается либо через ТП провайдера, либо через предоставленную веб морду.
>или какой то редирект интересный сделать
Что значит реддирект интересный сделать? Берёшь и делаешь. Можно даже не ковырять Nginx а тупо в PHP прописать или в JS.
>понимать что там к чему крайне полезно.
Ага, мне это уже лет 10 говорят. Надо ли говорить что за 10 лет я настраивал апач 1 раз, когда начинал PHP учить. Больше никогда к нему не прикасался.
Решил хотя бы попытаться вкатиться к вам. И черт возьми "http://archive-ipq-co.narod.ru/" это веселая хуйня, анонасы которые это делали вы ахуенные. Хоть и амублядки
>>15054
>У меня от валидатора приходит ассоциативный массив с ошибками. Нужно чекнуть если он пустой, то тогда добавляем данные в БД.
Вот эта проблема. Валидатор должен возвращать массив с ошибками, а не массив со всеми ключами. Тогда и не нужно обходить весь этот массив и проверять null'-ы, достаточно будет проверки:
$errors = $validator->validate($entity);
if (count($errors)) {
// вернуть пользователю ошибки
} else {
// сохранить сущность
}
Так например сделано в Symfony:
- http://symfony.com/doc/current/validation.html#using-the-validator-service
>>15024
array_map это о том, как преобразовать один список в другой, применяя к каждому из элементов функцию-преобразователь. Количество элементов на входе будет равно количеству элементов на выходе: https://ru.wikipedia.org/wiki/Map
>>15198
Тут не чатик, к чему этот пост?
Float и есть руки. Я не понял в чем проблема, что ты хочешь? Если хочешь сделать так чтобы в одном случае картинка была справа, в другом была слева просто создай 2 класса.
Бля а ты веселый паря как я погляжу.
чтобы выдавать медали, нужен авторитет. у тебя его нет. я не знаю сколько элементов в массиве, этого нет в условиях задачи, может 10, а может 100000. а ты начинаешь оправдываться "неправильни массив кококо"
>>15170
> еще со времен когда 50 лет назад был гендиром в майкрософте
иди выебывайся в перезвоним-тред, пожалуйста
Я всегда думал что медали для долбоебов.
ты наверное когда у тебя сайт ломается, пишешь хостеру "кококо, товарищ хостер, у меня НЕ РАБОТАЕТ, почините срочно кококо!"
>а вообще все суровые сайты используют нжынкс
Nginx в паре с апачем чаще всего работает как прокси, отдает статику сам, а другие запросы передает апачу.
Так что и то, и другое надо уметь настраивать.
>How to center the text of a block element horizontally (more precisely: in the inline direction) even if (part of) the block is next to a float?
да, лол. видимо, не все программисты используют каникулы для написания своих опесорс-проектов
Бля проиграл.
Спасибо, посмеялся над собой. Пойду таки сначала выучу всё, а потом буду пытаться закрепить.
это ты скорее говоришь про проекты, запущенные несколько лет назад. новые проекты чаще всего используют просто нжинкс из-за того, что php-fmp работает быстрее, чем php как служба апача. ну и из-за удобства.
на шаред-хостингах конечно ситуация другая (там ценна возможность использовать .htaccess), но мы же не про них говорим?
если ты агитируешь за связку апач+нжинкс для новых проектов, то подскажи плюсы апача, будет интересно
Ну я бы советовал параллельно все делать, быстрее прогресс пойдет.
Мне и надо локальное, но походу php -S это мой предел. 2 дня читал, ничего не откладывается в голове, боюсь браться за майэскуэл (что, теперь на каждый чих документации сотни страниц? А я думал PHPnet это самый сложный шаг).
да, но это анон написал уже после того, как задал изначальный вопрос. ты рассуди нас, корректно ли использовать foreach чтобы ускорить обработку больших массивов или нет?
вообще не угодал.
31, последние два года работаю в достаточно большой конторе с саас-продуктом. я понимаю, что ты клепаешь лендосы (ну ладно, не только лендосы), поэтому у тебя вопросы решаются хостингом, но серьезные проекты всегда работают на своих vds и там полезно представлять работу сервера, даже если ты не админ.
я не против фриланса или чем ты там занимаешься, но против позиции, что знание нжинкса для колхозников. как ты возможно знаешь, в крупных командах есть свои дев-сервера и там надо самому достаточно хорошо разбираться в устройстве среды, чтобы работать с очередями, делать свои воркеры для них и прочее говно. но бою тебя к настройкам сервера конечно никто не допустит, а на деве нужно все знать и часто делать самому.
плюс у меня на локальной машине всегда стоит нжинкс с последним пхп и днс-сервером, чтобы всегда иметь возможность разворачивать свои проекты сначала у себя. а у тебя, полагаю, нет.
Я дублирую. Это же по сути разные вещи - аннотации смотрит доктрина, а тайп-хинт аргуметов и ретурна сам интерпретатор
Последний проект принёс мне контракт на 10 000$ Где был отдельный админ на Nginx и закуп 2 серверных стоек под него. Если ты сам настраиваешь что-то внутри сервака, то у тебя уровень фронтенда в 31 год.
У меня есть OpenServer и мне этого достаточно. Я лучше новый гайд почитаю по PHP или разберу что нового добавили, чем буду ковыряться в Nginx. Ибо на практике это в итоге не нужно. И тот факт что ты даже примеры привёл которые можно решить вообще не касаясь Nginx только подтверждает это.
наверное у тебя больше развит талант бизнесмена (или пиздобола), если ты думаешь, что серваки настраивают фронтенды.
опен сервер - хорошая штука. когда сидел на винде, тоже им пользовался. но практика такова, что ты почитаешь новый мануал по 7.2, а потом выкатишь сайт на хостинг, где в лучшем случае 7.0
Да, я считаю что администрирование сервака - это значительно проще чем программирование. В конце концов по тому-же Nxinx есть куча документации. А как сделать ту или иную фичу на бэкэнде с 4 миллиардами записей в БД - хрен найдёшь.
алсо, работа одмина в больших конторах - это в основном давать доступы к впн и прокладывать провода. настройками веб-сервера, бд и производительности занимаются чуваки из отдела эксплуатации, где обычно сидят самые крутые и прошаренные программисты, знающие нутро проекта и среды.
Ты слишком высокого мнения о них. Раз в пол года шевельнут мизинцем и то радость.
Спасибо что пояснил этому колхознику, мне было лень печатать
Прошаренные девопсы
будешь браться за базы советую прорешать любой задачник по SQL запросам, так будет проще, вообще не читай ничего, а занимайся сразу практическими задачами параллельно гугля вопросы которые у тебя появятся.
Я понимаю, что так-то весь материал можно в инете прочитать, но есть ли что-то, что в наш цифровой век, следует сохранять в аналоговой форме?
по джаве дохуя хороших книг, по php нихуя. мой совет - читай по джаве, а потом переноси. по основам читай мануал. у других языков обсосные мануалы, а у php норм.
Анонсы, это нормально, что у меня не получаются задачки про регулярки? я тупой? все, что было до них легко решалось, а тут на тебе, ничего не понятно, мда. Может стоит почитать что-то, кроме того гайда для чайников?
вкатился полторы недели назад, до этого к погромированию вообще отношения не имел
В новом году понадобилось завести магазин так, чтобы данные о товарах грузились с 1с. Говно вопрос сказал я себе, задача казалось вполне простой:
Выгрузить - > Передать по соап -> загрузить
Такую задачу я много раз решал между 1с системами и тут мне казалось, что проблем не будет.
За основу я наугад выбрал opencart, оказалось что он на пхп, ну да и хуй с ним. Развернуть на локалке и поднять сервак оказалось очень простым. В целом никаких проблем.
Вопросы начались, когда стал решать задачу загрузки со стороны сайта. Решил по старой схеме передавать с помощью типизированного хмл wsdl схема. Включил соап сервер и оказалось, что всдл надо руками формировать, никаких механизмов из коробки по формированию исходника я не нашел. Оказывается существуют множество всяких библиотек типа php2wsdl, которые делают это декларативно. В общем полдня я ебался просто с установкой этого модуля, классы не грузились, автозагрузка хуй его знает как работает, поставил композер, разобрался с автолодом. Потом стал формировать всдл, еще полдня разбирался как работать с этими классами и методами, каждая ошибка вгоняла в гугол. В 1с классического ооп нет, поэтому для меня вся эта бодяга с классами немного напрягала. В общем на следующий день я посмотрел на сформированный всдл и понял, что к нему надо еще писать обработчик. Тут я подумал и решил что нахуй он не нужен этот всдл.
Решил использовать json, тем более один раз с ним уже работал. Удалив всё что наработал начал заного и внезапно пришла в голову идея, что наверно у опенкарта должно быть апи, так и оказалось, но нужных методов там не было. Но при разборе структуры апи внезапно столкнулся с mvc и охуел. Ничего подобного я раньше не видел и это меня сильно удивило. Сегодня написал свой первый контроллер с моделью и всё-таки удалось выгрузить данные, но авторизацию пока не победил. Завтра буду ебаться с токенами и прочей хуйней.
Мир пхп такой забавный, кек.
В новом году понадобилось завести магазин так, чтобы данные о товарах грузились с 1с. Говно вопрос сказал я себе, задача казалось вполне простой:
Выгрузить - > Передать по соап -> загрузить
Такую задачу я много раз решал между 1с системами и тут мне казалось, что проблем не будет.
За основу я наугад выбрал opencart, оказалось что он на пхп, ну да и хуй с ним. Развернуть на локалке и поднять сервак оказалось очень простым. В целом никаких проблем.
Вопросы начались, когда стал решать задачу загрузки со стороны сайта. Решил по старой схеме передавать с помощью типизированного хмл wsdl схема. Включил соап сервер и оказалось, что всдл надо руками формировать, никаких механизмов из коробки по формированию исходника я не нашел. Оказывается существуют множество всяких библиотек типа php2wsdl, которые делают это декларативно. В общем полдня я ебался просто с установкой этого модуля, классы не грузились, автозагрузка хуй его знает как работает, поставил композер, разобрался с автолодом. Потом стал формировать всдл, еще полдня разбирался как работать с этими классами и методами, каждая ошибка вгоняла в гугол. В 1с классического ооп нет, поэтому для меня вся эта бодяга с классами немного напрягала. В общем на следующий день я посмотрел на сформированный всдл и понял, что к нему надо еще писать обработчик. Тут я подумал и решил что нахуй он не нужен этот всдл.
Решил использовать json, тем более один раз с ним уже работал. Удалив всё что наработал начал заного и внезапно пришла в голову идея, что наверно у опенкарта должно быть апи, так и оказалось, но нужных методов там не было. Но при разборе структуры апи внезапно столкнулся с mvc и охуел. Ничего подобного я раньше не видел и это меня сильно удивило. Сегодня написал свой первый контроллер с моделью и всё-таки удалось выгрузить данные, но авторизацию пока не победил. Завтра буду ебаться с токенами и прочей хуйней.
Мир пхп такой забавный, кек.
брось регулярки если они тебе прям не нужны и занимайся программированием, регулярки заебная хуйня
почему ты битрикс то не взял
Ну он не сколько устарел сколько неудобен. Из блока нужно делать плавающую строку и накладывать кучу свойств на него чтобы выровнять. Сейчас все само делается парой строчек и стандартными средствами, тут уже вопрос об производительности.
И опять же, Float - Не нужен, бросайте его использовать, надеюсь его удалят.
Глядя на современные веб приложения я все больше замечаю, что php больше используется как веб-сервис для взаемодействия с бд, а все остальное пишется на каком-то js фреймворке.
Я сейчас на работе пишу все на php и по необходимости свистелки-перделки дописываю на jquery и мне кажется, что это старо и не правильно.
Что вы думаете по этому поводу. Видимо придется подучивать еще какой-то js фреймворк?
Я вообще вместо пары строк предлагаю 1 тег. Чем он неудобен то? Написал и забыл.
Что не так-то, аргументировал бы хоть.
Сама задача простая:
Пользователь вводит названия продуктов.
Потом эти продукты проходят проверку на наличие.
Первый вопрос:
Как задать, чтобы через HTML-форму входил целый массив, а не строка?
покажи на примере, а то не понятно
W5.1. Школьник решил купить айфон и для этой цели взял кредит. Сумма кредита — 40000 р., банк в начале каждого месяца (включая первый) начисляет 3% от остатка долга за пользование кредитом и 1000 р. комиссии (да, а ты думал, обойдешься процентами?). После этого, в конце каждого месяца, наш герой идет в банк и пытается выплатить долг, но он не может заплатить более 5000 р за раз (сэкономленных на школьных завтраках). Вопрос, когда он избавится от долга? Во сколько школьнику обошелся айфон?
код примера на http://codepad.org/nm9jPcpd
https://ideone.com/MtOprg
у меня вот так получилось. полагаю, что надо еще сделать буквы заглавными, но не могу придумать как. если кто подскажет, буду рад.
только не надо подсказывать в стиле чсв-анона "сделай preg_replace_callback, вошь, я даю вам удочку" лол. конкретную реализацию напишите
Не то чтобы "не нравится". Просто решил проработать несколько вариантов.
Так значит, через форму можно вводить только что-то простое?
Можешь использовать множественный селект, но для этого нужно будет еще ручками дописать функционал (можешь погуглить 'multiple select') либо заюзать какую-то библиотеку, например, select2.
в смысле ссылкой? это как просить ссылку "как водить солярис". мол мне все вождение похую, только солярис бы научиться водить. если ты оба языка знаешь, то проблема только в жопочасах. по рест апи инфы миллион.
так, чтобы буквы становились заглавными я делал в своем варианте, хотя оно почему-то не работало, хз почему, лол
Сложно https://habrahabr.ru/post/303572/
Просто -- API
Ещё проще -- вызывай C-приложение прямо из пыхи, например http://php.net/manual/en/function.shell-exec.php
Разобрался, просто не добавлял после if скобочку {. Но все равно, в задание оно есть, а у меня нету. Значит что-то не так
Я думаю ровно так же, но в задание exit стоит. Ну вот и подумал что нужно так же.
1. Зачем оборачивать переменные в строке в {}? В данном случае все отлично работает и без них. Тем более в первом уроке их нет и нигде не объясняется, зачем они нужны.
2. Зачем после exit ставить скобки? Краткость - сестра таланта же. Сам ставлю только со строкой внутри при дебаге и всегда использую die.
3. Бесполезные \n вместо <br>, все, понял, ideone.
Вообще уроки классные, спасибо тебе. Сам я учился в универе на программиста 5 лет, но это не особо меня вставляло, особенно на последних курсах. Полтора года проработал админом-эникейщиком, сейчас пытаюсь вкатиться в вебдев. Хотел узнать, насколько это занятие сложное для нервной системы и изматывающее для всего организма? По состоянию здоровья не могу напряженно работать, тем более думать, больше часа подряд, дальше клонит в сон и я уже не способен нормально работать, пока не отдохну пару минут. Так вот, реально ли с такой проблемой кодить фуллтайм? В начале весны сваливаю с работы, думаю за 2 месяца подтянуть знания и устроиться стажером за еду, в принципе есть куда. Сидеть за компом с утра до вечера не проблема, проблема при этом постоянно работать. Как там в офисах вообще, есть возможность встать, размяться, подремать 10 минут? Спасибо заранее, добра всем и ОПу особенно.
1. чтобы выводить более сложные конструкции типа $foo->getName(), $foo[0] и прочие. чтобы интерпретатор понимал, что именно ему выводить
2. die это синоним для exit. в скобках пишется ообщение, которое надо вывести при выполнении этой конструкции
3. сюрприз, пхп может работать не только в хтмл-страничках, но и в cli, и для вывода данных в файл, и в жсоны всякие, и т.д. странно, что после 5 лет инста ты об этом позабыл
алсо, это что за такое состояние здоровья, которое мешает тебе концентрироваться на задаче? ты же как-то написал этот пост, чем это принципиально отличается от написания кода? ничем
работа программистом - это без шуток САМОЕ не измытавающее занятие из всех работ, которые только можно себе представить. ты блядь сидишь на жопе почти все время. только сторож наверное меньше устает физически. поэтому я 3 раза в неделю в секцию на бокс хожу, бью ебала всем.
встать и размяться - ну где-то может стоят за спиной и палкой бьют тех, кто пытается разминаться, но думаю можно найти место, где понимают твои потребности. а так смысла спрашивать "ну как там в офисе?" нет, надо самому пойти и попробовать. только 2 месяца на подготовку к нормальной работе - это думаю, маловато, вот полгода и какие-то вменяемые курсы уже более реально
Почему у меня не работает эта регулярка?
https://regex101.com/r/MLy2Gd/1
>Почему у меня не работает эта регулярка?
Судя по твоему решению, ты не очень понимаешь как они работают. Может повторить уроки ОПа?
<?php
error_reporting(-1);
mb_internal_encoding('utf-8');
$reg = '/[^a-z\s]/iu';
$str = "Some cool string!!! With a lot, of shit in it #$(24324";
echo $str . PHP_EOL;
$result = preg_replace($reg, '', $str);
echo $result . PHP_EOL;
Не, мне хотелось удалить всё, кроме букв и дефисов из вводимого пользователем.
Но я перечитал урок опа и понял, что можно сразу запилить массив из вводимого юзером, через функцию preg_split
Спасибо, это были вопросы не сколько по языку вообще (я как бы понимаю немного), сколько по конкретной реализации и простоте понимания для новичков.
1. Но в конкретной задаче же выводятся только переменные. И, повторюсь, назначение фигурных скобок еще не было описано в учебнике.
2. Об этом я и писал. Если выводится сообщение - скобки нужны. Если не выводится, можно обойтись и без них, насколько я помню, это даже в стандарте где-то было.
3. Опять же, для новичка, запускающего пример на локалхосте, не очевидно, почему переносы строк не работают, хотя он их прописал. Ну это ладно, урок рассчитан на онлайн-интерпретатор.
Если кратко, у меня хронический гайморит - влияет на память, скорость мышления и обучения. Например, сейчас сталкиваюсь с тем, что очень тяжело запомнить названия функций и порядок аргументов, благо редактор подсказывает. Чтобы запомнить пример, мне его нужно как минимум один раз переделать с нуля, не смотря в оригинал.
Насчет изматывания - спасибо, что обнадежил. Хотя лично я устаю даже от продолжительного серфинга в инете, но уверен, что за пару месяцев работы привыкну.
Кое-какая база у меня уже есть, так что 2 месяцев на освежение и систематизацию знаний, думаю, хватит. Сейчас, кстати, прохожу курс по Yii 2 от webformyself, но проблема в том, что за день успеваю пройти не больше одного урока (1-2 часа видео, с конспектированием и выполнением заданий уходит примерно в 2 раза больше). Параллельно собираюсь пройти учебник ОПа, он намного быстрее, проще и не содержит воды.
Спасибо за подробный ответ. Успехов тебе в работе и саморазвитии.
Для удаленки мне пока не хватает знаний и опыта, учитывая, что в верстке и фронтенде я почти ноль. Еще имеются жесткие проблемы с самодисциплиной, из-за которых у меня сорвалось уже два проекта. Но спасибо за совет, если не получится в офисе, попробую фриланс снова.
Сейчас попиливаю первую задачку от ОПа про список студентов, пытаюсь сделать валидацию. У меня несколько вопросов. В хтмле в инпут теги можно добавить атрибут required, рисует красивую плашечку, не дает форме отправиться. Но это с клиентской стороны. Я правильно понимаю, что если я отправлю форму с другого места/сайта на свой sumbit адрес, то вся эта клиентская валидация с жс регэкспами до пизды? А если сделать защиту, как в той самой статье от ОПа про XSRF уязвимость, невидимую форму с токеном и куками, в таком случае я могу обойтись только клиентской валидацией ну или хотя бы required и быть уверенным что мой $_POST точно будет не пустым?
Еще про ООП, нужно ли создавать объекты на любой вздох, не считается ли плохим использовать статические методы? Вот роутер у меня например, что я напишу Router::run, что в конструкторе вызову метод, какая разница?
Для выполнения задачи так же требуется "типа" регистрация на куках, после успешного добавления студента в бд в куки что-то записывается, и после этого вместо кнопки добавления студента будет кнопка изменения. Я думал посл добавления записи брать последний айди из бд, как-то его там хешировать например и записывать в куки, а потом проверять, я даже хз будет ли это работать. Но если два чувака примерно в одно время отправят правильную форму, инфа добавится в бд, другой метод возьмет последний айди и выдаст не последнему чуваку из-за каких-то задержек? сложна
Можете посмотреть регулярку на https://regex101.com/r/EzsdMh/1
Вроде все работает, но может написано коряво... Вот задание
Grammar Nazi. Напиши скрипт, проверяющий текст на наличие злостных ошибок:
нет пробела после запятой, точки с запятой, восклицательного знака, вопросительного знака, двоеточия
«жи» или «ши» написано с буквой ы
в тексте есть слово «координально» или «сдесь», «зделал», «зделаю», «зделан»
в тексте есть слова «а» или «но» без запятой перед ними.
Нет. Лучше почитывать книжку и пописывать регулярки 2-3 раза в неделю по пару часов (spaced repetition вот это все). Тормозить основной процесс смысла нет.
> только клиентской валидацией ну или хотя бы required и быть уверенным что мой $_POST точно будет не пустым?
Открываю я значит chrome devtools, нахожу твою форму, стираю с инпутов required и кликаю сабмит.
не можешь, на стороне сервера всегда проверяй, не надейся на клиента.
>>16015
https://regex101.com/ , может здесь поиграться с регулярками, очень удобно.
Я некоторые задачи ОПа неосилил и просто пропустил либо глянул готовое решение, и их не мало, но все же уже работаю пбольше года. Хотя как был тупым, так и остался, а многое просто пришло и придет с опытом.
>>15623
бамп вопросу
Книга наверняка окажется тебе полезной, только помни про то, что есть разные диалекты регулярных выражений, и в PHP используется PCRE.
>>16009
> [:|.|?|!|,]
Символ | тут обозначает сам себя, то есть вертикальную черту. В квадратных скобках | не имеет специального значения.
> [ж|ш]
То же самое, надо писать просто [жш] так как квадратные скобки обозначают "один любой из указанных символов"
> зделал|зделаю|зделан
Нет "зделаем"
> [\s]
Можно просто написать \s
В выражении, проверяющем отсутствие запятой перед "а", у тебя заложено, что там должен быть ровно 1 пробел, между запятой и "а", но лучше предусмотреть любое их число.
После но/а, кроме пробела может идти запятая или двоеточие. Тут лучше было использовать \b (граница слова), а не \s.
Клиентская валидация только для удобства пользователя - чтобы он не тратил время на отправку некорректных данных. Проверять на сервере надо все равно. Естественно, любой школьник может эту валидацию легко отключить, подправив HTML-код страницы в инспекторе или сделав свою форму.
> А если сделать защиту, как в той самой статье от ОПа про XSRF уязвимость, невидимую форму с токеном и куками, в таком случае я могу обойтись только клиентской валидацией ну или хотя бы required и быть уверенным что мой $_POST точно будет не пустым?
Нет, так как пользователь может отключить валидацию в браузере, либо отправлять HTTP POST запрос не из браузера, а программой вроде curl, которая позволяет указывать любые данные. Если ты читал урок про HTTP ( https://github.com/codedokode/pasta/blob/master/network/http.md ), то знаешь, что браузер при отправке формы просто соединяется с сервером и отправляет определенный кусок текста. Никто не запрещает сделать то же самое без браузера. Или модифицировать браузер.
То есть защита токеном (либо по Referer/Origin) это защита именно от CSRF и ничего больше.
> не считается ли плохим использовать статические методы?
Зависит от ситуации. Статические методы обычно используются там, где нет состояния (ничего не сохраняется в поля). Вроде функции перевода миль в километры. В случае с роутером, я не очень понимаю, какая от этого выгода. У него наверняка есть какое-то состояние.
Вообще, так абстрактно сложно объяснить, но основная проблема статических методов как раз то, что они меняют глобальное состояние. То есть ты в одном месте кода вызвал метод, он что-то записал в статические поля, и это влияет на весь остальной код (так как статическое поле это по сути глобальная переменная, оно существует в единственном экземпляре). А когда у тебя объекты, ты можешь создать его, что-то с ним сделать и все состояние остается в этом обьекте, и никак не влияет на другой код.
За счет этого разбирать код может быть проще - в случае статических методов, их можно вызвать откуда угодно, а обычные методы - только оттуда, куда передан данный объект.
Также, когда у тебя обычные нестатические объекты, ты можешь создать несколько объектов с разными настройками. А в случае статических полей настройки - они глобальные.
В общем, обычные объекты этим удобнее, они позволяют писать более надежный код, так как они не влияют на глобальное состояние, а хранят состояние внутри. И ты контролируешь, кому ты даешь объект, кто может с ним что-то делать.
Еще немного по этой теме можно поискать тут
- https://github.com/codedokode/pasta/blob/master/arch/di.md
- https://habrahabr.ru/post/169301/
- https://www.google.ru/search?q=чем+плохи+статические+методы&newwindow=1&dcr=0&gbv=1&sei=vX1PWum9BYqXsgHLgZuABg
- https://www.google.ru/search?q=what+wrong+with+static+methods&newwindow=1&dcr=0&gbv=1&sei=wn1PWuS2NMmgsgGtvZuABg (англ)
Главное понимать, что мы избегаем эти методы не потому, что верим в какую-то догму, а их прагматичных соображений, потому что хотим более качественный код, с которым проще работать, удобнее тестировать. Потому советую почитать статьи из гугла.
> Я думал посл добавления записи брать последний айди из бд, как-то его там хешировать например и записывать в куки, а потом проверять, я даже хз будет ли это работать.
Есть lastInsertId который работает как нужно
Если класть в куки id или хеш от него, то ты решаешь задачу идентификации (определения, кто перед тобой), но не решаешь задачу аутентификации (подтверждения, что пользователь тот, за кого себя выдает). Что мешает хакеру записать себе куку с любым id? Для аутентификации нужно использовать какой-то секрет, который хакер не знает. Например:
- хеш пароля (но у нас нет паролей)
- случайно сгенерированный токен
- id, подписанный секретным паролем приложения (хеш от id + секретный пароль)
- id сессии
Клиентская валидация только для удобства пользователя - чтобы он не тратил время на отправку некорректных данных. Проверять на сервере надо все равно. Естественно, любой школьник может эту валидацию легко отключить, подправив HTML-код страницы в инспекторе или сделав свою форму.
> А если сделать защиту, как в той самой статье от ОПа про XSRF уязвимость, невидимую форму с токеном и куками, в таком случае я могу обойтись только клиентской валидацией ну или хотя бы required и быть уверенным что мой $_POST точно будет не пустым?
Нет, так как пользователь может отключить валидацию в браузере, либо отправлять HTTP POST запрос не из браузера, а программой вроде curl, которая позволяет указывать любые данные. Если ты читал урок про HTTP ( https://github.com/codedokode/pasta/blob/master/network/http.md ), то знаешь, что браузер при отправке формы просто соединяется с сервером и отправляет определенный кусок текста. Никто не запрещает сделать то же самое без браузера. Или модифицировать браузер.
То есть защита токеном (либо по Referer/Origin) это защита именно от CSRF и ничего больше.
> не считается ли плохим использовать статические методы?
Зависит от ситуации. Статические методы обычно используются там, где нет состояния (ничего не сохраняется в поля). Вроде функции перевода миль в километры. В случае с роутером, я не очень понимаю, какая от этого выгода. У него наверняка есть какое-то состояние.
Вообще, так абстрактно сложно объяснить, но основная проблема статических методов как раз то, что они меняют глобальное состояние. То есть ты в одном месте кода вызвал метод, он что-то записал в статические поля, и это влияет на весь остальной код (так как статическое поле это по сути глобальная переменная, оно существует в единственном экземпляре). А когда у тебя объекты, ты можешь создать его, что-то с ним сделать и все состояние остается в этом обьекте, и никак не влияет на другой код.
За счет этого разбирать код может быть проще - в случае статических методов, их можно вызвать откуда угодно, а обычные методы - только оттуда, куда передан данный объект.
Также, когда у тебя обычные нестатические объекты, ты можешь создать несколько объектов с разными настройками. А в случае статических полей настройки - они глобальные.
В общем, обычные объекты этим удобнее, они позволяют писать более надежный код, так как они не влияют на глобальное состояние, а хранят состояние внутри. И ты контролируешь, кому ты даешь объект, кто может с ним что-то делать.
Еще немного по этой теме можно поискать тут
- https://github.com/codedokode/pasta/blob/master/arch/di.md
- https://habrahabr.ru/post/169301/
- https://www.google.ru/search?q=чем+плохи+статические+методы&newwindow=1&dcr=0&gbv=1&sei=vX1PWum9BYqXsgHLgZuABg
- https://www.google.ru/search?q=what+wrong+with+static+methods&newwindow=1&dcr=0&gbv=1&sei=wn1PWuS2NMmgsgGtvZuABg (англ)
Главное понимать, что мы избегаем эти методы не потому, что верим в какую-то догму, а их прагматичных соображений, потому что хотим более качественный код, с которым проще работать, удобнее тестировать. Потому советую почитать статьи из гугла.
> Я думал посл добавления записи брать последний айди из бд, как-то его там хешировать например и записывать в куки, а потом проверять, я даже хз будет ли это работать.
Есть lastInsertId который работает как нужно
Если класть в куки id или хеш от него, то ты решаешь задачу идентификации (определения, кто перед тобой), но не решаешь задачу аутентификации (подтверждения, что пользователь тот, за кого себя выдает). Что мешает хакеру записать себе куку с любым id? Для аутентификации нужно использовать какой-то секрет, который хакер не знает. Например:
- хеш пароля (но у нас нет паролей)
- случайно сгенерированный токен
- id, подписанный секретным паролем приложения (хеш от id + секретный пароль)
- id сессии
Да как бы дело не во Фрилансе, многие компании берут Джунов и прочее для работы на удаленке.
$regexp = '/\s[,][.][;]/';
$food= 'Хлеб, мясо яблоко. пирог; отбивная';
$matches= preg_split ($regexp, $food);
var_dump($matches);
Вводить могут хоть как, но нужны только слова.
>>16122
Прога на сервере, отвечающая за отдачу HTTP-запросов.
Я ж тебе вверху давал код. Там два параметра допилить. Что же вы батенька такой лентяй:
<?php
error_reporting(-1);
mb_internal_encoding('utf-8');
$reg = '/[^а-я]+/iu';
$str = 'Хлеб, мясо яблоко. пирог; отбивная ';
echo $str . PHP_EOL;
$result = preg_split($reg, $str, -1, PREG_SPLIT_NO_EMPTY);
var_dump($result);
>>16216
Справедливости ради, мне понадобилось абсолютно иное выражение и Ваше не подходит!
В полной мере.
Суть я в том, что слова могут вводиться с непредсказуемым порядком "посторонних" символов.
Если я пользуюсь Вашим примером, то все работает только при одной комбинации:
Хлеб пробел запятая пробел свекла.
Посему, хотел бы уточнить в чем ошибка данного примера:
https://regex101.com/r/pfaOHr/2
Моя логика:
может быть сколько угодно пробелов, а может и не быть
может быть любой из данных символов, а может и не быть
может быть сколько угодно пробелов, а может и не быть
Алсо:
>а может и не быть
а как ты собираешься разделять слова тогда? Хотя бы один знак любой должен присутствовать. У тебя не регекспы хромают, а логика (Без обид).
А! Т.е. "что-то из перечисленного появиться один раз".
Хороший вариант. Спасибо!
>>16239
Ну, подразумевается, что вводящий значения пользователь не будет аутистом, который пишет "яйцахлебкрокодилзалупасыр" и не замечает ничего странного, но может присутствовать что-то одно из списка.
Ну типа "яйца.хлеб.твоямамка.говно".
Считать сколько студентов в БД и если больше 50, то создавать новую подстраницу?
Да. Это набор уже готовых решений.
Да. Подключаешь и просто задаешь элементам нужны классы и вкладываешь их друг в друга в нужном порядке.
Почему в новом бутстрапе не работает nav? Он заменён расовоправильным navbar? Он у меня работает.
Считаешь, сколько всего в БД студентов, делишь на допустим 20 и получаешь число страниц. Выводишь список страниц. Номер страницы можно передавать в параметре page, то есть ссылки могут выглядеть так:
/students.php (1-я страница)
/students.php?page=2 (2-я)
/students.php?page=3 (3-я)
итд.
Не забудь, что если выбрана сортировка или поиск, то их параметры надо тоже добавлять в ссылку. Если идет поиск, то для расчета числа страниц нужно считать только соответствующих условиям поиска студентов.
Для выборки части результата в MySQL есть нестандартная (ее нет в стандарте SQL) опция LIMIT.
>>16219
Есть еще интересный вариант - разбивать по границе слова (\b): https://regex101.com/r/bN3dsN/2 (я добавил флаг u для поддержки юникода).
Также, можно использовать \W (не-слово).
Не знаю, подойдет ли.
>>16216
Надо писать [^а-яё] так как "ё" не входит в диапазон "а-я", а идет отдельно.
>>16122
Это веб-сервер, отвечающий на HTTP запросы. Подробнее: https://github.com/codedokode/pasta/blob/master/network/http.md
Считаешь, сколько всего в БД студентов, делишь на допустим 20 и получаешь число страниц. Выводишь список страниц. Номер страницы можно передавать в параметре page, то есть ссылки могут выглядеть так:
/students.php (1-я страница)
/students.php?page=2 (2-я)
/students.php?page=3 (3-я)
итд.
Не забудь, что если выбрана сортировка или поиск, то их параметры надо тоже добавлять в ссылку. Если идет поиск, то для расчета числа страниц нужно считать только соответствующих условиям поиска студентов.
Для выборки части результата в MySQL есть нестандартная (ее нет в стандарте SQL) опция LIMIT.
>>16219
Есть еще интересный вариант - разбивать по границе слова (\b): https://regex101.com/r/bN3dsN/2 (я добавил флаг u для поддержки юникода).
Также, можно использовать \W (не-слово).
Не знаю, подойдет ли.
>>16216
Надо писать [^а-яё] так как "ё" не входит в диапазон "а-я", а идет отдельно.
>>16122
Это веб-сервер, отвечающий на HTTP запросы. Подробнее: https://github.com/codedokode/pasta/blob/master/network/http.md
> 1. Но в конкретной задаче же выводятся только переменные. И, повторюсь, назначение фигурных скобок еще не было описано в учебнике.
Это дело вкуса ОПа. Наверно, чтобы можно было вставлять в строку элементы массивов и тд. То, что не описано, плохо, многие спрашивают.
> Опять же, для новичка, запускающего пример на локалхосте, не очевидно, почему переносы строк не работают,
Они видны, если открыть исходный код страницы, а не смотреть на результат интерпретации HTML браузером. Там ведь не только переводы строк не работают, но и например конструкция & lt заменяется на знак "меньше". Никто не писал, что код без изменений можно запускать на веб-сервере.
Также. Чтобы переносы строк нормально работали и в браузере и в ideone (и в консоли), можно использовать для этого \n, а в начале программы поставить
header("Content-Type: text/plain; charset=utf-8");
Это заставит браузер воспринимать то, что выводит твоя программа, как обычный текст, а не HTML, и уважать переносы строк в нем (так как в языке HTML перенос строки равносилен пробелу).
> Сейчас, кстати, прохожу курс по Yii 2 от webformyself,
Тебе надо изучить сначала ООП, MVC, работу с БД, написание веб-приложений вообще (то есть формы, таблицы, HTTP) - ты все это знаешь? У нас есть в ОП посте задача про студентов, если ты не можешь ее сделать, тебе рано браться за Юи.
>>15944
Какой малопонятный пост. Где его прекращать использовать? И почему? Потому-что кто-то на имиджборде написал пост жирным шрифтом?
>>15866
Не рассмотрен 4-й возможный исход (даблов нет, но сумма очков равна), например, если выпало 1, 5 у анона и 2, 4 у компа.
exit не нужен.
>>15865
В задании оно есть, так как там первый if идет отдельным блоком, и нам надо не выполнять код дальше в случае срабатывания этого блока.
>>15826
Таким, как ты, мы не помогаем.
> 1. Но в конкретной задаче же выводятся только переменные. И, повторюсь, назначение фигурных скобок еще не было описано в учебнике.
Это дело вкуса ОПа. Наверно, чтобы можно было вставлять в строку элементы массивов и тд. То, что не описано, плохо, многие спрашивают.
> Опять же, для новичка, запускающего пример на локалхосте, не очевидно, почему переносы строк не работают,
Они видны, если открыть исходный код страницы, а не смотреть на результат интерпретации HTML браузером. Там ведь не только переводы строк не работают, но и например конструкция & lt заменяется на знак "меньше". Никто не писал, что код без изменений можно запускать на веб-сервере.
Также. Чтобы переносы строк нормально работали и в браузере и в ideone (и в консоли), можно использовать для этого \n, а в начале программы поставить
header("Content-Type: text/plain; charset=utf-8");
Это заставит браузер воспринимать то, что выводит твоя программа, как обычный текст, а не HTML, и уважать переносы строк в нем (так как в языке HTML перенос строки равносилен пробелу).
> Сейчас, кстати, прохожу курс по Yii 2 от webformyself,
Тебе надо изучить сначала ООП, MVC, работу с БД, написание веб-приложений вообще (то есть формы, таблицы, HTTP) - ты все это знаешь? У нас есть в ОП посте задача про студентов, если ты не можешь ее сделать, тебе рано браться за Юи.
>>15944
Какой малопонятный пост. Где его прекращать использовать? И почему? Потому-что кто-то на имиджборде написал пост жирным шрифтом?
>>15866
Не рассмотрен 4-й возможный исход (даблов нет, но сумма очков равна), например, если выпало 1, 5 у анона и 2, 4 у компа.
exit не нужен.
>>15865
В задании оно есть, так как там первый if идет отдельным блоком, и нам надо не выполнять код дальше в случае срабатывания этого блока.
>>15826
Таким, как ты, мы не помогаем.
> (\,|\.|\?|\!)
короче написать [,.?!]. Также, "," и "!" не спецсимволы и не требуют экранирования.
> [^\s]
То же самое, что \S
preg_replace может принимать массив регулярок и массив строк для замены: http://php.net/manual/ru/function.preg-replace.php
> надо еще сделать буквы заглавными, но не могу придумать как
1) Разбить текст на массив строк, у каждой заменить первую букву, склеить обратно
2) Использовать preg_replace_callback, который вызывает указанную тобой функцию для каждого найденного фрагмента текста. В ней ты можешь делать любые замены.
>>15695
С этой задачей у многих сложности.
Попробуй переписать код внутри цикла примерно так:
- прибавляем проценты и комиссию к остатку долга (!не вычитаем ничего пока!)
- если остаток маленький, выплачиваем сколько осталось и уходим
- иначе платим 5000
«Платим» здесь значит уменьшаем долг и увеличиваем общую сумму выплаченного.
Также, можешь натыкать там echo, чтобы увидеть значения переменных на каждом шаге.
>>15678
Либо select2, либо несколько полей, либо текстареа и попросить пользователя писать названия на отдельной строке.
> (\,|\.|\?|\!)
короче написать [,.?!]. Также, "," и "!" не спецсимволы и не требуют экранирования.
> [^\s]
То же самое, что \S
preg_replace может принимать массив регулярок и массив строк для замены: http://php.net/manual/ru/function.preg-replace.php
> надо еще сделать буквы заглавными, но не могу придумать как
1) Разбить текст на массив строк, у каждой заменить первую букву, склеить обратно
2) Использовать preg_replace_callback, который вызывает указанную тобой функцию для каждого найденного фрагмента текста. В ней ты можешь делать любые замены.
>>15695
С этой задачей у многих сложности.
Попробуй переписать код внутри цикла примерно так:
- прибавляем проценты и комиссию к остатку долга (!не вычитаем ничего пока!)
- если остаток маленький, выплачиваем сколько осталось и уходим
- иначе платим 5000
«Платим» здесь значит уменьшаем долг и увеличиваем общую сумму выплаченного.
Также, можешь натыкать там echo, чтобы увидеть значения переменных на каждом шаге.
>>15678
Либо select2, либо несколько полей, либо текстареа и попросить пользователя писать названия на отдельной строке.
> Глядя на современные веб приложения я все больше замечаю, что php больше используется как веб-сервис для взаемодействия с бд, а все остальное пишется на каком-то js фреймворке.
Ты наверно говоришь о SPA (Single Page Application), когда на клиенте работает JS-приложение и оно получает/отправляет на сервер данные через AJAX.
Сразу скажу, что рассуждать "в 2018 году X устарело и надо всегда использовать Y" неправильно. У SPA есть особенности, которые дают ему преимущество перед традиционным подходом (генерация страниц на сервере) в одних ситуациях, и оборачиваются недостатками в других. Не хочу даваать готовый ответ, давайте вместе подумаем, в чем плюсы и минусы SPA против традиционных приложений? Где что лучше использовать?
Подсказка, рассмотрите такие моменты:
- трудоемкость
- возможность разделения работы между командами
- удобство индексирования роботами
- время отклика интерфейса
- время загрузки страницы
- долго работающее, днями и неделями открытое приложение (вроде Gmail или календаря)
- сайт, на который пользователь приходит из гугла, что-то смотрит и закрывает
- работа в оффлайне, или с пропадающим интернетом (мобильная связь)
- дашбоарды, отображающие разные обновляющиеся данные и графики
- интерактивные интерфейсы, где много активных элементов, кнопок, полей
- приложение-мессенджер
Есть еще, кстати, смешанный вариант - традиционное приложение с отдельными интерактивными частями на JS. И вариант, когда традиционное приложение перехватывает клики по ссылкам, запрашивает аяксом страницу с сервера и выводит ее без перезагрузки страницы.
>>15268
text-align: center не подойдет?
>>15593
> Float - Не нужен
Ты вообще с ним знаком? Мне кажется, ты CSS плохо знаешь. Он отлично работает в таких ситуациях например:
- вынос элемента на поля
- врезка картинки с края текста
- горизонтальное расположение элементов с переносом
>>15387
Ты бы теорию почитал, это ведь в самом начале стандарта CSS написано. Это несемантично. Теги должны размечать текст, показывать чем является тот или иной кусок текста, а не задавать его внешний вид, размер шрифта или расположение. Для этого есть CSS.
Дело не в устаревании, а в нелогичности.
> Глядя на современные веб приложения я все больше замечаю, что php больше используется как веб-сервис для взаемодействия с бд, а все остальное пишется на каком-то js фреймворке.
Ты наверно говоришь о SPA (Single Page Application), когда на клиенте работает JS-приложение и оно получает/отправляет на сервер данные через AJAX.
Сразу скажу, что рассуждать "в 2018 году X устарело и надо всегда использовать Y" неправильно. У SPA есть особенности, которые дают ему преимущество перед традиционным подходом (генерация страниц на сервере) в одних ситуациях, и оборачиваются недостатками в других. Не хочу даваать готовый ответ, давайте вместе подумаем, в чем плюсы и минусы SPA против традиционных приложений? Где что лучше использовать?
Подсказка, рассмотрите такие моменты:
- трудоемкость
- возможность разделения работы между командами
- удобство индексирования роботами
- время отклика интерфейса
- время загрузки страницы
- долго работающее, днями и неделями открытое приложение (вроде Gmail или календаря)
- сайт, на который пользователь приходит из гугла, что-то смотрит и закрывает
- работа в оффлайне, или с пропадающим интернетом (мобильная связь)
- дашбоарды, отображающие разные обновляющиеся данные и графики
- интерактивные интерфейсы, где много активных элементов, кнопок, полей
- приложение-мессенджер
Есть еще, кстати, смешанный вариант - традиционное приложение с отдельными интерактивными частями на JS. И вариант, когда традиционное приложение перехватывает клики по ссылкам, запрашивает аяксом страницу с сервера и выводит ее без перезагрузки страницы.
>>15268
text-align: center не подойдет?
>>15593
> Float - Не нужен
Ты вообще с ним знаком? Мне кажется, ты CSS плохо знаешь. Он отлично работает в таких ситуациях например:
- вынос элемента на поля
- врезка картинки с края текста
- горизонтальное расположение элементов с переносом
>>15387
Ты бы теорию почитал, это ведь в самом начале стандарта CSS написано. Это несемантично. Теги должны размечать текст, показывать чем является тот или иной кусок текста, а не задавать его внешний вид, размер шрифта или расположение. Для этого есть CSS.
Дело не в устаревании, а в нелогичности.
Тут 5 однотипных регулярок, их можно объединить в одну. Также, внизу много сообщений об ошибках - их надо исправить.
>>15402
>>15348
Там в аннотации прописывается не тип поля, а тип маппинга - как преобразовывать данные из БД перед записью в поле объекта. И наоборот. Так что да, прописывать.
http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/types.html
Ну, например, для поля типа int там может стоять integer, bigint, smallint в зависимости от типа в БД.
Если где-то Доктрина может правильно определить маппинг по умолчанию, то можно не прописывать.
Тайп-хинты тут вообще не при чем, ты их указываешь на методах, и доктрина на них не смотрит. Ты вообще можешь писать там любые методы в зависимости от логики, не обязательно только get/set, Доктрине они все равно не нужны. Тайп-хинты писать конечно надо, но не для Доктрины, а для себя, для защиты от ошибок, для документирования кода.
>>15202
Еще есть вариант возвращать объект-коллекцию ошибок.
>>15285
> php-fmp работает быстрее, чем php как служба апача.
Есть какие-то подтверждения? я в этом сомневаюсь.
Используют php-fpm, так как нгинкс обычно уже есть (для раздачи статики, что он умеет очень хорошо), и ставить за ним второй веб-сервер (Апач) только ради запуска внутри него модуля PHP нет смысла, проще сразу поставить php-fpm. Также, php-fpm в случае нескольких сайтов позволяет использовать для каждого своих пользователей, свои лимиты, видеть кто сколько потребляет CPU/памяти и тд.
Плюсы Апача - много разных модулей и настроек, но, наверно, без него все же будет лучше. Также да, часто бывает такое, что проект исторически работает на Апаче и перед ним просто втыкают nginx для статики, не трогая остальное.
>>15196
А если ты напишешь места в уроках, которые ты не понял, или понял сначала не так, или долго разбирался, может быть, мы сможем сделать сайт еще лучше! А может ты даже сможешь предложить лучшее объяснение!
>>15187
> через ТП провайдера,
Это плохой вариант, так как 1) затраты времени на коммуникацию 2) они не заинтересованы сделать хорошо, а просто хотят чтобы ты поскорее от них отстал 3) у них один сервер на кучу сайтов и ради одного пользователя неохота что-то менять, даже если он дает готовый кусок конфига. Вдруг сломается?
В любом нормальном проекте свой сервер, и иногда свой админ к нему.
Тут 5 однотипных регулярок, их можно объединить в одну. Также, внизу много сообщений об ошибках - их надо исправить.
>>15402
>>15348
Там в аннотации прописывается не тип поля, а тип маппинга - как преобразовывать данные из БД перед записью в поле объекта. И наоборот. Так что да, прописывать.
http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/types.html
Ну, например, для поля типа int там может стоять integer, bigint, smallint в зависимости от типа в БД.
Если где-то Доктрина может правильно определить маппинг по умолчанию, то можно не прописывать.
Тайп-хинты тут вообще не при чем, ты их указываешь на методах, и доктрина на них не смотрит. Ты вообще можешь писать там любые методы в зависимости от логики, не обязательно только get/set, Доктрине они все равно не нужны. Тайп-хинты писать конечно надо, но не для Доктрины, а для себя, для защиты от ошибок, для документирования кода.
>>15202
Еще есть вариант возвращать объект-коллекцию ошибок.
>>15285
> php-fmp работает быстрее, чем php как служба апача.
Есть какие-то подтверждения? я в этом сомневаюсь.
Используют php-fpm, так как нгинкс обычно уже есть (для раздачи статики, что он умеет очень хорошо), и ставить за ним второй веб-сервер (Апач) только ради запуска внутри него модуля PHP нет смысла, проще сразу поставить php-fpm. Также, php-fpm в случае нескольких сайтов позволяет использовать для каждого своих пользователей, свои лимиты, видеть кто сколько потребляет CPU/памяти и тд.
Плюсы Апача - много разных модулей и настроек, но, наверно, без него все же будет лучше. Также да, часто бывает такое, что проект исторически работает на Апаче и перед ним просто втыкают nginx для статики, не трогая остальное.
>>15196
А если ты напишешь места в уроках, которые ты не понял, или понял сначала не так, или долго разбирался, может быть, мы сможем сделать сайт еще лучше! А может ты даже сможешь предложить лучшее объяснение!
>>15187
> через ТП провайдера,
Это плохой вариант, так как 1) затраты времени на коммуникацию 2) они не заинтересованы сделать хорошо, а просто хотят чтобы ты поскорее от них отстал 3) у них один сервер на кучу сайтов и ради одного пользователя неохота что-то менять, даже если он дает готовый кусок конфига. Вдруг сломается?
В любом нормальном проекте свой сервер, и иногда свой админ к нему.
В учебнике в ОП-посте и про объекты рассказывается.
А так, есть ситуации, когда массив прекрасно подходит.
>>15148
Справедливости ради, lazy loading я видел в документации Доктрины, там это было про загрузку данных из БД.
У него задача про валидацию формы и там миллиона ошибок быть не может.
Разумеется, при проверке на пустые значения лучше выходить из цикла как только стало понятно, что массив не пустой.
>>15147
А в ОП посте есть супер-сложная задачка на SPA ведь https://github.com/codedokode/pasta/blob/master/js/spa.md
Если сложно, сделай сайт-приложение для чтения новостей с категориями (либо сделай инстаграм), потом добавь там лайки и комменты.
>>15119
В цикле ничего плохого для данной задачи. Наоборот, использовать тут array_filter/map выглядит как усложнение, и я не понимаю выгоды. Что, циклы уже объявлены устаревшими?
in_array можно, если мы ищем именно null.
>>15123
Не надо никого бить по рукам. Нужно спокойно, аргументированно объяснить, чем один вариант лучше другого. Уверен, что тогда люди прислушаются. А если начинать речь с того, что ты д`Артяньян, то конечно симпатии это не вызывает.
>>15122
6-8 месяцев
В учебнике в ОП-посте и про объекты рассказывается.
А так, есть ситуации, когда массив прекрасно подходит.
>>15148
Справедливости ради, lazy loading я видел в документации Доктрины, там это было про загрузку данных из БД.
У него задача про валидацию формы и там миллиона ошибок быть не может.
Разумеется, при проверке на пустые значения лучше выходить из цикла как только стало понятно, что массив не пустой.
>>15147
А в ОП посте есть супер-сложная задачка на SPA ведь https://github.com/codedokode/pasta/blob/master/js/spa.md
Если сложно, сделай сайт-приложение для чтения новостей с категориями (либо сделай инстаграм), потом добавь там лайки и комменты.
>>15119
В цикле ничего плохого для данной задачи. Наоборот, использовать тут array_filter/map выглядит как усложнение, и я не понимаю выгоды. Что, циклы уже объявлены устаревшими?
in_array можно, если мы ищем именно null.
>>15123
Не надо никого бить по рукам. Нужно спокойно, аргументированно объяснить, чем один вариант лучше другого. Уверен, что тогда люди прислушаются. А если начинать речь с того, что ты д`Артяньян, то конечно симпатии это не вызывает.
>>15122
6-8 месяцев
Наверно !in_array(null, ...) ? Там еще стоит добавить параметр, чтобы in_array делал строгое сравнение с null.
>>14847
Зачем использовать хеш, если можно использовать сам URL? отлаживать код будет проще, если захочешь посмотреть содержимое кеша.
Кеш это вообще костыль, который используют не от хорошей жизни и которого стоит избегать по возможности.
Подвохи кеша такие:
- устаревание данных в кеше (товар закончился, а в кеше данные, будто бы он еще есть - недовольный клиент)
- если идет большое количество разных запросов, то кеш будет большой и малоэффективный
Чтобы кеш работал эффективно, число попаданий в кеш должно быть больше, чем число "промахов".
Твой алгоритм увеличивает скорость ответа только для второго пользователя, отправившего тот же запрос в течение промежутка времени. То есть если часто идут одинаковые запросы.
Повысить эффективность можно, если генерировать кеш не при первом обращении, а по крону в оффлайне - тогда даже первый пользователь сможет получить быстрый ответ из кеша.
>>14854
> У API есть эндпоинт, позволяющий по IP-адресу клиента определить его город, страну и координаты города.
Вообще, проще конечно скачать себе какую-нибудь геобазу.
>>14840
Права на файлы надо проверить наверно?
>>14836
Вообще, папка vendor и не должна быть публично доступна.
>>14711
Виртуальные хосты. Ты можешь создать несколько "сайтов" и каждому назначить отдельную корневую папку.
Наверно !in_array(null, ...) ? Там еще стоит добавить параметр, чтобы in_array делал строгое сравнение с null.
>>14847
Зачем использовать хеш, если можно использовать сам URL? отлаживать код будет проще, если захочешь посмотреть содержимое кеша.
Кеш это вообще костыль, который используют не от хорошей жизни и которого стоит избегать по возможности.
Подвохи кеша такие:
- устаревание данных в кеше (товар закончился, а в кеше данные, будто бы он еще есть - недовольный клиент)
- если идет большое количество разных запросов, то кеш будет большой и малоэффективный
Чтобы кеш работал эффективно, число попаданий в кеш должно быть больше, чем число "промахов".
Твой алгоритм увеличивает скорость ответа только для второго пользователя, отправившего тот же запрос в течение промежутка времени. То есть если часто идут одинаковые запросы.
Повысить эффективность можно, если генерировать кеш не при первом обращении, а по крону в оффлайне - тогда даже первый пользователь сможет получить быстрый ответ из кеша.
>>14854
> У API есть эндпоинт, позволяющий по IP-адресу клиента определить его город, страну и координаты города.
Вообще, проще конечно скачать себе какую-нибудь геобазу.
>>14840
Права на файлы надо проверить наверно?
>>14836
Вообще, папка vendor и не должна быть публично доступна.
>>14711
Виртуальные хосты. Ты можешь создать несколько "сайтов" и каждому назначить отдельную корневую папку.
Начнем с того, что в PHP все массивы фактически ассоциативные (а также упорядоченные, то есть элементы хранятся в том порядке, в котором их добавляли). Массив - это упорядоченная последовательность элементов, каждый элемент имеет ключ и значение. Ключ может быть только числом или строкой, не может повторяться, используется для нахождения элемента. Значение элемента может быть любым, строкой, числом или даже другим массивом.
"Неассоциативный" массив отличается от ассоциативного тем, что в качестве ключей можно использовать только идущие по возрастанию числа. В PHP массивы ассоциативные и такого ограниченя нет.
> Например почему $key распарсивается в итоге на $params и $value? Как он узнаёт что там правильные данные?
foreach работает так. Он проходится по списку элементов, из которых состоит массив. Для каждого элемента, он копирует его ключ и значение в переменные key/value, затем выполняет тело цикла. Затем берет следующий элемент, копирует ключ/значение в переменные и снова выполняет тело цикла. И так столько раз, сколько в массиве элементов.
> А если например там виесто одного из параметров - массив вложенный?
То этот массив будет скопирован в value.
Вот возьмем твой пример. Тут ты создаешь массив из 3 элементов:
> $cars = Array("nissan" => $nissan, "toyota" => $toyota, "isuzu" => $isuzu);
Ключи тут строки, а в значениях хранятся другие массивы с информацией о машине. А почему бы и нет?
>>14790
Есть CSS свойство float: http://softwaremaniacs.org/blog/2005/12/01/css-layout-float/
Также, может тебе поможет мой недописанный урок https://github.com/codedokode/pasta/blob/master/html/positioning.md
>>14646
Я хочу прокомментировать это:
> $_POST['mail_subject'] = htmlspecialchars(stripslashes($_POST['mail_subject']));
Это вообще неправильно. Ну например, зачем там stripslashes? Он же вырезает бекслеши из текста. Кто об этом просил?
Также, htmlspecilachars тут использован неправильно, его надо использовать при выводе HTML, а не в начале скрипта. Ну например, пользователь ввел в поле "<", и мы хотим посчитать длину текста. Если мы сначала вызовем htmlspecialchars, то он превратит "<" в "& lt ;" и мы получим 4 вместо 1.
Также, в заголовках писем не используется HTML кодирование, и тема <привет> превратится в < ;привет& gt; и именно так и будет отображаться в почтовой программе.
htmlspecialchars нужна только в одном случае: для экранирования символов в тексте, который подставляется в HTML-код. И применять ее надо только там, где происходит эта подстановка.
Почитайте про правильное использование htmlspecialchars: https://github.com/codedokode/pasta/blob/master/security/xss.md
Тем, кто хочет разобраться с экранированием, я рекомендую решить задачу: https://github.com/codedokode/pasta/blob/master/soft/web-server.md#Экранирование
Начнем с того, что в PHP все массивы фактически ассоциативные (а также упорядоченные, то есть элементы хранятся в том порядке, в котором их добавляли). Массив - это упорядоченная последовательность элементов, каждый элемент имеет ключ и значение. Ключ может быть только числом или строкой, не может повторяться, используется для нахождения элемента. Значение элемента может быть любым, строкой, числом или даже другим массивом.
"Неассоциативный" массив отличается от ассоциативного тем, что в качестве ключей можно использовать только идущие по возрастанию числа. В PHP массивы ассоциативные и такого ограниченя нет.
> Например почему $key распарсивается в итоге на $params и $value? Как он узнаёт что там правильные данные?
foreach работает так. Он проходится по списку элементов, из которых состоит массив. Для каждого элемента, он копирует его ключ и значение в переменные key/value, затем выполняет тело цикла. Затем берет следующий элемент, копирует ключ/значение в переменные и снова выполняет тело цикла. И так столько раз, сколько в массиве элементов.
> А если например там виесто одного из параметров - массив вложенный?
То этот массив будет скопирован в value.
Вот возьмем твой пример. Тут ты создаешь массив из 3 элементов:
> $cars = Array("nissan" => $nissan, "toyota" => $toyota, "isuzu" => $isuzu);
Ключи тут строки, а в значениях хранятся другие массивы с информацией о машине. А почему бы и нет?
>>14790
Есть CSS свойство float: http://softwaremaniacs.org/blog/2005/12/01/css-layout-float/
Также, может тебе поможет мой недописанный урок https://github.com/codedokode/pasta/blob/master/html/positioning.md
>>14646
Я хочу прокомментировать это:
> $_POST['mail_subject'] = htmlspecialchars(stripslashes($_POST['mail_subject']));
Это вообще неправильно. Ну например, зачем там stripslashes? Он же вырезает бекслеши из текста. Кто об этом просил?
Также, htmlspecilachars тут использован неправильно, его надо использовать при выводе HTML, а не в начале скрипта. Ну например, пользователь ввел в поле "<", и мы хотим посчитать длину текста. Если мы сначала вызовем htmlspecialchars, то он превратит "<" в "& lt ;" и мы получим 4 вместо 1.
Также, в заголовках писем не используется HTML кодирование, и тема <привет> превратится в < ;привет& gt; и именно так и будет отображаться в почтовой программе.
htmlspecialchars нужна только в одном случае: для экранирования символов в тексте, который подставляется в HTML-код. И применять ее надо только там, где происходит эта подстановка.
Почитайте про правильное использование htmlspecialchars: https://github.com/codedokode/pasta/blob/master/security/xss.md
Тем, кто хочет разобраться с экранированием, я рекомендую решить задачу: https://github.com/codedokode/pasta/blob/master/soft/web-server.md#Экранирование
Тайп хинты позволяют указать, что аргумент функции должен быть определенного типа (например быть объектом определенного класса или его наследника). Тайп хинт делает код понятнее (так как видно какого типа переменная) и надежнее (так как PHP не позволит передать что-то неразрешенное и ты сразу увидишь ошибку). Используй их везде.
Мануал: http://php.net/manual/ru/language.oop5.typehinting.php
Обрати внимание, что php7 усовершенствовал систему тайп-хинтов - теперь можно в их качестве указывать примитивные типы вроде int/string, а в php7.1 стало можно указывать тайп-хинт для возвращаемого функцией значения: https://habrahabr.ru/post/267799/ , причем можно указать тип void, значащий, что функция ничего не возвращает.
>>14521
Только, анон, не храни пароль в открытом виде в Бд, тем более в учебном примере. Храни там соленый хеш.
>>14528
Предлагаю тебе для практики в ООП 2 полезных задачки:
--------------------------------
Задача про Гостиницу
Есть Гостиница, в ней есть Номера. Для каждого Номера известен его номер, количество Гостей, которое в него влезет, а также цена за сутки. В Гостиницу приезжают Гости. Нужно сделать объектную модель Гостиницы с такими возможностями (методами):
- получить список свободных номеров на определенную дату
- получить список свободных номеров, которые будут свободны в определенный диапазон дат (от A до B)
- дан список Гостей и диапазон дат, в которые они хотели бы заселиться. Необходимо подобрать им самый дешевый (а среди номеров с одинаковой ценой - самый маленький) Номер, который их вместит и который свободен в это время.
- то же самое, но при отстутствии одного подходящего номера для Гостей разрешается заселить их в несколько номеров, опять же, начиная с самых дешевых. Например, приехало 3 Гостя, но все 3-местные номера заняты и мы выделяем 2 2-местных, или 3 1-местных или 1-местный + 2-местный.
- зарегистрировать проживание данных Гостей в данных Номерах на данный период
- получить историю заселения Номера (кто в нем когда жил)
- получить историю заселения Гостя (в каких номерах он жил)
- получить статистику доходов Гостиницы за данный диапазон дат (в день A отдель заработал X тугриков, в день B - Y тугриков и так далее)
Для хранения дат подходит встроенный в PHP класс DateImmutable.
Задача про Продюсерское Агенство
Есть ПродюсерскоеАгенство, и оно периодически сотрудничает с разными Персонами для участия в рекламных, музыкальных, кинематографических и других Проектах. Агенству нужно хранить информацию о Персонах, с которыми оно контактировало или планирует контактировать. Тебе поручено создание соответствующей базы данных.
Персоны - это люди, у которых есть какие-то творческие способности. У каждой Персоны есть такие свойства:
- имя
- контактный номер телефона
Кроме того, у них могут быть навыки: Персона может быть Актером, Моделью, Музыкантом, Менеджером.
У Актера в дополнение к обычным свойствам есть свойство: список Фильмов, в которых он снимался
У Музыканта есть свойства: список Групп, в которых он участвует, и список инструментов, на которых он умеет играть
У Модели есть свойства: рост, цвет глаз и цвет волос
У Менеджера (Агент или менеджер по работе с талантами) есть свойство: название Агенства, которое он представляет.
У Актера, Музыканта или Модели может быть свой Менеджер, и эта информация должна быть указана в их профиле (нельзя заключить договор без обсуждения с ним).
Нужно представить информацию о Персонах в виде объектной модели (набора классов), которая бы позволила наиболее удобно представить информацию о них. Соответственно "база Персон" - это просто массив таких объектов. Тебе нужно спроектировать эти классы. Методы тут писать не нужно, хватит только полей.
------------------------------------
Задачи на ООП решаются примерно так:
- определяем, какие у нас есть в задаче сущности и для каждой делаем класс
- определяем, какие их свойвства нам интересны, делаем поля в классах
- определяем, что эти классы должны уметь делать, какую информаицю предоставлять, что с ними можно делать - и делаем методы
- определяем, как сущности связаны между собой, если их больше одной
Тайп хинты позволяют указать, что аргумент функции должен быть определенного типа (например быть объектом определенного класса или его наследника). Тайп хинт делает код понятнее (так как видно какого типа переменная) и надежнее (так как PHP не позволит передать что-то неразрешенное и ты сразу увидишь ошибку). Используй их везде.
Мануал: http://php.net/manual/ru/language.oop5.typehinting.php
Обрати внимание, что php7 усовершенствовал систему тайп-хинтов - теперь можно в их качестве указывать примитивные типы вроде int/string, а в php7.1 стало можно указывать тайп-хинт для возвращаемого функцией значения: https://habrahabr.ru/post/267799/ , причем можно указать тип void, значащий, что функция ничего не возвращает.
>>14521
Только, анон, не храни пароль в открытом виде в Бд, тем более в учебном примере. Храни там соленый хеш.
>>14528
Предлагаю тебе для практики в ООП 2 полезных задачки:
--------------------------------
Задача про Гостиницу
Есть Гостиница, в ней есть Номера. Для каждого Номера известен его номер, количество Гостей, которое в него влезет, а также цена за сутки. В Гостиницу приезжают Гости. Нужно сделать объектную модель Гостиницы с такими возможностями (методами):
- получить список свободных номеров на определенную дату
- получить список свободных номеров, которые будут свободны в определенный диапазон дат (от A до B)
- дан список Гостей и диапазон дат, в которые они хотели бы заселиться. Необходимо подобрать им самый дешевый (а среди номеров с одинаковой ценой - самый маленький) Номер, который их вместит и который свободен в это время.
- то же самое, но при отстутствии одного подходящего номера для Гостей разрешается заселить их в несколько номеров, опять же, начиная с самых дешевых. Например, приехало 3 Гостя, но все 3-местные номера заняты и мы выделяем 2 2-местных, или 3 1-местных или 1-местный + 2-местный.
- зарегистрировать проживание данных Гостей в данных Номерах на данный период
- получить историю заселения Номера (кто в нем когда жил)
- получить историю заселения Гостя (в каких номерах он жил)
- получить статистику доходов Гостиницы за данный диапазон дат (в день A отдель заработал X тугриков, в день B - Y тугриков и так далее)
Для хранения дат подходит встроенный в PHP класс DateImmutable.
Задача про Продюсерское Агенство
Есть ПродюсерскоеАгенство, и оно периодически сотрудничает с разными Персонами для участия в рекламных, музыкальных, кинематографических и других Проектах. Агенству нужно хранить информацию о Персонах, с которыми оно контактировало или планирует контактировать. Тебе поручено создание соответствующей базы данных.
Персоны - это люди, у которых есть какие-то творческие способности. У каждой Персоны есть такие свойства:
- имя
- контактный номер телефона
Кроме того, у них могут быть навыки: Персона может быть Актером, Моделью, Музыкантом, Менеджером.
У Актера в дополнение к обычным свойствам есть свойство: список Фильмов, в которых он снимался
У Музыканта есть свойства: список Групп, в которых он участвует, и список инструментов, на которых он умеет играть
У Модели есть свойства: рост, цвет глаз и цвет волос
У Менеджера (Агент или менеджер по работе с талантами) есть свойство: название Агенства, которое он представляет.
У Актера, Музыканта или Модели может быть свой Менеджер, и эта информация должна быть указана в их профиле (нельзя заключить договор без обсуждения с ним).
Нужно представить информацию о Персонах в виде объектной модели (набора классов), которая бы позволила наиболее удобно представить информацию о них. Соответственно "база Персон" - это просто массив таких объектов. Тебе нужно спроектировать эти классы. Методы тут писать не нужно, хватит только полей.
------------------------------------
Задачи на ООП решаются примерно так:
- определяем, какие у нас есть в задаче сущности и для каждой делаем класс
- определяем, какие их свойвства нам интересны, делаем поля в классах
- определяем, что эти классы должны уметь делать, какую информаицю предоставлять, что с ними можно делать - и делаем методы
- определяем, как сущности связаны между собой, если их больше одной
Оно задает кодировку для функций вроде mb_strlen (они сами угадать кодировку текста не могут). Писать его стоит на случай, если в конфиге PHP стоит не utf-8, чтобы программа корректно работала в этом случае.
>>14329
Ты не просил проверить код, но вкинул его в тред, а значит, я его прокомментирую:
Код ужасный. Не смешивай вперемешку логику (получение данных из БД) и их вывод. Пиши это отдельно .Читай про шаблоны https://github.com/codedokode/pasta/blob/master/php/templates.md
> SELECT * FROM `articles_categories` WHERE `id`
Неправильный запрос. Что значит "WHERE id" ?
Нет проверки того, что функция mysqli_query вернула не ошибку. Читай https://ru.stackoverflow.com/questions/509143/Как-осуществляется-обработка-ошибок-в-mysqli
При выводе данных надо использовать htmlspecialchars: https://github.com/codedokode/pasta/blob/master/security/xss.md
Почему не работает, понять трудно, так как код плохо читаемый.
>>14271
> В каких случаях нужно использовать строку mb_internal_encoding('udf-8')?
не udf, а utf-8. Она задает кодировку по умолчанию для функций вроде mb_strlen, и нужна на тот случай, если другая кодировка указана в php.ini.
>А если ты напишешь места в уроках, которые ты не понял, или понял сначала не так, или долго разбирался, может быть, мы сможем сделать сайт еще лучше! А может ты даже сможешь предложить лучшее объяснение!
Дошел до циклов и вообще нихуя понять не могу. Я понял общую работу циклов, начало=>проверка все ли заебись=>продолжает. Но я уже на первой задачке из циклов ахуел. Я не могу понять как сделать таблицу умножения и тем более расчитать 10% годовых.
Почитал архивач и нашел как все сделать, но до сих пор не понимаю. Почему без точки не работает?
<?php
$n = 10;
for ($i=1; $i<=$n; $i++) {
$sum = $i * $i;
echo $sum .(вот эта ебанная точка) "\n";
}
Блин, учебник хороший, но черт возьми как все расплывчато.
Аноны, порекомендуйте годные курсы, чтобы начать с нуля. Или все равно с чего начинать по HTML?
бесплатная эштиэмэль академия неплохая, у опа также есть гайды. Основы если знать будешь, можешь в мануале быстро искать информацию и ничего и составлять вопросы в гугл.
У меня есть форма аутенфикации и следующие состояния запроса на клиенте:
SUBMIT_REQUEST - ожидание ответа
SUBMIT_ERROR - ошибка
SUBMIT_SUCCESS - запрос прошел успешно
Вроде все понятно, если запрос не отправился, например из-за проблем с сетью - это очевидный SUBMIT_ERROR, а если запрос ушел и вернулся ответ с набором валидационных ошибок, это SUBMIT_ERROR или SUBMIT_SUCCESS? Какой код ответа должен отдать сервер в этом случае 2хх или 4хх?
И как должен выглядеть диалог между сервером и клиентом при авторизации? Сейчас у меня Silex
принимает запрос с логином/паролем, и либо отвечает редиректом, либо присылает идентификатор сессии, который устанавливается в куки. Данные аутенфицированного юзера нужно получать отдельным запросом. В примерах я видел, что сервер сразу присылает ответ с данными юзера, стоит ли настраивать Silex подобным образом?
Нужно ли вообще всегда отдавать код на каждый запрос к api?
Плохой совет про ПарашеКадеми, никому не советую.
тогда лучше начать не с html. без английского в нашем деле будешь хуй сосать
вообще htmlacademy отличные курсы. если жалко денег, посмотри в ознакомительных целях в торрентах
Хорошо, понял, спасибо.
> Вроде все понятно, если запрос не отправился, например из-за проблем с сетью - это очевидный SUBMIT_ERROR, а если запрос ушел и вернулся ответ с набором валидационных ошибок, это SUBMIT_ERROR или SUBMIT_SUCCESS?
Ну это ты определяешь, что считать успехом - получение ответа вообще или получение ответа с подтверждением авторизации. Мне кажется, что последнее. Ты ведь не будешь писать пользователю "вы залогинились успешно, но пароль неправильный".
> Какой код ответа должен отдать сервер в этом случае 2хх или 4хх?
Нет единого мнения. Некоторые используют HTTP-коды (например 401), некоторые отдают 200, но в ответе передают информацию об ошибке.
> И как должен выглядеть диалог между сервером и клиентом при авторизации?
В случае аякс запроса - конечно, редирект делать нет смысла, и надо отдавать ответ (правильный логин/пароль или нет). Обычно ответ отдается в формате JSON. Что касается авторизационной куки, есть 2 варианта - сервер может передавать ее с ответом как куку (в заголовке Set-Cookie) либо же в JSON-ответе, а клиент уже сам создает ее.
Вообще, авторизацию делать аяксом смысла мало, так как после залогинивания/разлогинивания скорее всего ты перезагруззишь всю страницу, и непонятно в чем был смысл использовать тут аякс, если страница все равно перезагружается.
Если ты хочешь делать полноценное REST API, то в описаниии REST https://ru.wikipedia.org/wiki/REST упомянут такой пункт:
> 2. Отсутствие состояния
Разумеется, авторизационная кука или какие-то сессии не очень вписываются в идеологию REST. Ведь эту куку нужно ставить, она может устаревать и тд. Идеальнее было бы передавать имя/пароль (или хеш от него) с каждым запросом.
Вообще (этого поечму-то нигде не пишут), REST сам по себе не очень хорошо подходит для взаимодействия фронтенда с бекендом. Он все же был придуман для взаимодействия программ-клиентов с сервером.
>>16400
Есть еще htmlbook, там тоже какой-то самоучитель был.
>>16351
Точка это оператор склеивания строк. Например, ("a" . "b") дает строку "ab". Соответственно echo $sum . "\n"; склеивает содержимое $sum и символ \n, и выводит получившуюся строку.
Без точки получается просто ошибка:
echo $sum "\n";
здесь PHP после $sum ждет точку с запятой, обозначающую конец команды, а ее нет. Вот и ошибка. У echo синтаксис примерно такой:
echo <значение>;
Написать 2 значения через пробел нельзя.
Кроме точки, ты бы мог использовать подстановку переменных в строку: http://php.net/manual/ru/language.types.string.php#language.types.string.parsing
echo "$sum\n";
> Вроде все понятно, если запрос не отправился, например из-за проблем с сетью - это очевидный SUBMIT_ERROR, а если запрос ушел и вернулся ответ с набором валидационных ошибок, это SUBMIT_ERROR или SUBMIT_SUCCESS?
Ну это ты определяешь, что считать успехом - получение ответа вообще или получение ответа с подтверждением авторизации. Мне кажется, что последнее. Ты ведь не будешь писать пользователю "вы залогинились успешно, но пароль неправильный".
> Какой код ответа должен отдать сервер в этом случае 2хх или 4хх?
Нет единого мнения. Некоторые используют HTTP-коды (например 401), некоторые отдают 200, но в ответе передают информацию об ошибке.
> И как должен выглядеть диалог между сервером и клиентом при авторизации?
В случае аякс запроса - конечно, редирект делать нет смысла, и надо отдавать ответ (правильный логин/пароль или нет). Обычно ответ отдается в формате JSON. Что касается авторизационной куки, есть 2 варианта - сервер может передавать ее с ответом как куку (в заголовке Set-Cookie) либо же в JSON-ответе, а клиент уже сам создает ее.
Вообще, авторизацию делать аяксом смысла мало, так как после залогинивания/разлогинивания скорее всего ты перезагруззишь всю страницу, и непонятно в чем был смысл использовать тут аякс, если страница все равно перезагружается.
Если ты хочешь делать полноценное REST API, то в описаниии REST https://ru.wikipedia.org/wiki/REST упомянут такой пункт:
> 2. Отсутствие состояния
Разумеется, авторизационная кука или какие-то сессии не очень вписываются в идеологию REST. Ведь эту куку нужно ставить, она может устаревать и тд. Идеальнее было бы передавать имя/пароль (или хеш от него) с каждым запросом.
Вообще (этого поечму-то нигде не пишут), REST сам по себе не очень хорошо подходит для взаимодействия фронтенда с бекендом. Он все же был придуман для взаимодействия программ-клиентов с сервером.
>>16400
Есть еще htmlbook, там тоже какой-то самоучитель был.
>>16351
Точка это оператор склеивания строк. Например, ("a" . "b") дает строку "ab". Соответственно echo $sum . "\n"; склеивает содержимое $sum и символ \n, и выводит получившуюся строку.
Без точки получается просто ошибка:
echo $sum "\n";
здесь PHP после $sum ждет точку с запятой, обозначающую конец команды, а ее нет. Вот и ошибка. У echo синтаксис примерно такой:
echo <значение>;
Написать 2 значения через пробел нельзя.
Кроме точки, ты бы мог использовать подстановку переменных в строку: http://php.net/manual/ru/language.types.string.php#language.types.string.parsing
echo "$sum\n";
Есть два массива. Используя их значения, нужно получить id-шники через БД.
Далее, нужно запилить ссылки с комбинациями id-шников, полученных от БД.
В чем трудность:
Если я пытаюсь использовать этот код для создания запроса и передачи его результата в переменную, то записывается только последнее значение не то чтобы местный анон не догадался бы, но это скорее я пытаюсь объяснить, что не полный дурак
https://ideone.com/w4CJWC
Внимание вопрос: как мне запилить массив с присвоением результата запроса?
Или же просто: как мне подружить цикл for для создания массива с foreach, через который я буду выводить содержимое массива?
Премного благодарен.
Мне кажется или стоит добавить такой способ создания массива из массива в учебник?
И ещё:
$countrysId[] - это массив состоящий из таблиц взятых из БД.
Я и раньше с трудом понимал, как работает логика цикла
while ($line = mysql_fetch_array($countrysId, MYSQL_BOTH)
Пока значение переменной не равно нулю, делай что-то?
То теперь я не представляю, как можно вытащить значения из массива таблиц.
Я попробовал вот что https://ideone.com/aq6gtM , но в результате нихера.
КАК!? КАК СДЕЛАТЬ ТАК ЧТОБЫ СЛОГИ ВЫСТРАИВАЛИСЬ БЛЯТЬ В СЛОВО!? КАК СДЕЛАТЬ ЭТО!?
Я что только не пробовал уже, помогите раздуплить, сука. Почему на этом http://archive-ipq-co.narod.ru/ сайте вашем нету ответов у задач? Ну ладно, остальные я пока осилил сам, но это просто завело меня в тупик. Слишком сложно, сука, слишком сложно! Я уже 2 часа сижу как аутист, пялюсь в экран и нихуя не выходит. Какую хуйню только не пытался выдумать, а постоянно какая-то ебала в результате, а не слоги в ряд. Помогите! Как решить эту задачу?
Тебе надо из нескольких строк получить одну, то есть сложить их. Это называют буржуйским словом "конкатенация". Гугл по запросу "конкатенация строк php" выдаст все что нужно.
А как из всех добавить в переменную "$name"? Эта задача стопудова так решается, все слоги из одного массива.
>из всех
Их всех я имел ввиду. Все эти ебучие слоги сначала нужно записать в переменную Нейм, так в условии задачи сказано, а я не знаю блять каким образом это сделать так, дабы всё работало в итоге.
Лах.
http://php.net/manual/ru/function.implode.php
Предлагаю ОПу запилить первым делом гайд: как пользоваться поисковыми системами.
Ну блин, ну в задании же написано.
Собрать одну большую строку (имя) из кусочков (слогов) можно несколькими способами:
Создать переменную и положить в нее пустую строку ($string = '';). Затем на каждом шаге цикла «приклеивать» к ней новый кусочек: $string = $string . $piece; или $string .= $piece; Точка — это оператор, склеивающий («конкатенирующий») 2 строки вместе. Оператор .= надо писать слитно, без пробела.
Создать переменную, поместить в нее пустой массив. На каждом шаге добавлять в массив новый слог. В конце склеить слоги в массиве в одну строку с помощью implode.
Пока ждал ответа, пришел к выводу, что я неправильно все делал.
Надо было перебирать таблицы в foreach и уже их подставлять в while.
Казалось бы, решение найдено!
Но нет. Выводится какой-то бесконечный массив.
foreach ($countrysId as $x=>$table){
while ($line = mysql_fetch_array($table, MYSQL_BOTH)) {
print_r ($line);
}
}
foreach ($countrysId as $x=>$table){
while ($line = mysql_fetch_array($table, MYSQL_NUM)) {
foreach ($line as $s=>$a){
echo "$a\n";
}
}
}
Да, вывел. У меня там порядок чисел от 1 до 200.
Ну что ж, у меня неверное значение приходило!
Тогда такой вопрос:
$str_sql_query = "SELECT id FROM dbCountries WHERE name LIKE '%$count%' OR alias LIKE '%$count%' ";
foreach ($first as $count){
$countrysId[] = mysql_query($str_sql_query, $link);
}
foreach ($second as $cit){
$str_sql_query = "SELECT id FROM dptCities WHERE name LIKE '%$cit%' OR synonymus LIKE '%$cit%' ";
$citiesId[] = mysql_query($str_sql_query, $link);
}
Я правильно понимаю, что $str_sql_query - это просто устоявшееся название переменной?
Алсо, в этом коде в каждом цикле foreach правильно указано, чтобы использовалось свое выражение SQL-запроса?
foreach ($countrysId as $x=>$table){
while ($line = mysql_fetch_array($table, MYSQL_NUM)) {
foreach ($line as $s=>$a){
echo "$a\n";
}
}
}
Да, вывел. У меня там порядок чисел от 1 до 200.
Ну что ж, у меня неверное значение приходило!
Тогда такой вопрос:
$str_sql_query = "SELECT id FROM dbCountries WHERE name LIKE '%$count%' OR alias LIKE '%$count%' ";
foreach ($first as $count){
$countrysId[] = mysql_query($str_sql_query, $link);
}
foreach ($second as $cit){
$str_sql_query = "SELECT id FROM dptCities WHERE name LIKE '%$cit%' OR synonymus LIKE '%$cit%' ";
$citiesId[] = mysql_query($str_sql_query, $link);
}
Я правильно понимаю, что $str_sql_query - это просто устоявшееся название переменной?
Алсо, в этом коде в каждом цикле foreach правильно указано, чтобы использовалось свое выражение SQL-запроса?
>это просто устоявшееся название переменной
Да хуй его знает, как там было в девяностые.
Ты физически не можешь воспользоваться PDО? Строчек столько же, возможности — шире.
Просто прочти например http://phpfaq.ru/pdo (просто прочти, 15 минут!).
>правильно указано, чтобы использовалось свое выражение
Определи свою цель.
Не читал что там в условии, но первое что приходит на ум: вырезать все не-буквы, пересобрать строку, начиная с конца и сравнить с первой. Одинаковые — палиндром. (Наверно есть и лучше решение).
берешь массив и начинаешь сравнивать элементы у одного индекс i у второго ленгтх-и
>>16679
Вот такой вариант. А можно ссылку на задачу?
http://sandbox.onlinephpfunctions.com/code/10a83b5d7f2989965990706ed950cfd1f1c8ba10
Квадриплу отвечает Александр Друзь (музыка вноса черного ящика):
Ошибка 1:
Для работы с русскими символами нужно использовать кодировку utf-8.
Ты обращаешься к символу строки $text2[$i], что даст тебе 1 байт из этой строки (PHP работает со строкой, как с последовательностью байт, чем она и является), но в кодировке utf-8 символ кодируется 2-мя байтами. Чтобы получить n-ный символ из utf-8 строки:
mb_substr($str, $n, 1)
А, тут подразумевается совершенно другое решение, ну и пох. === это строгое сравнение:
$a === $b(Тождественно равно)TRUE если $a равно $b и имеет тот же тип.
Так-с.
Я попробовал написать альтернативную версию своего кода с POD.
https://ideone.com/ZKeXeW
На строке с SQL-запросом все ломается.
Я проверил, сам POD на серваке подключен.
> Создаётся командами типа make:controller. Поудаляю
Только сначала лучше разобраться, почему - может, есть какая-то выгода.
> Подсмотрел у knpuniverse. Без подчеркивания - это страница, с подчеркиванием - какой-то элемент: форма, модуль, и т.п. По-моему удобно. Да и в библиотеках такое встречал (вроде в EasyAdmin)
Ок, дело вкуса, хотя мне не очень нравится.
>> "{{ path('tests', {'tag': tag.name}) }}"
>> Вот это мне не нравится. Разве не лучше было бы написать getTestsByTagUrl(tag)? Так мы собираем код генерации URL в одном месте, а не размазываем по шаблонам, получаем тайп-хинты, можем делать дополнительные проверки. Можем как-то централизованно влиять на генерацию URL.
> Че-то я не понял, о чем ты
Чтобы вывести ссылку, ты пишешь в шаблоне {{ path(...) }} . Вместо этого можно сделать класс UrlGenerator, в нем методы вроде getTestsByTagUrl(Tag $tag): string. И использовать их. Выгоды:
- убираем дублирование кода, если надо что-то поменять, то меняем в одном месте, а не в 10 местах в шаблонах
- можно делать проверки
- можно делать тайп-хинты
- можно делать любую логику
- можно исправлять проблемы стандартного генератора URL, который неудачно спроектирован и в cli может генерировать ссылки с localhost вместо домена.
>> По переменным окружения - не стоит ли добавить им уникальный префикс вроде TH_..., чтобы они были гарантированно уникальными?
> И тут тоже не понял, о каких переменных ты говоришь
Переменные окружения в env.dist - больше их вроде нигде нету.
> А вот в routing.yaml у меня стоит strict_requirements: ~ и я не знаю, что означает тильда
https://stackoverflow.com/questions/8667766/what-does-mean-in-the-yml-configuration-file-in-symfony-2
http://yaml.org/type/null.html
> Но в принципе, я не понимаю, что плохого в присваивании внутри if
По моему, плохо то, что смешивается 2 действия в одной строке: создание переменной и проверка условия. Если ты быстро просматриваешь код и ищешь, где задается переменная, то ты скорее всего будешь искать строку вроде $x = ..., а на if сразу можно не обратить внимания, понадобится чуть больше времени. Удобнее, когда одна строка содержит одно действие и понятно, что строка, начинающаяся с if, не меняет ничего, а только проверяет какое-то условие.
Тут можно задать ответный вопрос, а зачем упаковывать 2 действия в одну строку? Ты пишешь слишком большие функции и пытаешься их таким образом сделать компактнее?
>> Что-то выглядит как костыль. Значение в форму в контроллере прописать нельзя?
> Я долго искал, как это реализовать. В итоге нашел вариант переопределить поле: $form->add('search', null, ['data' => $searchString]);
> Но меня ждал облом: You cannot add children to a submitted form
> Как переопределить аттрибут поля, а не всё поле целиком, я найти не смог. Но что-то мне подсказывает, что такая возможность должна быть
Symfony Forms сложные, но я бы советовал найти время, прочесть документацию, а затем изучить код, рисуя на листочке диаграмму классов. Если ты будешь понимать, какие там есть классы, как они связаны, то сможешь понять, как решить ту или иную задачу, связанную с формами. Я готов подсказать, если что-то непонятно.
Форма там состоит из дерева объектов, реализующих FormInterface ( https://github.com/symfony/form/blob/master/FormInterface.php ). Один объект FormInterface может представлять либо отдельное поле, либо представлять форму (или просто группу полей) и содержать в себе коллекцию дочерних объектов FormInterface.
В коде можно увидеть, что FormInterface реализует ArrayAccess (описан в мануале), а также содержит метод get($name). Таким образом, имея форму, мы можем получить ее поле с помощью $form->get('field') либо $form['field'].
Имея FormInterface, представляющий поле, мы можем получить или задать его значение с помощью методов setData/getData/getNormData/getViewData. Чем они отличаются, можно найти в документации или коде.
Я думаю, тебе стоит изучить компонент форм и тогда ты так же легко, как и я, мог бы получить ответ на вопрос "как задать значение поля в форме".
Ну и в данном случае, у тебя там в контроллере ( https://github.com/TheSidSpears/test_hub/blob/master/src/Controller/TestController.php ) есть вызов $form->handleRequest($request); который, скорее всего, принимает данные из $request->query и переносит их в поля формы. Так что код, меняющий атрибут value в шаблоне, вообще не требуется.
> В итоге нашел вариант переопределить поле: $form->add
Это не переопределение, а добавление еще одного поля.
> А для того, чтобы в миграциях автоматически проставлялась верная кодировка, мне пришлось добавить doctrine.dbal.default_table_options.charset: utf8mb4 и doctrine.dbal.default_table_options.collate: utf8mb4_unicode_ci, не смотря на то, что уже стоит doctrine.dbal.charset: utf8mb4
Ну, utf8 - это неполноценный урезанный вариант UTF-8, и смысла особого ее использовать нет, если только ты не желаешь сэкономить место в индексах. Если доктрина ее плохо поддерживает, то либо ты не разобрался в ней (надо разобраться), либо это баг в доктрине (надо зарепортить или посмотреть, может уже зарепортили). Либо в DoctrineBundle (который подключает Доктрину к Симфони).
У тебя в конфиге mysql (my.ini) по умолчанию какая кодировка стоит? utf8 или utf8mb4? И какая кодировка стоит у базы данных? Может в этом проблема?
Если есть возможность, глянь код Doctrine/DoctrineBundle и посмотри, как там определяется кодировка.
> У меня короче не получилось
Ну, там не требуется вставлять имя класса, можно писать
SELECT t FROM AppBundle:Test t
ORDER BY ...
По моему, тут получается меньше стрелок, скобок, кавычек и за счет этого код выходит читабельнее. Разве нет? Может это конечно, только мне так кажется, но мне читать DQL проще чем парсить все эти скобки и кавычки, особенно, когда там идут джойны. Тут например https://github.com/TheSidSpears/test_hub/blob/master/src/Repository/TestRepository.php#L45 DQL мне кажется был бы более читабельный, чем собирать в уме запрос по кусочкам.
По коду.
Не хватает README с кратким описанием проекта, как его установить, как запускать тесты и тд.
> Создаётся командами типа make:controller. Поудаляю
Только сначала лучше разобраться, почему - может, есть какая-то выгода.
> Подсмотрел у knpuniverse. Без подчеркивания - это страница, с подчеркиванием - какой-то элемент: форма, модуль, и т.п. По-моему удобно. Да и в библиотеках такое встречал (вроде в EasyAdmin)
Ок, дело вкуса, хотя мне не очень нравится.
>> "{{ path('tests', {'tag': tag.name}) }}"
>> Вот это мне не нравится. Разве не лучше было бы написать getTestsByTagUrl(tag)? Так мы собираем код генерации URL в одном месте, а не размазываем по шаблонам, получаем тайп-хинты, можем делать дополнительные проверки. Можем как-то централизованно влиять на генерацию URL.
> Че-то я не понял, о чем ты
Чтобы вывести ссылку, ты пишешь в шаблоне {{ path(...) }} . Вместо этого можно сделать класс UrlGenerator, в нем методы вроде getTestsByTagUrl(Tag $tag): string. И использовать их. Выгоды:
- убираем дублирование кода, если надо что-то поменять, то меняем в одном месте, а не в 10 местах в шаблонах
- можно делать проверки
- можно делать тайп-хинты
- можно делать любую логику
- можно исправлять проблемы стандартного генератора URL, который неудачно спроектирован и в cli может генерировать ссылки с localhost вместо домена.
>> По переменным окружения - не стоит ли добавить им уникальный префикс вроде TH_..., чтобы они были гарантированно уникальными?
> И тут тоже не понял, о каких переменных ты говоришь
Переменные окружения в env.dist - больше их вроде нигде нету.
> А вот в routing.yaml у меня стоит strict_requirements: ~ и я не знаю, что означает тильда
https://stackoverflow.com/questions/8667766/what-does-mean-in-the-yml-configuration-file-in-symfony-2
http://yaml.org/type/null.html
> Но в принципе, я не понимаю, что плохого в присваивании внутри if
По моему, плохо то, что смешивается 2 действия в одной строке: создание переменной и проверка условия. Если ты быстро просматриваешь код и ищешь, где задается переменная, то ты скорее всего будешь искать строку вроде $x = ..., а на if сразу можно не обратить внимания, понадобится чуть больше времени. Удобнее, когда одна строка содержит одно действие и понятно, что строка, начинающаяся с if, не меняет ничего, а только проверяет какое-то условие.
Тут можно задать ответный вопрос, а зачем упаковывать 2 действия в одну строку? Ты пишешь слишком большие функции и пытаешься их таким образом сделать компактнее?
>> Что-то выглядит как костыль. Значение в форму в контроллере прописать нельзя?
> Я долго искал, как это реализовать. В итоге нашел вариант переопределить поле: $form->add('search', null, ['data' => $searchString]);
> Но меня ждал облом: You cannot add children to a submitted form
> Как переопределить аттрибут поля, а не всё поле целиком, я найти не смог. Но что-то мне подсказывает, что такая возможность должна быть
Symfony Forms сложные, но я бы советовал найти время, прочесть документацию, а затем изучить код, рисуя на листочке диаграмму классов. Если ты будешь понимать, какие там есть классы, как они связаны, то сможешь понять, как решить ту или иную задачу, связанную с формами. Я готов подсказать, если что-то непонятно.
Форма там состоит из дерева объектов, реализующих FormInterface ( https://github.com/symfony/form/blob/master/FormInterface.php ). Один объект FormInterface может представлять либо отдельное поле, либо представлять форму (или просто группу полей) и содержать в себе коллекцию дочерних объектов FormInterface.
В коде можно увидеть, что FormInterface реализует ArrayAccess (описан в мануале), а также содержит метод get($name). Таким образом, имея форму, мы можем получить ее поле с помощью $form->get('field') либо $form['field'].
Имея FormInterface, представляющий поле, мы можем получить или задать его значение с помощью методов setData/getData/getNormData/getViewData. Чем они отличаются, можно найти в документации или коде.
Я думаю, тебе стоит изучить компонент форм и тогда ты так же легко, как и я, мог бы получить ответ на вопрос "как задать значение поля в форме".
Ну и в данном случае, у тебя там в контроллере ( https://github.com/TheSidSpears/test_hub/blob/master/src/Controller/TestController.php ) есть вызов $form->handleRequest($request); который, скорее всего, принимает данные из $request->query и переносит их в поля формы. Так что код, меняющий атрибут value в шаблоне, вообще не требуется.
> В итоге нашел вариант переопределить поле: $form->add
Это не переопределение, а добавление еще одного поля.
> А для того, чтобы в миграциях автоматически проставлялась верная кодировка, мне пришлось добавить doctrine.dbal.default_table_options.charset: utf8mb4 и doctrine.dbal.default_table_options.collate: utf8mb4_unicode_ci, не смотря на то, что уже стоит doctrine.dbal.charset: utf8mb4
Ну, utf8 - это неполноценный урезанный вариант UTF-8, и смысла особого ее использовать нет, если только ты не желаешь сэкономить место в индексах. Если доктрина ее плохо поддерживает, то либо ты не разобрался в ней (надо разобраться), либо это баг в доктрине (надо зарепортить или посмотреть, может уже зарепортили). Либо в DoctrineBundle (который подключает Доктрину к Симфони).
У тебя в конфиге mysql (my.ini) по умолчанию какая кодировка стоит? utf8 или utf8mb4? И какая кодировка стоит у базы данных? Может в этом проблема?
Если есть возможность, глянь код Doctrine/DoctrineBundle и посмотри, как там определяется кодировка.
> У меня короче не получилось
Ну, там не требуется вставлять имя класса, можно писать
SELECT t FROM AppBundle:Test t
ORDER BY ...
По моему, тут получается меньше стрелок, скобок, кавычек и за счет этого код выходит читабельнее. Разве нет? Может это конечно, только мне так кажется, но мне читать DQL проще чем парсить все эти скобки и кавычки, особенно, когда там идут джойны. Тут например https://github.com/TheSidSpears/test_hub/blob/master/src/Repository/TestRepository.php#L45 DQL мне кажется был бы более читабельный, чем собирать в уме запрос по кусочкам.
По коду.
Не хватает README с кратким описанием проекта, как его установить, как запускать тесты и тд.
По поводу тестов https://github.com/TheSidSpears/test_hub/blob/master/tests/Entity/TestEntityTest.php
Конечно, у тебя пока мало что можно протестировать чисто юнит-тестами, репозитории нужно тестировать с использованием БД, а контроллеры/вид - с использованием приемочного тестирования без или с использованием эмулятора браузера. Но рассмотрим то, что есть.
Тесты обычно пишутся на основе требований, ТЗ. Ты тестируешь класс Entity\Test - я вижу, что ты сделал несколько методов-сценариев, но, мне кажется, лучше было бы составить список требований (которым должен соответствовать класс) и писать по методу на требование. Тогда по результатам прогона теста сразу видно, какие требования не выполняются.
Подумаем, какие требования мы предъявим к классу Entity\Test? Я не буду писать требования вроде "объект теста должен запоминать присвоенное тесту название", так как это спорная вещь, эффективно ли тестировать простые геттеры/сеттеры.
Например, у класса есть функционал хранения и вычсиления числа попыток. Отлично, можно составить требования:
- у нового созданного теста число попыток должно быть равно 0
- при увеличении числа удачных попыток оно должно увеличиться, как и общее число попыток
- то же для неудачных попыток
Далее, можно добавить еще такие требования:
- к тесту можно добавить новый вопрос
- нельзя дважды добавить один и тот же вопрос
- можно добавить тег
- можно удалить тег
И уже на основе этих требований мы пишем методы, и даем им понятные имена, и тестируем, выполняет ли класс это требование.
Вот как может выглядеть самый простой тест для требования "можно добавить тег":
public function testCanAddTagsForTest()
{
$test = new Test;
$tag1 = new Tag;
$test->addTag($tag1);
}
Этот тест уже проверяет, что метод addTag не падает на ровном месте и таким образом приносит какую-то пользу. Но, конечно, мы его можем улучшить, добавив проверку, что после добавления тега мы можем получить его назад:
$test->addTag($tag1);
$tags = $test->getTags();
$this->assertTrue($tags->contains($tag1));
Конечно, тут в классе почти нет никакой логики, и по сути мы занимаемся тестированием геттеров/сеттеров. То есть пишем много тестов, и почти ничего не тестируем. Надо бы настроить проведение тестов репозиториев и тестов контроллеров (либо дергать контроллеры напрямую, либо через отправку HTTP запросов на сервер, первое конечно проще и сойдет для начала, но не позволит проверять JS функционал).
У Симфони есть куцая статья https://symfony.com/doc/current/testing/database.html и первый вариант (mock entity manager) я не советую делать, это будут очень некачественные и хрупкие тесты.
Еще замечания по тестам:
> $this->assertNull($test->getName());
Стоит ли это тестировать? Ты по сути тестируешь требование "у нового теста name должно быть null", но что, если мы завтра поменяем его на '' или 'Новый тест'? Стоит ли закладывать такое требование, что название теста по умолчанию должно равняться null?
> $this->assertNull($test->getId());
Тоже непонятен смысл делать такое требование. Ведь мы можем в теории перейти на генерацию id на стороне PHP при создании объекта. Это никак не должно сломать код, зачем тогда в тесте запрещать это? Ты скорее всего ведь не хотел ставить такое требование, а просто не очень понял, как писать тесты?
> $this->assertNull($test->getFailedAttempts());
Наверно значение по умолчанию должно быть 0?
> $this->assertInstanceOf(ArrayCollection::class, $test->getQuestions());
Вот здесь уже ошибка. Так как при загрузке из БД доктрина инжектит туда PersistentCollection, и тайп-хинтить тут надо интерфейс Collection (не помню неймспейс).
Также, тут ты по сути занимаешься дублированием тайп-хинтов, проще поставить тайп-хинт на результат функции.
И я не очень понимаю, зачем вообще закладывать в тест, какого класса будет коллекция.
> $this->assertCount(0, $test->getQuestions());
А вот это можно оставить.
> Set number of failed attempts for instantly created item
> public function setFailedAttempts($failedAttempts)
Вот такого лучше избегать. Увеличивать число попыток в тесте лучше тем же способом, каким это будет делать приложение, а не делать костыли там, где без них легко обойтись.
Более того, смотри, ты добавил метод setFailedAttempts для тестов, а затем еще и написал тест для него. Ты тесты ради тестов пишешь, получается? Так делать не надо, это просто трата времени. Тестировать надо тот код, который будет использовать приложение.
> $test->setSuccessAttempts($num1 + 20);
В тестах не стоит делать сложные вычисления, стоит их максимально упрощать. То есть была 1 попытка, мы добавили еще одну, стало две (без переменных). Так и читать тест проще, и тебе не придется дублировать код из тестируемого класса (при этом есть риск сделать одну и ту же ошибку, например, неправильно написать формулу в обоих случаях).
https://github.com/TheSidSpears/test_hub/blob/master/src/Repository/TestRepository.php
Вот тут я уже вижу логику, ее было бы хорошо протестировать.
Если ты используешь PHP7, ставь тайп хинты на возвращаемые значения функций.
> public function findByTag(Tag $tag){
Вообще, Доктрина генерирует методы finxByXXX, findOneByXXX, они тут не подошли бы?
> findByNameOrTagInclusions
Не лучше ли search или searchByKeyword или как-то так?
Я тут еще хотел посоветовать использовать faker в fixtures, но погуглил, и увидел, что он там уже используется (через alice), интересно. не знал про такую штуку. Ну прекрасно, если вдруг не знаком с ним, изучи faker, пригодится.
https://github.com/TheSidSpears/test_hub/blob/master/templates/base.html.twig#L22
> {% if isMainRoute is defined and isMainRoute == true %}
Вот это мне не нравится. У тебя переменная может быть передана, а может не быть. Как писать надежный код в такой ситуации?
https://github.com/TheSidSpears/test_hub/blob/master/templates/tests/by_tag_list.html.twig
Проверь, соответствует ли имя шаблона гайдлайнам Симфони (я сам не помню).
https://github.com/TheSidSpears/test_hub/blob/master/templates/tests/list.html.twig#L34
Это костыли, нужна нормальная функция-хелпер для склонения чисел, а еще лучше сразу использовать синтаксис для переводимых (локализумых) строк, так как в разных языках правила выбора формы слов разные.
> $em = $this->getDoctrine()->getManager();
> $tests = $em->getRepository(Test::class)
Если это у тебя часто встречается в контроллерах, стоит добавить метод для получения репозитория напрямую. Либо использовать DI для контроллеров (больше писанины).
> public function tagList(Request $request, PaginatorInterface $paginator)
Почему пагинатор передается в аргументы метода контроллера? Это такой DI?
Хорошо бы предусмотреть выдачу 404 для слишком больших номеров страниц, начиная со 2.
> $searchString = $form->getData()['text'];
лучше $form->get('text')->getData()
> if ($form->isSubmitted() && $form->isValid()) {
> $searchString = $form->getData()['text'];
> } else {
> $searchString = $request->query->get('text');
> }
А зачем else?
> } else {
> //todo customize error pages
> throw $this->createNotFoundException('There is nothing to search');
лучше выводить просьбу ввести ключевое слово
https://github.com/TheSidSpears/test_hub/blob/master/src/Controller/TagController.php
тут findAll не приводит к выборке всех записей из БД?
По поводу тестов https://github.com/TheSidSpears/test_hub/blob/master/tests/Entity/TestEntityTest.php
Конечно, у тебя пока мало что можно протестировать чисто юнит-тестами, репозитории нужно тестировать с использованием БД, а контроллеры/вид - с использованием приемочного тестирования без или с использованием эмулятора браузера. Но рассмотрим то, что есть.
Тесты обычно пишутся на основе требований, ТЗ. Ты тестируешь класс Entity\Test - я вижу, что ты сделал несколько методов-сценариев, но, мне кажется, лучше было бы составить список требований (которым должен соответствовать класс) и писать по методу на требование. Тогда по результатам прогона теста сразу видно, какие требования не выполняются.
Подумаем, какие требования мы предъявим к классу Entity\Test? Я не буду писать требования вроде "объект теста должен запоминать присвоенное тесту название", так как это спорная вещь, эффективно ли тестировать простые геттеры/сеттеры.
Например, у класса есть функционал хранения и вычсиления числа попыток. Отлично, можно составить требования:
- у нового созданного теста число попыток должно быть равно 0
- при увеличении числа удачных попыток оно должно увеличиться, как и общее число попыток
- то же для неудачных попыток
Далее, можно добавить еще такие требования:
- к тесту можно добавить новый вопрос
- нельзя дважды добавить один и тот же вопрос
- можно добавить тег
- можно удалить тег
И уже на основе этих требований мы пишем методы, и даем им понятные имена, и тестируем, выполняет ли класс это требование.
Вот как может выглядеть самый простой тест для требования "можно добавить тег":
public function testCanAddTagsForTest()
{
$test = new Test;
$tag1 = new Tag;
$test->addTag($tag1);
}
Этот тест уже проверяет, что метод addTag не падает на ровном месте и таким образом приносит какую-то пользу. Но, конечно, мы его можем улучшить, добавив проверку, что после добавления тега мы можем получить его назад:
$test->addTag($tag1);
$tags = $test->getTags();
$this->assertTrue($tags->contains($tag1));
Конечно, тут в классе почти нет никакой логики, и по сути мы занимаемся тестированием геттеров/сеттеров. То есть пишем много тестов, и почти ничего не тестируем. Надо бы настроить проведение тестов репозиториев и тестов контроллеров (либо дергать контроллеры напрямую, либо через отправку HTTP запросов на сервер, первое конечно проще и сойдет для начала, но не позволит проверять JS функционал).
У Симфони есть куцая статья https://symfony.com/doc/current/testing/database.html и первый вариант (mock entity manager) я не советую делать, это будут очень некачественные и хрупкие тесты.
Еще замечания по тестам:
> $this->assertNull($test->getName());
Стоит ли это тестировать? Ты по сути тестируешь требование "у нового теста name должно быть null", но что, если мы завтра поменяем его на '' или 'Новый тест'? Стоит ли закладывать такое требование, что название теста по умолчанию должно равняться null?
> $this->assertNull($test->getId());
Тоже непонятен смысл делать такое требование. Ведь мы можем в теории перейти на генерацию id на стороне PHP при создании объекта. Это никак не должно сломать код, зачем тогда в тесте запрещать это? Ты скорее всего ведь не хотел ставить такое требование, а просто не очень понял, как писать тесты?
> $this->assertNull($test->getFailedAttempts());
Наверно значение по умолчанию должно быть 0?
> $this->assertInstanceOf(ArrayCollection::class, $test->getQuestions());
Вот здесь уже ошибка. Так как при загрузке из БД доктрина инжектит туда PersistentCollection, и тайп-хинтить тут надо интерфейс Collection (не помню неймспейс).
Также, тут ты по сути занимаешься дублированием тайп-хинтов, проще поставить тайп-хинт на результат функции.
И я не очень понимаю, зачем вообще закладывать в тест, какого класса будет коллекция.
> $this->assertCount(0, $test->getQuestions());
А вот это можно оставить.
> Set number of failed attempts for instantly created item
> public function setFailedAttempts($failedAttempts)
Вот такого лучше избегать. Увеличивать число попыток в тесте лучше тем же способом, каким это будет делать приложение, а не делать костыли там, где без них легко обойтись.
Более того, смотри, ты добавил метод setFailedAttempts для тестов, а затем еще и написал тест для него. Ты тесты ради тестов пишешь, получается? Так делать не надо, это просто трата времени. Тестировать надо тот код, который будет использовать приложение.
> $test->setSuccessAttempts($num1 + 20);
В тестах не стоит делать сложные вычисления, стоит их максимально упрощать. То есть была 1 попытка, мы добавили еще одну, стало две (без переменных). Так и читать тест проще, и тебе не придется дублировать код из тестируемого класса (при этом есть риск сделать одну и ту же ошибку, например, неправильно написать формулу в обоих случаях).
https://github.com/TheSidSpears/test_hub/blob/master/src/Repository/TestRepository.php
Вот тут я уже вижу логику, ее было бы хорошо протестировать.
Если ты используешь PHP7, ставь тайп хинты на возвращаемые значения функций.
> public function findByTag(Tag $tag){
Вообще, Доктрина генерирует методы finxByXXX, findOneByXXX, они тут не подошли бы?
> findByNameOrTagInclusions
Не лучше ли search или searchByKeyword или как-то так?
Я тут еще хотел посоветовать использовать faker в fixtures, но погуглил, и увидел, что он там уже используется (через alice), интересно. не знал про такую штуку. Ну прекрасно, если вдруг не знаком с ним, изучи faker, пригодится.
https://github.com/TheSidSpears/test_hub/blob/master/templates/base.html.twig#L22
> {% if isMainRoute is defined and isMainRoute == true %}
Вот это мне не нравится. У тебя переменная может быть передана, а может не быть. Как писать надежный код в такой ситуации?
https://github.com/TheSidSpears/test_hub/blob/master/templates/tests/by_tag_list.html.twig
Проверь, соответствует ли имя шаблона гайдлайнам Симфони (я сам не помню).
https://github.com/TheSidSpears/test_hub/blob/master/templates/tests/list.html.twig#L34
Это костыли, нужна нормальная функция-хелпер для склонения чисел, а еще лучше сразу использовать синтаксис для переводимых (локализумых) строк, так как в разных языках правила выбора формы слов разные.
> $em = $this->getDoctrine()->getManager();
> $tests = $em->getRepository(Test::class)
Если это у тебя часто встречается в контроллерах, стоит добавить метод для получения репозитория напрямую. Либо использовать DI для контроллеров (больше писанины).
> public function tagList(Request $request, PaginatorInterface $paginator)
Почему пагинатор передается в аргументы метода контроллера? Это такой DI?
Хорошо бы предусмотреть выдачу 404 для слишком больших номеров страниц, начиная со 2.
> $searchString = $form->getData()['text'];
лучше $form->get('text')->getData()
> if ($form->isSubmitted() && $form->isValid()) {
> $searchString = $form->getData()['text'];
> } else {
> $searchString = $request->query->get('text');
> }
А зачем else?
> } else {
> //todo customize error pages
> throw $this->createNotFoundException('There is nothing to search');
лучше выводить просьбу ввести ключевое слово
https://github.com/TheSidSpears/test_hub/blob/master/src/Controller/TagController.php
тут findAll не приводит к выборке всех записей из БД?
Я думаю, не все хотят проверку обновлений по умолчанию, так как она может замедлять работу программы. Потому там и предусмотрена команда self-update. В автоматизированных скриптах, которые используются для запуска тестов (например для Travis CI) эту команду просто вписывают в скрипт, чтобы тестирование всегда проходило на новейшей версии.
>>13910
Использовать просто preg_match, оно ищет только первое совпадение с регуляркой, а не все. Также можно посмотреть мануал по preg_match_all, там есть опции.
>>13902
У тебя там куча ошибок, например, круглые скобки не сбалансированы:
> $result = mysql_query($str_sql_query, $link))
Также, не подставляй переменные в SQL запрос, будет SQL инъекция: https://github.com/codedokode/pasta/blob/master/security/sql-injection.md
>>13811
> Два раза попались задачки из учебника Опа.
Вот видите, учебник вам может хоть где-то пригодиться.
>>13736
На другой странице есть какие-то CSS правила, влияющие на раскладку элементов. Или какие-то HTML элементы.
>>16760
Плейсхолдер :x вставляет не просто переданное значение, а экранирует в нем спецсимволы и добавляет кавычки вокруг него. Соответственно, надо писать LIKE :x.
Я думаю, не все хотят проверку обновлений по умолчанию, так как она может замедлять работу программы. Потому там и предусмотрена команда self-update. В автоматизированных скриптах, которые используются для запуска тестов (например для Travis CI) эту команду просто вписывают в скрипт, чтобы тестирование всегда проходило на новейшей версии.
>>13910
Использовать просто preg_match, оно ищет только первое совпадение с регуляркой, а не все. Также можно посмотреть мануал по preg_match_all, там есть опции.
>>13902
У тебя там куча ошибок, например, круглые скобки не сбалансированы:
> $result = mysql_query($str_sql_query, $link))
Также, не подставляй переменные в SQL запрос, будет SQL инъекция: https://github.com/codedokode/pasta/blob/master/security/sql-injection.md
>>13811
> Два раза попались задачки из учебника Опа.
Вот видите, учебник вам может хоть где-то пригодиться.
>>13736
На другой странице есть какие-то CSS правила, влияющие на раскладку элементов. Или какие-то HTML элементы.
>>16760
Плейсхолдер :x вставляет не просто переданное значение, а экранирует в нем спецсимволы и добавляет кавычки вокруг него. Соответственно, надо писать LIKE :x.
Также, обрати внимание, что execute не возвращает результат выполнения запроса, его надо извлекать из объекта PDOStatement ($stmt), используя его методы fetch.... Они описаны в мануале.
>>16763
Справедливо.
На самом деле, я там ещё одинарные кавычки поставил до и после плейсхолда.
Но к моему жопочтению надо относится с уважением! Я смог неправильно понять абзацы с подготовленными выражениями.
Я подумал, что можно, аки в пасте про жареный суп, хуярить массив в плейсхолд и система как-то сама справится.
В общем, я запилил своего монстра https://ideone.com/dUHfz5 и теперь хотел бы уточнить несколько вещей:
1.Я правильно сделал запрос с LIKE и двумя переменными?
2.Почему не выводится значения?
>>16768
Ох, прости, ОП, не заметил твоего ответа, пока писал свой.
Да, все указанное тобой попытался использовать.
И тогда задам вопрос, пользуясь возможностью: если PDO дает мощную защиту от SQL-инъекций, позволяет спокойно переносить программу с одного типа БД на другую и может сильно расширить функционал самой программы, то почему о нем достаточно редко вспоминают и во всех учебниках пишут, как делать прямые запросы?
Я в коде на ideon сделал ошибку.
Там так должно было быть написано:
foreach ($aza as $desk){
$desk = $stmt->fetchColumn();
var_dump($desk);
}
Хоть этот вариант и так, и так не работает и выводит только bool(false) .
http://sandbox.onlinephpfunctions.com/code/fd831e19928cf02fb83c390a4338668efd3c1116
Все равно не работает :(
Очевидно, что я обосрался где-то в цикле, но я не могу понять где.
Сори, я не могу с тобой, пусть ОП тебе отвечает. Только время потратил на тебя. Чтобы браться за пдо, нужно представлять хотя бы минимально, как с PHP работать, ты там такую чушь пишешь — это не незнание пдо, это незнание принципов работы языка вообще.
Ты вообще читал, что я тебе написал? Ошибка все еще на месте
>mb_substr($str, $n, 1)
>вместо $str[$n]
>В случае аякс запроса - конечно, редирект делать нет смысла, и надо отдавать ответ (правильный логин/пароль или нет). Обычно ответ отдается в формате JSON. Что касается авторизационной куки, есть 2 варианта - сервер может передавать ее с ответом как куку (в заголовке Set-Cookie) либо же в JSON-ответе, а клиент уже сам создает ее.
В случае с Silex мне нужно пилить собственный authentication provider, что бы получать ответ с ошибками или подтверждениями login/logout? Сейчас использую "form_login". В описании настроек есть success_handler и LogoutSuccessHandler. Но подключить LogoutSuccessHandler, не получается.
В доках по Symfony написано "adding a success_handler key and pointing it to a service id of a class that implements LogoutSuccessHandlerInterface".
Добавил в конфиг, в раздел 'logout' (пикрил)
'success_handler' => function () use ($app) {
return new CustomLogoutSuccessHandler();
}
Но продолжает использоваться DefaultLogoutSuccessHandler
Еще заметил, что названия настроек (key) фаервола немного отличаются, например в Symfony путь логаута в настройках "path" a в Silex "logout_path". Может быть в этом дело?
>Если ты хочешь делать полноценное REST API
Я делаю SPA приложение https://github.com/codedokode/pasta/blob/master/js/spa.md
Думаю разобраться в начале с обычной аутенфикацией с сессией и куками... А потом все остальное.
Справедливости ради, сам я не лез в PDO, ибо чувствовал, что мне и обычные запросы составлять сложно.
Зато, тебе будет урок. Ну и я кое-что новое узнал.
Я попробовал заменить русский палиндром на английский и мой код заработал. Я неправильно указал кодировку? Ну и цикл у меня в этот раз правильный, надеюсь?
http://sandbox.onlinephpfunctions.com/code/d68bff5b96bf3a3d5c606713c2ad4fa774254370
сделал так и CustomLogoutSuccessHandler заработал:
$app['security.authentication.logout_handler.admin'] = function () {
return new CustomLogoutSuccessHandler();
};
Судя по исходнику SecurityServiceProvider в Silex по другому не получится назначить logout_handler?
https://github.com/silexphp/Silex-Providers/blob/d9b9e4f6bdd72af745444b4d71e59a55e5e10dbd/SecurityServiceProvider.php#L558
Я советую тебе пока отложить базы данных, попрактиковаться на базовых уроках, а когда дойдешь возвращаться сразу на PDО, пропустив mysql и mysqli, потому что они сами по себе отстают.
Это не смешно.
Основной алгоритм ты сделал верно. Осталось только причесать: например использовать "флаг" чтобы убрать выводы на каждом символе. И правильно брать символы из utf-8 строки:
http://sandbox.onlinephpfunctions.com/code/635504ff0951c21f68a07d1a47bf17bbe16c1602
Окей, спасибо!
Ну тут такое дело, что а)это было задание от руководителя я не погромист, просто "стремящийся" из саппорта б)я уже выполнил задачу за время прошедшее с моего последнего поста.
Но выполнил её с myqsl.
Так-то я продолжу содомизировать вторую версию кода с PDO. Сейчас попытаюсь приделать вывод исключения для своего запроса, чтобы понять, где проблема.
Книга ОП-а - самое то. Начинай с неё.
как это сделать? я добавляю header($this->setCustomHeaderBlahBlah()) в result.php, но он получается показывается как хедер ОТВЕТА, response header. а это полное говно. как-то возможно с формой передать заголовки?
Спасибо, друг, про шаблоны уже читаю.
Смотрел этот урок https://youtu.be/xihMCwARRpk и хотел чуть отойти от его идеи, и что бы не создавать на html руками каждый блок "@название категории [новейшее]", то хотел сделать генерацию этих блоков прям из БД циклом.
upd почитал, понял что без js невозможно это сделать. буду ajax-запрос слать кверями и там передавать нужные хедеры
Я сам только начинаю, но путем прочитывая кучи обсуждений на торрентах, нашел книгу, которую все считают лучшей: Мэтт Зандстра - PHP. Объекты, шаблоны и методики программирования
Просто мне кажется, использование этой "прокси-переменной" $а2, это лишнее нагромождение. Стопудова есть способ вывести значение удобней чем так, но я пока не додумался до этого. Так чё?
ох, пиздец.
Забейте, вопрос отменяется, до меня дошло.
>>16339
Сегодня опять взялся на php, в общем, запилил таки свою генерацию, надо было в запросе к бд во внешнем цикле указать id
> "SELECT * FROM `articles` WHERE `categorie_id` = " . $new['id'] ." ORDER BY `id` DESC LIMIT 4"
>>17049
Да, у него там мешанина в коде несется по полной, нет ооп итд, но за это говно поясняет вполне доступно.
"от профессионала" - от скромности не умрет. говнокод периода пхп4. это бывает, когда 10 лет говнякаешь лэндосы на фрилансе
ну и как бэ привет sql-инъекция. (сорян, что все в разных постах - не могу контролировать эмоции).
Хуясе ты господь, я уж и не думал что можно ещё кароче.
А как вы преобразуете закодированные base64 строки, для функций base64_decode и quoted_printable_decode нужно сперва убрать =?utf-8?B? и =?UTF-8?Q? вместе с ?= в конце строки, написал свою функцию конечно, но стало интересно это все так делают?
Ну или через десяток перезагрузок срабатывает.
>>17128
Ты не написал, где это делаешь? У себя локально, на хостинге? Какие правила кеширования прописаны в веб-сервере?
Попробуй очистить кеш в браузере или включить опцию не использовать кеш в инструментах разработчика (Ctrl + Shift + I, вкладка Network).
>>17094
Если это для разбора письма, то не надо делать это руками, а надо взять расширение или библиотеку для разбора писем. Погугли.
А в твоем примере - в письме ведь могут быть и другие варианты кодирования, ты их учел?
>>17049
Всем, кто не понял, где уязвимость в коде, читать урок https://github.com/codedokode/pasta/blob/master/security/sql-injection.md
Ну и вообще, этот код некачественный. Автор очень плохо знает PHP и я рекомендую не учиться у него.
>>17038
Только через AJAX.
Исключения специально выводить не надо, если ты работаешь локально, то включи display_errors = On в php.ini, чтобы они выводились на экран, если на продакшен-сервере, то выводить на экран ничего не нужно, а нужно найти логи ошибок PHP или Апача и посмотреть там.
>>16922
$text2[$i] берет $i-й байт строки, а не i-й символ, урок https://github.com/codedokode/pasta/blob/master/php/strings-utf8.md
Используй mb_substr.
>>16900
> Я делаю SPA приложение
Ну удачи. Пока никто его не сделал.
По поводу авторизации, выскажу свое личное мнение, что мне не нравится, как в симфони/силекс это сделано. Там почему-то информация о залогиненном пользователе хранится в контейнере. Это ненормально. Просто мысленный эксперимент: что, если у нас приложение обрабатывает 2 HTTP-запроса по очереди, не завершаясь, или даже 2 запроса параллельно (например, с использованием ReactPHP)? Это все не будет работать нормально. Я считаю, в контейнере не должно сохраняться ничего, относящееся к текущему запросу. Но это мое личное мнение.
> мне нужно пилить собственный authentication provider, что бы получать ответ с ошибками или подтверждениями login/logout?
Скорее всего. Тот, что form, не заточен на работу с аякс-запросами, а только на обычные формы.
По поводу аякса. Я тут кое-что нашел, можно это посмотреть:
- https://symfony.com/blog/new-in-symfony-3-3-json-authentication
- http://www.webtipblog.com/adding-an-ajax-login-form-to-a-symfony-project/
- http://symfony.com/doc/current/security/custom_authentication_provider.html (тут создание своего провайдера)
> Судя по исходнику SecurityServiceProvider в Silex по другому не получится назначить logout_handler?
Видимо, да. Он там ставит свой хендлер по умолчанию, и ты можешь его переопределить с помощью настройки security.authentication.logout_handler.admin. Только писать ее логичнее не где-то отдельно, а передавать как второй параметр в $app->register().
> В доках по Symfony написано "adding a success_handler key and pointing it to a service id of a class that implements LogoutSuccessHandlerInterface".
Это доки к чему? Если это https://symfony.com/doc/current/reference/configuration/security.html то это дока по Symfony SecurityBundle, то есть бандлу от Симфони. Который скорее всего является оберкой над Symfony Security Component.
Бандлы - это части фреймворка Симфони, они не подходя к Силекс и документация к ним тоже. Они интегрируют Компонент в контейнер, обеспечивают его настройку через конфиги и тд. Компоненты Симфони - это независимые библиотеки, которые можно использовать отдельно от Симфони. Я думаю, Силекс использует именно Security Component: https://symfony.com/doc/current/components/security.html (причем у меня ощущение, что часть документации там относится все равно к бандлу, а не к компоненту).
Код тут https://github.com/symfony/security
Соответственно надо смотреть код/доки по провайдеру Силекса и по компоненту, а не по бандлам от Симфони. И из этого делать вывод, как там что настраивается.
> Еще заметил, что названия настроек (key) фаервола немного отличаются, например в Symfony путь логаута в настройках "path" a в Silex "logout_path". Может быть в этом дело?
Это скорее всего из-за того что в Симфони это настройка бандла, а в Силексе это настройка провайдера. И они оказались разные.
Исключения специально выводить не надо, если ты работаешь локально, то включи display_errors = On в php.ini, чтобы они выводились на экран, если на продакшен-сервере, то выводить на экран ничего не нужно, а нужно найти логи ошибок PHP или Апача и посмотреть там.
>>16922
$text2[$i] берет $i-й байт строки, а не i-й символ, урок https://github.com/codedokode/pasta/blob/master/php/strings-utf8.md
Используй mb_substr.
>>16900
> Я делаю SPA приложение
Ну удачи. Пока никто его не сделал.
По поводу авторизации, выскажу свое личное мнение, что мне не нравится, как в симфони/силекс это сделано. Там почему-то информация о залогиненном пользователе хранится в контейнере. Это ненормально. Просто мысленный эксперимент: что, если у нас приложение обрабатывает 2 HTTP-запроса по очереди, не завершаясь, или даже 2 запроса параллельно (например, с использованием ReactPHP)? Это все не будет работать нормально. Я считаю, в контейнере не должно сохраняться ничего, относящееся к текущему запросу. Но это мое личное мнение.
> мне нужно пилить собственный authentication provider, что бы получать ответ с ошибками или подтверждениями login/logout?
Скорее всего. Тот, что form, не заточен на работу с аякс-запросами, а только на обычные формы.
По поводу аякса. Я тут кое-что нашел, можно это посмотреть:
- https://symfony.com/blog/new-in-symfony-3-3-json-authentication
- http://www.webtipblog.com/adding-an-ajax-login-form-to-a-symfony-project/
- http://symfony.com/doc/current/security/custom_authentication_provider.html (тут создание своего провайдера)
> Судя по исходнику SecurityServiceProvider в Silex по другому не получится назначить logout_handler?
Видимо, да. Он там ставит свой хендлер по умолчанию, и ты можешь его переопределить с помощью настройки security.authentication.logout_handler.admin. Только писать ее логичнее не где-то отдельно, а передавать как второй параметр в $app->register().
> В доках по Symfony написано "adding a success_handler key and pointing it to a service id of a class that implements LogoutSuccessHandlerInterface".
Это доки к чему? Если это https://symfony.com/doc/current/reference/configuration/security.html то это дока по Symfony SecurityBundle, то есть бандлу от Симфони. Который скорее всего является оберкой над Symfony Security Component.
Бандлы - это части фреймворка Симфони, они не подходя к Силекс и документация к ним тоже. Они интегрируют Компонент в контейнер, обеспечивают его настройку через конфиги и тд. Компоненты Симфони - это независимые библиотеки, которые можно использовать отдельно от Симфони. Я думаю, Силекс использует именно Security Component: https://symfony.com/doc/current/components/security.html (причем у меня ощущение, что часть документации там относится все равно к бандлу, а не к компоненту).
Код тут https://github.com/symfony/security
Соответственно надо смотреть код/доки по провайдеру Силекса и по компоненту, а не по бандлам от Симфони. И из этого делать вывод, как там что настраивается.
> Еще заметил, что названия настроек (key) фаервола немного отличаются, например в Symfony путь логаута в настройках "path" a в Silex "logout_path". Может быть в этом дело?
Это скорее всего из-за того что в Симфони это настройка бандла, а в Силексе это настройка провайдера. И они оказались разные.
Нормально, но по задумке он используется только в dev версии, а на продакшене его надо отключать через конфиг ради производительности (что имхо глуповато). Потому я бы советовал использовать if или сделать свой assert.
Что же касается assert из phpunit, то они вряд ли подходят для чего-то, кроме тестов.
>>16770
> если PDO дает мощную защиту от SQL-инъекций, позволяет спокойно переносить программу с одного типа БД на другую и может сильно расширить функционал самой программы, то почему о нем достаточно редко вспоминают и во всех учебниках пишут, как делать прямые запросы?
Потому, что это некачественный учебники 10-летней давности, написанные, когда не было PDO. Или их авторы до сих пор о нем не знают.
О PDO пишут, открой например:
- https://habrahabr.ru/post/137664/
- http://phptherightway.ru/#Базы_данных
Прочитай phptherightway и сравни с тем, что расскаызвают в твоем учебнике.
>>16769
Нет, неправильно. Твой код вообще бессмысленный, и как советуют выше, тебе надо начать с изучения языка PHP. Я приведу только один пример:
> $first = "%$first%";
> foreach ($first as $id => $x)
Как это по твоему должно работать? Ты перебираешь по очереди все буквы (байты, если говорить строго) из строки "%$first%" и для каждой буквы выполняешь SQL запрос?
Нужно понимать каждую строчку и каждый символ, иначе писать код не получится. Делать "по аналогии" с каким-то готовым кодом можно только если тебе надо поменять совсем чуть-чуть.
Если ты хочешь изучать PHP, я могу предложить свой учебник из ОП-поста. Там нет ничего про базы данных, но объясняется, как вообще писать программу на PHP, с нуля.
Нормально, но по задумке он используется только в dev версии, а на продакшене его надо отключать через конфиг ради производительности (что имхо глуповато). Потому я бы советовал использовать if или сделать свой assert.
Что же касается assert из phpunit, то они вряд ли подходят для чего-то, кроме тестов.
>>16770
> если PDO дает мощную защиту от SQL-инъекций, позволяет спокойно переносить программу с одного типа БД на другую и может сильно расширить функционал самой программы, то почему о нем достаточно редко вспоминают и во всех учебниках пишут, как делать прямые запросы?
Потому, что это некачественный учебники 10-летней давности, написанные, когда не было PDO. Или их авторы до сих пор о нем не знают.
О PDO пишут, открой например:
- https://habrahabr.ru/post/137664/
- http://phptherightway.ru/#Базы_данных
Прочитай phptherightway и сравни с тем, что расскаызвают в твоем учебнике.
>>16769
Нет, неправильно. Твой код вообще бессмысленный, и как советуют выше, тебе надо начать с изучения языка PHP. Я приведу только один пример:
> $first = "%$first%";
> foreach ($first as $id => $x)
Как это по твоему должно работать? Ты перебираешь по очереди все буквы (байты, если говорить строго) из строки "%$first%" и для каждой буквы выполняешь SQL запрос?
Нужно понимать каждую строчку и каждый символ, иначе писать код не получится. Делать "по аналогии" с каким-то готовым кодом можно только если тебе надо поменять совсем чуть-чуть.
Если ты хочешь изучать PHP, я могу предложить свой учебник из ОП-поста. Там нет ничего про базы данных, но объясняется, как вообще писать программу на PHP, с нуля.
>Какие правила кеширования прописаны в веб-сервере?
Никакие, я только вкатиться пытаюсь. XXAMP включил первые две строки.
Поясните за базы данных в php. Mysqli, pdo и прочие. Есть какая-то наиболее годная или всё они нормальны?
Тогда можно открыть средства разработчика в браузере, вкладку Network и отключить там где-то кеширование (а заодно проверить, какие заголовки отдает сервер). Или чистить кеш браузера руками.
mysqli и PDO это не БД и не СУБД, а библиотеки-клиенты для соединения с сервером СУБД. Я бы посоветовал PDO.
>Там почему-то информация о залогиненном пользователе хранится в контейнере
Ты имеешь ввиду service container ?
https://symfony.com/doc/3.4/service_container.html
>в контейнере не должно сохраняться ничего, относящееся к текущему запросу.
сохранять сессию в БД?
>По поводу аякса. Я тут кое-что нашел, можно это посмотреть:
- https://symfony.com/blog/new-in-symfony-3-3-json-authentication
- http://www.webtipblog.com/adding-an-ajax-login-form-to-a-symfony-project/
- http://symfony.com/doc/current/security/custom_authentication_provider.html (тут создание своего провайдера)
спасибо, я прочитал,
по первой статье symfony-3-3-json-authentication - нужно дополнить стандартный SecurityServiceProvider в Silex, чтобы он поддерживал этот механизм аутенфикации, если я правильно понял.
Во второй статье как раз используют login_form и добавляют свой AuthenticationSuccessHandler, то что я думал сделать.
По третьей статье - пишут что это hard, и есть ссылка на статью "How to Create a Custom Authentication System with Guard", по счастливой случайности есть подобный рецепт именно для Silex. Для меня сложность заключается, в том что на данный момент я не до конца разобрался как работает Аутенфикация в Symfony, и в чем разница между Authenticator и Authentication Provider
https://silex.symfony.com/doc/2.0/cookbook/guard_authentication.html
>Бандлы - это части фреймворка Симфони, они не подходя к Силекс
>Я думаю, Силекс использует именно Security Component:
Век учись - век учись.
>Соответственно надо смотреть код/доки по провайдеру Силекса и по компоненту, а не по бандлам от Симфони. И из этого делать вывод, как там что настраивается.
Коварно, учитывая что в доках Silex Security ссылка именно на бандл, а не на компонент.
>просто знайте
Всегда знал, что программирование — это просто. Удивляюсь, что у него столько времени ушло на объяснения, можно было проще сделать.
А ты чего ожидал от видоса "Учим PHP за час?", что он тебе про mysqli расскажет, ооп добавит и ещё шаблончиков подкинет?
>Только через AJAX.
а как через ajax сделать редирект на ту страницу, на которую идет запрос? т.е. как имитировать отправку нормальной формы?
я вот с jquery написал такое: https://ideone.com/yKWdnb
но проблема в том, что видимо с т.з. браузера этот редирект не имеет отношения к первоначальной функции и поэтому там этих хедеров нет.
Форма же из браузера отправляется, а у всех браузерных запросов есть хедеры. Зачем джаваскрипт? Непонимат. В result.php разбираешь хедеры так же как в form.php (если ты там это делаешь)
Запрос к форм
от форм будет запрос к резулт
2 запроса! Зачем джаваскрипт.
>$result->data_seek
Орайли хуесос, так лампово поясняет по началу, а потом резко бросает бомжа о реальность заставляя гуглить
Есть задача
>На картинке — часть программы, создающая философское настроение. Принцип работы таков: есть 5 наборов слов, из которых случайно выбираются слова, образуя такую структуру:
> слово1 слово2 слово3
> слово1 слово2 слово3
> Я слово4 слово5
Я ее сделал, но есть еще доп условие, с которым я справиться не могу
>можно упростить программу, сделав что-то вроде шаблона для генерации стиха на основе массива. В каждый элемент массива мы кладем массив вариантов слова или строки, из которого надо сделать выбор: [$word1, $word2, $word3, ["\n"], ...]. Мы добавляем массив с "\n", чтобы в нужном месте вывелся перевод строки. Остается только пройти по массиву циклом и сгенерировать стих..
Cделал двухмерный массив, а как сделать так, чтобы он рандомно из него извлекал значения и выводил, я понять не могу.
https://ideone.com/0VoXhM Сам текст программы, пробовал через foreach реализовать, но нихуя не работает.
как их разобрать - это понятно. также понятно, как сделать response headers. проблема в том, что мне нужны кастомные заголовки запросов (request headers). они отсылаются КЛИЕНТОМ, т.е. в данном случае браузером.
если ты их можешь сделать без js, то подскажи, пожалуйста, как.
>>$result->data_seek
в смысле, на пальцах? ресулт - это объект какого-то класса, а дата_сик - это судя по всему его поле (либо, если ты пропустил скобочки в конце, метод). или что тебе объяснить?
...
for ($j = 0 ; $j < $rows ; ++$j)
{
echo 'name: ' . $result->fetch_assoc()['name'] . '<br>';
$result->data_seek($j);
echo 'profession: ' . $result->fetch_assoc()['profession'] . '<br>';
$result->data_seek($j);
echo 'date: ' . $result->fetch_assoc()['date'] . '<br>';
$result->data_seek($j);
echo 'id: ' . $result->fetch_assoc()['id'] . '<br>';
$result->data_seek($j);
}
...
Если я уберу $result->data_seek($j); то мне выведет только 1 список данных.
Дата сик проверяет на наличие или чего? Хуйня какаято, без пояснений без нихуя на грит тебе код и краткое описание, и ни слова функциях mysqli
Нужно проходиться по всему массиву слов $words и брать случайное значение из каждого элемента массива $wordsN.
https://secure.php.net/manual/ru/mysqli-result.data-seek.php
вбил бы в гугол хоть.
вообще, если хочешь учиться, учись сразу правильно. выброси нахуй mysqli и используй pdo. и выброси книги, которые рекомендуют использовать mysqli. учить его - потеря времени, т.к. учить пдо не намного дольше (можно начать работу через полчаса), но зато он используется везде, а mysqli только фриками
у ОПа есть урок по пдо.
Это вызов метода data_seek() класса mysqli_result
https://secure.php.net/manual/ru/mysqli-result.data-seek.php
https://secure.php.net/manual/ru/class.mysqli-result.php
Он >Перемещает указатель результата на выбранную строку
Т.е. например, если у тебя в результате 10 строк, то data_seek(5) переместит указатель на 6 строку (отсчёт, судя по всему, идёт с 0), и при выполнении fetch_assoc() вернётся эта строка, а не весь массив результатов
Ааа понел, просто я невнимательный хуесос и вообще некоторые вещи до меня доходят с диким лагом - нужно только отвлечься немного.
В процессе гугления так же нашел инфу по которой будто переучиться с мускли на пдо на раз два можно - очень схожи типа. И да, сегодня пдо а завтра какая другая хуйня, и если я не прав то дай аналог орейли
>Пока никто его не сделал
Звучит как вызов! Впрочем, я жалкая посредственность, так что тоже не смогу.
А я тоже начал, но с фронтенда.
>сегодня пдо а завтра какая другая хуйня
так можно про вообще все сказать. но пока другой хуйни даже на горизонте нет. учить пару дней, а использовать будешь несколько лет (и даже когда появится другая хуйня, не захочешь на нее переходить)
нормальных КНИГ по пхп пока не написано. тут кто-то рекомендовал Зандстру, но она написана в 2011, а пхп - это не си, с 2011 года все сильно поменалось, в т.ч. используемые практики. то, что считалось нормальным в 2011, сейчас считается говнокодом, увы. не говоря уже о том, что в 2011 актуальной версией была 5.3
я считаю, нужно: читать книги по джаве (герберт шилдт, java complete reference, чистый код роберта мартина), мануал по пхп - он у нас охуенный (в отличие от других языков), учебник и пасту ОПа, проходить хорошие курсы (profit).
>Если это для разбора письма, то не надо делать это руками, а надо взять расширение или библиотеку для разбора писем. Погугли.
>А в твоем примере - в письме ведь могут быть и другие варианты кодирования, ты их учел?
Да, для чтения заголовка письма, ну 2 варианта только предусмотрел, один для заголовка, второй для названия файла вот. Погуглю, благодарю.
ОПу спасибо - годно сделал, по нему пхп учил
Я ленивый, информацию мне нужно подавать структурированно, как у ОПа и орейли
Разобрался, спасибо, анончик
Да фишка в том, что он из word1 должен тоже рандомно выводить слово, а он не выводит. Я просто не пойму, какой функцией мне вообще это реализовать надо, через foreach?
>>17319
Там же по задаче, вначале должно быть слово из первого подмассива, потом из второго, потом из третьего, во второй строке все повторяться должно.
Добавлю
Просто я как думаю, через mt_rand()запилить генератор случайных чисел, чтобы он мне под каждый подмассив случайный индекс давал в их диапазоне, и потом как то вывести общий результат.
>Я просто не пойму, какой функцией мне вообще это реализовать надо, через foreach?
Да, через foreach.
>Нужно проходиться по всему массиву слов $words и брать случайное значение из каждого элемента массива $wordsN.
Проходишься с его помощью по массиву $words и из каждого его элемента $wordsN берешь случайное значение.
Как обращаться к элементам перебираемого массива, надеюсь, знаешь?
У тебя, кстати, ещё проблема в коде есть, что ты диапазон случайных чисел ручками заполняешь. А если массивов и его элементов будет заведомо неизвестное количество, как это зачастую и бывает?
Тебе нужно исхитрится программно получить количество элементов или воспользоваться функцией получения случайного элемента массива.
Изучи какие есть функции для работы с массивом. Если ты хочешь программировать на PHP тебе они, в любом случае, пригодятся.
https://secure.php.net/manual/ru/ref.array.php
Эти функции ты уже должен пройти:
https://php.net/manual/ru/function.count.php
https://php.net/manual/ru/function.array-rand.php
Ты чет горишь и придираешься к словам, которые по какой то причине были вырваны из контекста. Будь няшей, а не злюкой :3
Хз че вы так бугуртите, мне ее даже проходить не нужно, я тупо обновляю страницу, быстро вставляю текст с картинкой и отправляю.
по-моему, заебатая капча. я в соновном даже галочку не жму, оно само валидируется там.
правда херово, что на телефоне постоянно заставляют угадывать витрины магазинов и прочее говно. а с десктопа все ок.
>>17341
вопрос, что будет потом, когда ты соберешься применять полученную информацию. поди же деньги захочешь за это? за код образца 2011 года деньги особо не платят.
обрати внимание на фразу про хорошие курсы - в них все предельно структурировано.
но так-то я не против, учись по тому, что нравится. через год заходи и расскажешь, какие результаты.
>>17360
для работы с массивами нужно использовать функции работы с массивами (array_rand в твоем случае).
Получаю ошибку Maximum execution time of 30 seconds exceeded на mysqli::query.
Код:
Рабочий:
$db_data = $db->query(запрос);
while ($data = $db_data->fetch_assoc()) {}
Не рабочий:
while ($data = $db->query(запрос)->fetch_assoc()) {}
По сути логика одна и та же, но первый код не зависает, а второй зависает (но раньше не зависал никогда за 3 года кодинга на пхп, лол. Всегда так писал).
Че за проклятье-то блять? На всякий случай boot файл приложил.
идея хорошая, но надо учитывать, что без нужного опыта проект в реальности оказывается в несколько раз сложнее, чем кажется, когда придумываешь его. попробуй начать с проектирования БД, нарисовать на листочке таблицы со связями.
я считаю, для учебы лучше написать с нуля (это и получится свой учебный микрофреймворк). параллельно можно поизучать исходники существующих борд.
алсо, чем "с 0 на нативке" отличается от "написать свой движок"?
>while ($data = $db_data->fetch_assoc())
костыльненько.
ты хочешь реализовать method chaining, но для этого нужно, чтобы $db->query() возвращал сам себя: https://habrahabr.ru/post/170019/
раз ты сказал, то ничем, просто читал не особо улавливаю разницу между, например, движком и фреймворком, почитал об этом на форумах. движок - по типу CMS, как мне понимается. Буду благодарен, если объяснишь более доходчиво.
>это и получится свой учебный микрофреймворк
У меня есть некоторые наработки, потому что хотел написать свой микрофреймворк, хотя кроме самописного роутера, некотрых пакетов симфони там и нет ничего, лол.
>>17480
>костыльненько.
в файлах на 3 строки и так сойдет.
>method chaining
что это?
спасибоза линк. я хоть понял наконец-то, зачем нужны интерфейсы.
движок - это типа готовая болванка, которую ты средствами ее интерфейса настраиваешь под свои нужды. это необязательно cms, может быть движок для вики, форума и пр. предполагается, что ты не должен быть программистом, чтобы поднимать сайты на cms.
фреймворк - это набор библиотек, связанный общей структурой, кодстайлом и набором гайдлайнов, руководствуясь которыми ты пишешь свой код, использующий данные библиотеки. главное отличие фреймворка от просто набора библиотек (помимо перечисленных выше) - инверсия управления, т.е. в случае с библиотекой ты ставишь ее себе на сайт и вызываешь из своего кода, а в случае с фреймворком ты вставляешь свой код в него, и фреймворк вызывает его. то есть запрос всегда сначала идет на фронт-контроллер фреймворка.
>>17484
>я хоть понял наконец-то, зачем нужны интерфейсы
на здоровье. после года работы пора бы
Программер 15+ лет, ненавижу вкатывальщиков, PHP -- единственный пост, в котором я отвечаю по-настоящему.
Да, имеет, bootstrap/sass + gulp.
олсо в следующей версии CSS обещают многие фишки из сегодняшних препроцессоров, но пока их норм не сделоли, это неважно.
ну и C/C++ ещё, на котором, собственно, РНР и написан, как и большинство других языков
>>17599
>>17600
как бы в чём кайф PHP,
это фреймворк на C++, который сохраняет синтаксис Cpp, с лучшими решениями от той же Java (тайпхинт, анонимные функции, asserts и т.д.).
До сих пор, это,
1) язык, который уверенно держит 80++% рынка веба,
2) стал в несколько раз быстрее с вресии 7.0
3) в общем смысле приятен и быстр в разработке. Качественная разработка на РНР до сих пор впечатляет по скорости.
Это не имеет никакого отношения ко вкатывальщикам <5лет опыта, но, в целом, высркоквалифицированное программирование на PHP -- это круто.
Суть такова. Допустим есть карта. Есть например изображение которое нужно разместить на карте и запомнить это место. Затем выводить его при каждой загрузке изображения. Как это сделать ума не приложу. Ну тоесть координаты в пикселях наверное можно хранить в бд. И брать их оттуда, но вот как в CSS это всё организовать?
тогда просто поверх позиционируй свою пижню,
https://www.w3schools.com/cssref/pr_pos_z-index.asp
https://www.w3schools.com/css/css_positioning.asp
велкам, чувак, PHP-тред -- единственное место, где тебе по-доброму подскажут, а не насмеются и пошлют нахуй
>>17601
если хотите прям просветлиться, качайте исходник PHP, написанный на православном C++, и изучайте, что такое "язык PHP" http://php.net/downloads.php
ну и вообще, вы, дурацкие вкатывальщики, должны понять, что все (ново)(модные) C#, Java, PHP, Perl, Node.js, R, Go -- всё это написано на С++/C http://lurkmore.to/Pure_C , что, как бы, без вариантов.
>по-моему, заебатая капча. я в соновном даже галочку не жму, оно само валидируется там.
>
>правда херово, что на телефоне постоянно заставляют угадывать витрины магазинов и прочее говно. а с десктопа все ок.
Конченная каптча. Угадывать витрины это вообще моё самое любимое. И ждать по несколько секунд пока новые картинки появиться. Обожаю.
Вообще, самая крутая капча, которую я видел, за всё время, это на доброчане. Настоящие слова читать и печатать быстрей, потому что мы читаем не каждый слог отдельно а всё слово целиком, и печатать тоже проще, потому что руки уже привыкли.
Накрутить на неё каких-нибудь фильтров типо шума и глитчей всяких, чтобы роботам было тяжело разгадать и норм будет.
ну в том числе, но без фанатизма
Привет. Видел твое резюме на хх. Отпиши мне на мыльце, расскажу о вакансии.
Как сделать регистронезависимый поиск по БД? Т.е. чтобы независимо от того, какая ошибка с регистром была совершена при запросе, он завершился удачно.
А если я делаю поиск через переменную?
Выражение такого типа:
SELECT * FROM pet WHERE name REGEXP '^$x';
не работает.
М.б. в PDO есть какая-то фича специально для этого?
>SELECT FROM pet WHERE name REGEXP '^$x';
>не работает.
Я полагаю, потому что символ $, это метасимвол регулярного выражения, а не обозначение переменной
https://dev.mysql.com/doc/refman/5.5/en/regexp.html#regexp-syntax
>$ Match the end of a string.
Так же, регулярное выражение будет искать точную строку, т.е. регистрозависимую
Тебе нужно использовать вместо него оператор LIKE
https://dev.mysql.com/doc/refman/5.7/en/string-comparison-functions.html#operator_like
Более того, в твоём запросе есть уязвимость для SQL инъекции
Чтобы её не было нужно использовать плейсхолдеры
https://secure.php.net/manual/ru/pdo.prepared-statements.php
SELECT FROM pet WHERE name LIKE :search
http://php.net/manual/ru/class.exception.php#exception.props.file
Например у меня страница обрабатывает GET запрос с двумя переменными, например x и y.
Так же на этой странице у меня есть ссылки с разными значениями этих x и y, что-то вроде <a href="index.php?x=x1">x1 и href="index.php?y=y1">y1 и их много с разными значениями
Мне нужно чтобы запоминалось состояние этих переменных. То есть например я первый раз захожу на страницу, гет поля пустые = ставятся значения по умолчанию, если я нажму на ссылку х5 например, то что-то произойдет, потом я нажму на y6 например, то тоже что-то произойдет, но моя х переменная сбросится. Если вручную прописывать в юрл ?x=5&y=6 то всё работает. Я что-то вообще запутался, помогите аноны.
Добавляй динамически полный href каждой ссылке.
<a href="?x=5&y=6&unset=x">x активна (нажми чтобы инактивировать)</a>
<a href="?x=5&y=6&unset=y">y активна (нажми чтобы инактивировать)</a>
<a href="?x=5&y=6&z=1488">z не активна</a>
или
<a href="?y=6&z=1488">x активна (нажми чтобы инактивировать)</a>
<a href="?x=5&z=1488">y активна (нажми чтобы инактивировать)</a>
<a href="?x=5&y=6">z активна (нажми чтобы инактивировать)</a>
<a href="?x=5&y=6&z=1488&q=101010">q не активна (нажми чтобы активировать)</a>
Ну ты понел.
>Почему в конструктор исключения 3 параметром передается предыдущее исключение, и даже есть метод getPrevious(), но нет свойства $previous в котором оно хранится?
Вот что накопал:
https://github.com/php/php-src/blob/master/Zend/zend_exceptions.c#L371
https://github.com/php/php-src/blob/master/Zend/zend_exceptions.c#L641
ОП, я правильно понимаю, что это зашито намертво? Это. Охуенно.
Это неправильно. Учебный код должен быть безупречен с точки зрения безопасности, так как это учебный код, люди на нем учатся и делают свой код на его основе. Что ему мешает сделать нормальный код? Скорее всего, отсутствие нужных знаний.
>>12937
>>13592
Было бы удобнее конечно делать примеры на jsfiddle или codepen, а то надо файлы скачивать и в браузере открывать.
1) все ок
2)
> font-family: "Trebuchet MS";
В конце списка шрифтов всегда нужно ставить один из стандартных serif, sans-serif итд ( http://www.wisdomweb.ru/CSS/font.php )
Если ты задаешь шрифт для блока, то его надо задавать на div, а не на p, так как текст может быть не только внутри абзаца, но и сам по себе, внутри списков, таблиц и тд. Шрифт наследуется на дочерние элементы, если для них не задан другой шрифт.
3) ок, верно
4)
> .wrapper div:not(:first-child)
:not поддерживается только в новых браузерах, а для старых лучше было бы сделать 2 правила, для всех дивов + правило для :first-child.
5)
> margin: 0 -3px -4px -3px;
Вертикальные маргины можно не указывать, так как у inline-элементов они ни на что не влияют.
6) В списке шрифтов в конец надо добавить стандартный шрифт.
7)
> <input type="edit">
такого типа вроде нет, нужно выбрать другой: https://developer.mozilla.org/ru/docs/Web/HTML/Element/Input
8) На первый взгляд неплохо, но если примечаний много, они накладываются друг на друга: https://codepen.io/anon/pen/PEEePd
Надо бы добавить clear или найти другое решение.
9)
Если текста много, он заезжает под картинку снизу, это надо убрать: https://codepen.io/anon/pen/RxxyGy
Если картинки нет, наверно, стоит все равно оставить место слева пустым, чтобы блоки с текстами располагались точно друг над другом.
10) Пока картинка не загрузилась (и неизвестны ее размеры), верстка выглядит криво. Попробуй поставить в HTML в теге img ссылку на несуществующую картинку (http://example.com/invalid.png) и посмотри, как выглядит верстка. Это надо исправить, верстка должна смотреться хорошо в любой момент, в том числе в процессе загрузки.
Можно попробовать задать какие-то мин. размеры для figure или улучшить позиционирование figcaption.
> em[data-ref="1"]::before {
> left: 64px;
Это не годится, не надо вручную подбирать отступ под каждую сноску, надо сделать для них выравнивание вправо (подсказка: можно сделать сноску фикс. ширины и внутри нее выровнять текст вправо, также можно в абс. поз. использовать не left, а отрицательные right + margin-right, чтобы прижать картинку правым краем к левому полю).
> figcaption .subtitle
Чтобы расположить подзаголовок под заголовком, достаточно дать ему display: block.
11)
> user-scalable=no
> maximum-scale=1.0, minimum-scale=1.0
Это плохая идея. Эта строка запрещает масштабирование на мобильных устройствах, и это неудобно. Почему я не могу изменить масштаб?
Я бы советовал избегать использовать в CSS-селекторах теги span и div. Это теги общего назначения, и может завтра кто-то добавит в верстку еще один спан, и на него автоматически применятся твои стили. Неудобно. Лучше указать CSS-класс или использовать не тег общего назначения.
Кнопки сделаны хорошо, но не работает навигация с помощью клавиатуры - скорее всего из-за того, что input скрыт с помощью display none, если скрыть его другим способом (задвинуть за край экрана, сделать нулнвых размеров, спрятать в блоке с overflow, засунуть под label с помощью z-index, сделать 100% прозрачным), то наверно клавиатурная навигация заработает.
12) Недостаток использования id в том, что нам нужно следить, чтобы они были уникальны, когда на странице несколько блоков табов (особенно, если код не пишется вручную, а как-то генерируется). Но это еще ладно. А вот то, что ты в CSS прописываешь id, не позволяет нам использовать более 4 вкладок на странице.
Нужно, чтобы:
а) можно было поставить 2 блока с вкладками на странице
б) можно было вложить блок с вкладками в тело вкладки в другом блоке
Лучше было бы использовать для связи заголовка и тела вкладки CSS-классы или data-атрибуты и написать правила так, чтобы они могли бы повторяться в разных блоках вкладок.
Что касается связи input и label, наверно, там придется оставить связь через id, если только у тебя нет идей получше.
Этот пункт задачи должен научить тебя применять CSS-правила точечно только к нужным элементам и избегать конфликтов.
Если вставить в заголовок таба очень-очень длинное слово, оно вываливается из него. Я бы предложил сделать там принудительный перенос длинных слов.
Но вообще, твоя работа производит хорошее впечатление и у тебя верно переданы цвета и шрифты, думаю, что у тебя верстка хорошо получается.
Это неправильно. Учебный код должен быть безупречен с точки зрения безопасности, так как это учебный код, люди на нем учатся и делают свой код на его основе. Что ему мешает сделать нормальный код? Скорее всего, отсутствие нужных знаний.
>>12937
>>13592
Было бы удобнее конечно делать примеры на jsfiddle или codepen, а то надо файлы скачивать и в браузере открывать.
1) все ок
2)
> font-family: "Trebuchet MS";
В конце списка шрифтов всегда нужно ставить один из стандартных serif, sans-serif итд ( http://www.wisdomweb.ru/CSS/font.php )
Если ты задаешь шрифт для блока, то его надо задавать на div, а не на p, так как текст может быть не только внутри абзаца, но и сам по себе, внутри списков, таблиц и тд. Шрифт наследуется на дочерние элементы, если для них не задан другой шрифт.
3) ок, верно
4)
> .wrapper div:not(:first-child)
:not поддерживается только в новых браузерах, а для старых лучше было бы сделать 2 правила, для всех дивов + правило для :first-child.
5)
> margin: 0 -3px -4px -3px;
Вертикальные маргины можно не указывать, так как у inline-элементов они ни на что не влияют.
6) В списке шрифтов в конец надо добавить стандартный шрифт.
7)
> <input type="edit">
такого типа вроде нет, нужно выбрать другой: https://developer.mozilla.org/ru/docs/Web/HTML/Element/Input
8) На первый взгляд неплохо, но если примечаний много, они накладываются друг на друга: https://codepen.io/anon/pen/PEEePd
Надо бы добавить clear или найти другое решение.
9)
Если текста много, он заезжает под картинку снизу, это надо убрать: https://codepen.io/anon/pen/RxxyGy
Если картинки нет, наверно, стоит все равно оставить место слева пустым, чтобы блоки с текстами располагались точно друг над другом.
10) Пока картинка не загрузилась (и неизвестны ее размеры), верстка выглядит криво. Попробуй поставить в HTML в теге img ссылку на несуществующую картинку (http://example.com/invalid.png) и посмотри, как выглядит верстка. Это надо исправить, верстка должна смотреться хорошо в любой момент, в том числе в процессе загрузки.
Можно попробовать задать какие-то мин. размеры для figure или улучшить позиционирование figcaption.
> em[data-ref="1"]::before {
> left: 64px;
Это не годится, не надо вручную подбирать отступ под каждую сноску, надо сделать для них выравнивание вправо (подсказка: можно сделать сноску фикс. ширины и внутри нее выровнять текст вправо, также можно в абс. поз. использовать не left, а отрицательные right + margin-right, чтобы прижать картинку правым краем к левому полю).
> figcaption .subtitle
Чтобы расположить подзаголовок под заголовком, достаточно дать ему display: block.
11)
> user-scalable=no
> maximum-scale=1.0, minimum-scale=1.0
Это плохая идея. Эта строка запрещает масштабирование на мобильных устройствах, и это неудобно. Почему я не могу изменить масштаб?
Я бы советовал избегать использовать в CSS-селекторах теги span и div. Это теги общего назначения, и может завтра кто-то добавит в верстку еще один спан, и на него автоматически применятся твои стили. Неудобно. Лучше указать CSS-класс или использовать не тег общего назначения.
Кнопки сделаны хорошо, но не работает навигация с помощью клавиатуры - скорее всего из-за того, что input скрыт с помощью display none, если скрыть его другим способом (задвинуть за край экрана, сделать нулнвых размеров, спрятать в блоке с overflow, засунуть под label с помощью z-index, сделать 100% прозрачным), то наверно клавиатурная навигация заработает.
12) Недостаток использования id в том, что нам нужно следить, чтобы они были уникальны, когда на странице несколько блоков табов (особенно, если код не пишется вручную, а как-то генерируется). Но это еще ладно. А вот то, что ты в CSS прописываешь id, не позволяет нам использовать более 4 вкладок на странице.
Нужно, чтобы:
а) можно было поставить 2 блока с вкладками на странице
б) можно было вложить блок с вкладками в тело вкладки в другом блоке
Лучше было бы использовать для связи заголовка и тела вкладки CSS-классы или data-атрибуты и написать правила так, чтобы они могли бы повторяться в разных блоках вкладок.
Что касается связи input и label, наверно, там придется оставить связь через id, если только у тебя нет идей получше.
Этот пункт задачи должен научить тебя применять CSS-правила точечно только к нужным элементам и избегать конфликтов.
Если вставить в заголовок таба очень-очень длинное слово, оно вываливается из него. Я бы предложил сделать там принудительный перенос длинных слов.
Но вообще, твоя работа производит хорошее впечатление и у тебя верно переданы цвета и шрифты, думаю, что у тебя верстка хорошо получается.
Справедливые замечания. Я хочу написать уроки про особенности SPA приложений (в первую орчередь про организацию API и синхронизацию данных), про способы позиционирования в HTML. Про сокеты - не знаю, сначала надо поискать, может где-то уже есть хорошие уроки.
>>13346
https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2
> Почему мне тогда просто не поставить try/catch на роутер, а если кто то захочет обрабатывать какую либо ошибку, напишет себе личный try/catch на тот метод, который хочет?
Можно так, но можно просто поставить обработчик всех необработанных исключений через set_exception_handler.
> я думал у меня только index.php в публичном доступе
Я думаю, что нет. Веб-сервер по умолчанию отдаст любые файлы из публичной папки, например, дампы, бекапы, конфиг, файлы .git и и тд. Потому и надо выделить в проекте публичную папку, где лежит только то, что мы готовы отдать наружу.
У тебя там есть какие-то запреты в htaccess, но я например не вижу исключения для index.php, возможно, что они не работают или работают не так, как задумано. Это в любом случае ненадежный метод, так как достаточно убрать htaccess или еще как-то накосячить с настройкой сервера и защита отключится. Я помню, в фейсбуке был баг - они какое-то время вместо выполнения скрипта index.php отдавали его пользователям как файл - если поискать, в сети есть эти утекшие кусочки кода фейсбука.
>>> const REG_FORM_SEX_MAN = "Мужской";
>> Эту константу уместнее поместить в студента, а не в проверяльщик формы.
> Почему?
Потому, что пол - это свойство студента, а не формы. Вот мы удалим форму, но студент и пол останется. А константа для него?
>>Папку лучше назвать не Student, а Entity или Model.
> почему?
Потому, что если ты будешь развивать проект, у тебя появятся новые сущности (например, Занятия, Факультеты и тд) и ты ведь не будешь для каждой свою папку делать. В случае с Entity их можно будет в ту же папку класть.
>>Этот класс не очень-то и нужен, тебе ведь никто не запрещает просто создать PDO через new.
> вообще я украл это. ну и как я понимаю, он для того что бы данные для пдо из ини файла брать.
Получается, он не очень-то и нужен. Этот класс делают люди, не знакомые с DI. Подход с сингтонами и статическими методами описан у меня в уроке про DI https://github.com/codedokode/pasta/blob/master/arch/di.md
> не понимаю. я вроде делаю большинство того что там написано
Если делать DI, то должно быть так:
class UsersTableGateway {
public function __construct (Db $db) { ... }
}
То есть класс получает нужные ему объекты-зависимости извне, а не ищет их сам. В уроке по DI описано, чем плохи другие подходы (например: зависимости явно не видны, нельзя их подменить, нельзя настроить какие-то опции для них).
>>Здесь проблема в том, что ты возвращаешь "неполноценные" объекты Student, у которых не заполнена часть полей. Это усложняет код, так как в нем где-то гуляют полностью заполненные объекты, а где-то нет и различить их невозможно. >Получив такой объект, ты не знаешь - у студента пустое название группы или оно просто не загружено. Если ты хочешь вернуть только 4 поля, надо использовать массив или отдельный объект. Но лучше бы вернуть полноценных студентов.
> В смысле гулять. Он же используется только в профайле и потом уничтожается. А возвращаться полноценых с хешомпароля, логином и тд не опасней?
Это пока. Потом ты будешь развивать код и он будет использоваться где-то еще, потом где-то еще и потом пойдут баги из-за того, что ты передал не тот вид объекта, который требуется. Если тебе нужна только часть полей, надо либо делать массив, либо делать отдельный объект только с этими полями (StudentView например) либо еще придумать какое-то решение.
Ну и представь, что кто-то другой дорабатывает твой код. Вот он видит заголовок функции
function doSomething(Student $s)
{
Как ему угадать, какие поля заполнены, а какие нет у объекта $s? Никак, он будет думать, что там полноценный объект.
> А возвращаться полноценых с хешомпароля, логином и тд не опасней?
Если ты их не выводишь, то думаю, что это приемлемо.
>>(в роутере) Вместо exit лучше бы поставить return.
> почему?
Потому что может быть ты захочешь написать какой-то код в index.php после вызова роутера и в случае exit он никогда не выполнится, а в случае return выполнится.
> header('location: profile');
Этот относительный URL, который будет вести на разные страницы в зависимости от того, с какого URL делается редирект. Лучше написать /profile чтобы все было однозначно.
>>Контроллеры profile и reg наверно можно объединить?
> но они же разные
По моему так регистрация и редактирования профиля очень похожие вещи, и там и там мы заполняем свойства студента и сохраняем их в БД.
> Я сначала подключая headers, и потом к нему только тело. Это нормально?
Ну можно так оставить, но по моему так логичнее делать один вызов render. Пусть вью сам решает, какая на той или иной странице шапка.
> Нормально ли создавать их и вызывать функцию doExecute (что я тоже кстати подсмотрел), когда это можно все в конструктор запихать.
Конструктор должен только инициализировать и подгогтавливать объект к работе, а не делать саму работу. Так что нет, неправильно. Что касается doExecute, лучше было бы назвать его просто execute.
Также, если у тебя контроллер обязан иметь метод execute, то логично сделать интерфейс для контроллера, зафиксировать в нем наличие этого метода и требовать от всех контроллеров реализовать этот интерфейс. Урок про интерфейсы: https://github.com/codedokode/pasta/blob/master/php/interfaces.md
А то сейчас у тебя контроллеры никак не связаны между собой, и никак не определены требования к контроллеру.
> Нормально ли создавать в них классы и потом их передавать тем кто нуждаются?
Зависит от ситуации, если речь про DI, то конечно объекты лучше создавать где-нибудь отдельно. Часто это делают при инициализации приложения или в DI контейнере.
> Нужно ли мне использовать интерфейсы и абстракт класы к примеру к контролерам?
Интерфейс бы тут подошел.
> А еще я запушил новые файлы и папки а старые так же остались и получилась каша. Как скрыть старые?
Удалить у себя файлы, закоммитить удаление, запушить на гитхаб. Эти удаленные файлы все равно останутся в истории репозитории.
Справедливые замечания. Я хочу написать уроки про особенности SPA приложений (в первую орчередь про организацию API и синхронизацию данных), про способы позиционирования в HTML. Про сокеты - не знаю, сначала надо поискать, может где-то уже есть хорошие уроки.
>>13346
https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2
> Почему мне тогда просто не поставить try/catch на роутер, а если кто то захочет обрабатывать какую либо ошибку, напишет себе личный try/catch на тот метод, который хочет?
Можно так, но можно просто поставить обработчик всех необработанных исключений через set_exception_handler.
> я думал у меня только index.php в публичном доступе
Я думаю, что нет. Веб-сервер по умолчанию отдаст любые файлы из публичной папки, например, дампы, бекапы, конфиг, файлы .git и и тд. Потому и надо выделить в проекте публичную папку, где лежит только то, что мы готовы отдать наружу.
У тебя там есть какие-то запреты в htaccess, но я например не вижу исключения для index.php, возможно, что они не работают или работают не так, как задумано. Это в любом случае ненадежный метод, так как достаточно убрать htaccess или еще как-то накосячить с настройкой сервера и защита отключится. Я помню, в фейсбуке был баг - они какое-то время вместо выполнения скрипта index.php отдавали его пользователям как файл - если поискать, в сети есть эти утекшие кусочки кода фейсбука.
>>> const REG_FORM_SEX_MAN = "Мужской";
>> Эту константу уместнее поместить в студента, а не в проверяльщик формы.
> Почему?
Потому, что пол - это свойство студента, а не формы. Вот мы удалим форму, но студент и пол останется. А константа для него?
>>Папку лучше назвать не Student, а Entity или Model.
> почему?
Потому, что если ты будешь развивать проект, у тебя появятся новые сущности (например, Занятия, Факультеты и тд) и ты ведь не будешь для каждой свою папку делать. В случае с Entity их можно будет в ту же папку класть.
>>Этот класс не очень-то и нужен, тебе ведь никто не запрещает просто создать PDO через new.
> вообще я украл это. ну и как я понимаю, он для того что бы данные для пдо из ини файла брать.
Получается, он не очень-то и нужен. Этот класс делают люди, не знакомые с DI. Подход с сингтонами и статическими методами описан у меня в уроке про DI https://github.com/codedokode/pasta/blob/master/arch/di.md
> не понимаю. я вроде делаю большинство того что там написано
Если делать DI, то должно быть так:
class UsersTableGateway {
public function __construct (Db $db) { ... }
}
То есть класс получает нужные ему объекты-зависимости извне, а не ищет их сам. В уроке по DI описано, чем плохи другие подходы (например: зависимости явно не видны, нельзя их подменить, нельзя настроить какие-то опции для них).
>>Здесь проблема в том, что ты возвращаешь "неполноценные" объекты Student, у которых не заполнена часть полей. Это усложняет код, так как в нем где-то гуляют полностью заполненные объекты, а где-то нет и различить их невозможно. >Получив такой объект, ты не знаешь - у студента пустое название группы или оно просто не загружено. Если ты хочешь вернуть только 4 поля, надо использовать массив или отдельный объект. Но лучше бы вернуть полноценных студентов.
> В смысле гулять. Он же используется только в профайле и потом уничтожается. А возвращаться полноценых с хешомпароля, логином и тд не опасней?
Это пока. Потом ты будешь развивать код и он будет использоваться где-то еще, потом где-то еще и потом пойдут баги из-за того, что ты передал не тот вид объекта, который требуется. Если тебе нужна только часть полей, надо либо делать массив, либо делать отдельный объект только с этими полями (StudentView например) либо еще придумать какое-то решение.
Ну и представь, что кто-то другой дорабатывает твой код. Вот он видит заголовок функции
function doSomething(Student $s)
{
Как ему угадать, какие поля заполнены, а какие нет у объекта $s? Никак, он будет думать, что там полноценный объект.
> А возвращаться полноценых с хешомпароля, логином и тд не опасней?
Если ты их не выводишь, то думаю, что это приемлемо.
>>(в роутере) Вместо exit лучше бы поставить return.
> почему?
Потому что может быть ты захочешь написать какой-то код в index.php после вызова роутера и в случае exit он никогда не выполнится, а в случае return выполнится.
> header('location: profile');
Этот относительный URL, который будет вести на разные страницы в зависимости от того, с какого URL делается редирект. Лучше написать /profile чтобы все было однозначно.
>>Контроллеры profile и reg наверно можно объединить?
> но они же разные
По моему так регистрация и редактирования профиля очень похожие вещи, и там и там мы заполняем свойства студента и сохраняем их в БД.
> Я сначала подключая headers, и потом к нему только тело. Это нормально?
Ну можно так оставить, но по моему так логичнее делать один вызов render. Пусть вью сам решает, какая на той или иной странице шапка.
> Нормально ли создавать их и вызывать функцию doExecute (что я тоже кстати подсмотрел), когда это можно все в конструктор запихать.
Конструктор должен только инициализировать и подгогтавливать объект к работе, а не делать саму работу. Так что нет, неправильно. Что касается doExecute, лучше было бы назвать его просто execute.
Также, если у тебя контроллер обязан иметь метод execute, то логично сделать интерфейс для контроллера, зафиксировать в нем наличие этого метода и требовать от всех контроллеров реализовать этот интерфейс. Урок про интерфейсы: https://github.com/codedokode/pasta/blob/master/php/interfaces.md
А то сейчас у тебя контроллеры никак не связаны между собой, и никак не определены требования к контроллеру.
> Нормально ли создавать в них классы и потом их передавать тем кто нуждаются?
Зависит от ситуации, если речь про DI, то конечно объекты лучше создавать где-нибудь отдельно. Часто это делают при инициализации приложения или в DI контейнере.
> Нужно ли мне использовать интерфейсы и абстракт класы к примеру к контролерам?
Интерфейс бы тут подошел.
> А еще я запушил новые файлы и папки а старые так же остались и получилась каша. Как скрыть старые?
Удалить у себя файлы, закоммитить удаление, запушить на гитхаб. Эти удаленные файлы все равно останутся в истории репозитории.
Встроенные в PHP классы вроде Exception могут быть написаны на Си, и в этом случае они могут не соблюдать общие правила. То есть это свойство там, конечно, есть, но оно скрыто и недоступно из PHP кода. Наверно, чтобы не было соблазна туда лезть, чтобы использовали getPrevious().
>>17776
Я вижу тут варианты:
1) генерировать ссылки в зависимости от текущих параметров, чтобы они сохранялись
2) использовать для сохранения настроек пользователя куки
3) если у тебя есть база данных и таблица зарегистрированных пользователей, можно запомнать настройки пользвоателя там
>>17180
>>Там почему-то информация о залогиненном пользователе хранится в контейнере
> Ты имеешь ввиду service container ?
Да. В нем, как следует из названия, хранятся сервисы, а также параметры конфигурации. То есть не меняющиеся между запросами значения. Не знаю, почему в Симфони решили туда класть Request, User и прочее (request они уже заменили на request_stack).
В чем тут проблема? В том, что этот подход рассчитан на то, что программа умрет после обработки первого запроса и не будет обрабатывать второй, а уж тем более, не будет пытаться обрабатывать 2 HTTP-запроса параллельно.
Плюс, это делает код менее надежным. Если сервис использует request или user, как он будет работать при вызове из командной строки? Или там например есть роутер, который разбирает URL и сохраняет результаты разбора в атрибуты request. Получается, что у нас в один момент времени в контейнере лежит request без атрибутов, а потом с атрибутами.
По моему, user/request/session должны создаваться в начале цикла обработки запроса, передаваться куда-нибудь в контроллер и пусть он дальше распоряжается ими как хочет. А так, это получаются те же глобальные переменные.
>> в контейнере не должно сохраняться ничего, относящееся к текущему запросу.
> сохранять сессию в БД?
Ну саму сессию в контейнер никто и не сохраняет, ее данные хранятся в файлах. Может, там хранится сервис для работы с сессиями? Хотя я погуглил, эти гении и объект сессии в контейнер засунули.
> по первой статье symfony-3-3-json-authentication - нужно дополнить стандартный SecurityServiceProvider в Silex, чтобы он поддерживал этот механизм аутенфикации, если я правильно понял.
Можешь предложить разработчикам Silex свою помощью в этом ;)
> Во второй статье как раз используют login_form и добавляют свой AuthenticationSuccessHandler, то что я думал сделать.
Да, это хороший вариант, просто возвращать свой response нужного типа после проверки. Я думаю, это проще всего.
> Для меня сложность заключается, в том что на данный момент я не до конца разобрался как работает Аутенфикация в Symfony, и в чем разница между Authenticator и Authentication Provider
Я бы советовал разобраться, если есть время. Начать именно с компонента Security, посмотреть код, может, нарисовать диаграмму классов, понять, кто за что отвечает. Может, ты лучше начнешь понимать устройство Симфони, ну и может какие паттерны полезные увидишь в коде.
> Коварно, учитывая что в доках Silex Security ссылка именно на бандл, а не на компонент.
Да, это такая проблема Симфони, что там может быть документация немного перепутана. Но зная отличие между компонентами и бандлами, я думаю, ты разберешься. Опять же, ты можешь просто сравнить код Security Bundle и Security Component и увидеть за что каждый отвечает.
>>17324
нет, урока по PDO у меня нет, но есть статья на Хабре.
>>17333
Ну если ты будешь писать о возникающих затруднениях, то может, нам удастся за счет тебя написать подробные комментарии к уроку, которые помогут следующим (а может даже пару уроков по SPA). Именно так, постепенно, по опыту разбора решений, были написаны комментарии к студентам, и я вижу, что после их добавления люди уже не делают те ошибки, что раньше.
>>17436
Можешь утешать себя, что ты помогаешь разработке самодвижущихся автомобилей Гуглом (я думаю, что мы тут размечаем картинки, на которых потом обучают и тренируют нейросети для распознавания образов). Гугл умно это придумал, как найти бесплатных размечальщиков данных.
>>17814
Вообще, я посмотрел код и нашел функцию, где создается класс исключения (именно описывается сам класс) и я вижу, что там добавляется свойство previous:
> zend_declare_property_null(zend_ce_exception, "previous", sizeof("previous")-1, ZEND_ACC_PRIVATE);
Видимо, оно не описано в документации. Если посмотреть, там вообще приватные поля не описаны, только протектед. Если тебе это кажется неправильным, можно (на англ) создать баг в багтрекере по поводу документации и предложить описать приватные поля. Если они согласятся, то зайти на edit.php.net и отредактировать англ. и рус. версии документации.
Встроенные в PHP классы вроде Exception могут быть написаны на Си, и в этом случае они могут не соблюдать общие правила. То есть это свойство там, конечно, есть, но оно скрыто и недоступно из PHP кода. Наверно, чтобы не было соблазна туда лезть, чтобы использовали getPrevious().
>>17776
Я вижу тут варианты:
1) генерировать ссылки в зависимости от текущих параметров, чтобы они сохранялись
2) использовать для сохранения настроек пользователя куки
3) если у тебя есть база данных и таблица зарегистрированных пользователей, можно запомнать настройки пользвоателя там
>>17180
>>Там почему-то информация о залогиненном пользователе хранится в контейнере
> Ты имеешь ввиду service container ?
Да. В нем, как следует из названия, хранятся сервисы, а также параметры конфигурации. То есть не меняющиеся между запросами значения. Не знаю, почему в Симфони решили туда класть Request, User и прочее (request они уже заменили на request_stack).
В чем тут проблема? В том, что этот подход рассчитан на то, что программа умрет после обработки первого запроса и не будет обрабатывать второй, а уж тем более, не будет пытаться обрабатывать 2 HTTP-запроса параллельно.
Плюс, это делает код менее надежным. Если сервис использует request или user, как он будет работать при вызове из командной строки? Или там например есть роутер, который разбирает URL и сохраняет результаты разбора в атрибуты request. Получается, что у нас в один момент времени в контейнере лежит request без атрибутов, а потом с атрибутами.
По моему, user/request/session должны создаваться в начале цикла обработки запроса, передаваться куда-нибудь в контроллер и пусть он дальше распоряжается ими как хочет. А так, это получаются те же глобальные переменные.
>> в контейнере не должно сохраняться ничего, относящееся к текущему запросу.
> сохранять сессию в БД?
Ну саму сессию в контейнер никто и не сохраняет, ее данные хранятся в файлах. Может, там хранится сервис для работы с сессиями? Хотя я погуглил, эти гении и объект сессии в контейнер засунули.
> по первой статье symfony-3-3-json-authentication - нужно дополнить стандартный SecurityServiceProvider в Silex, чтобы он поддерживал этот механизм аутенфикации, если я правильно понял.
Можешь предложить разработчикам Silex свою помощью в этом ;)
> Во второй статье как раз используют login_form и добавляют свой AuthenticationSuccessHandler, то что я думал сделать.
Да, это хороший вариант, просто возвращать свой response нужного типа после проверки. Я думаю, это проще всего.
> Для меня сложность заключается, в том что на данный момент я не до конца разобрался как работает Аутенфикация в Symfony, и в чем разница между Authenticator и Authentication Provider
Я бы советовал разобраться, если есть время. Начать именно с компонента Security, посмотреть код, может, нарисовать диаграмму классов, понять, кто за что отвечает. Может, ты лучше начнешь понимать устройство Симфони, ну и может какие паттерны полезные увидишь в коде.
> Коварно, учитывая что в доках Silex Security ссылка именно на бандл, а не на компонент.
Да, это такая проблема Симфони, что там может быть документация немного перепутана. Но зная отличие между компонентами и бандлами, я думаю, ты разберешься. Опять же, ты можешь просто сравнить код Security Bundle и Security Component и увидеть за что каждый отвечает.
>>17324
нет, урока по PDO у меня нет, но есть статья на Хабре.
>>17333
Ну если ты будешь писать о возникающих затруднениях, то может, нам удастся за счет тебя написать подробные комментарии к уроку, которые помогут следующим (а может даже пару уроков по SPA). Именно так, постепенно, по опыту разбора решений, были написаны комментарии к студентам, и я вижу, что после их добавления люди уже не делают те ошибки, что раньше.
>>17436
Можешь утешать себя, что ты помогаешь разработке самодвижущихся автомобилей Гуглом (я думаю, что мы тут размечаем картинки, на которых потом обучают и тренируют нейросети для распознавания образов). Гугл умно это придумал, как найти бесплатных размечальщиков данных.
>>17814
Вообще, я посмотрел код и нашел функцию, где создается класс исключения (именно описывается сам класс) и я вижу, что там добавляется свойство previous:
> zend_declare_property_null(zend_ce_exception, "previous", sizeof("previous")-1, ZEND_ACC_PRIVATE);
Видимо, оно не описано в документации. Если посмотреть, там вообще приватные поля не описаны, только протектед. Если тебе это кажется неправильным, можно (на англ) создать баг в багтрекере по поводу документации и предложить описать приватные поля. Если они согласятся, то зайти на edit.php.net и отредактировать англ. и рус. версии документации.
у тебя судя по вопросу нет понимания, что вообще происходит. хром - это клиент, вместо него может быть что угодно. ошибка интерпретатора тебе и так показывается, нужно выводить отладочную информацию (см. в предыдущем посте ). http error 500 - это http статус, он идет в кач-ве заголовка ответа. ты можешь при желании любой контент выдавать с любым статусом.
ini_set("display_errors", On);
error_reporting(-1);
В начале скрипта.
Могут быть проблемы с показом ошибок из вложенных файлов. Надежнее добавить:
display_errors = On
error_reporting = E_ALL
В php.ini и перезапустить сервер. Как узнать где php.ini:
<?php
phpinfo();
В начале будет список загружаемых ini файлов.
У- успешен!
https://ideone.com/SQwBre
Почему этот цикл заместо того чтобы выводить $rows количество раз один и тот же результат оно перебирает всю таблицу? id 1 balabla id2 balbla id3 blabla Как это работает?
for ($j = 0 ; $j < $rows ; ++$j)
{
$row = $result->fetch_array(MYSQLI_ASSOC);
echo 'name: ' . $row['name'] . '<br>';
echo 'profession: ' . $row['profession'] . '<br>';
echo 'date: ' . $row['date'] . '<br>';
echo 'id: ' . $row['id'] . '<br><br>';
}
for ($j = 0 ; $j < $rows ; ++$j)
{
$row = $result->fetch_array(MYSQLI_ASSOC);
echo 'name: ' . $row['name'] . '<br>';
echo 'profession: ' . $row['profession'] . '<br>';
echo 'date: ' . $row['date'] . '<br>';
echo 'id: ' . $row['id'] . '<br><br>';
}
Спасибо
А, разобрался
echo, можно ли сделать так, чтобы ключ массива задавался через переменную?
$rand_keys = array_rand($words['word1'], 4);
echo $words['word'][$rand_keys[0]] . "\n";
>Можешь утешать себя, что ты помогаешь разработке самодвижущихся автомобилей Гуглом (я думаю, что мы тут размечаем картинки, на которых потом обучают и тренируют нейросети для распознавания образов). Гугл умно это придумал, как найти бесплатных размечальщиков данных.
Я слышал об этом, но я не могу понять тогда, каптча узнает что картинки не правильные? Значит кто-то уже сказал ей об этом, поэтому нет смысла, размечать картинки.
Или робот уже сам отобрал картинки и калибрует их точность, проверяя есть неправильные распознавания, отмечаемые большинства пользователями.
В любом случае спасибо тебе анончик.
1.Если мне нужно взять только значение при переборе массива, то выражения
foreach ($z as $v=>$f)
и
foreach ($z as $f)
будут идентичны?
Что я хочу выяснить. Разница между ними только в том, что в первом случае я могу делать манипуляцию И с ключом И со значением или же есть что-то ещё?
2.Если я собираюсь перебрать значения взятые из БД, мне стоит юзать foreach или while? Или тут тупо "что удобнее, то и бери"?
Потому-что если есть такой выбор:
while ($row = $stmt->fetch())
{
echo $row['name'] . "\n";
}
ИЛИ
foreach($stmt as $row);{
echo "<p>". $row['id']."|".$row['name'];
}
то мне foreach больше нравится.
1.Если мне нужно взять только значение при переборе массива, то выражения
foreach ($z as $v=>$f)
и
foreach ($z as $f)
будут идентичны?
Что я хочу выяснить. Разница между ними только в том, что в первом случае я могу делать манипуляцию И с ключом И со значением или же есть что-то ещё?
2.Если я собираюсь перебрать значения взятые из БД, мне стоит юзать foreach или while? Или тут тупо "что удобнее, то и бери"?
Потому-что если есть такой выбор:
while ($row = $stmt->fetch())
{
echo $row['name'] . "\n";
}
ИЛИ
foreach($stmt as $row);{
echo "<p>". $row['id']."|".$row['name'];
}
то мне foreach больше нравится.
Ну я там к fetch параметры не передал, но это такая постмодернистическая пост-ирония, а не демонстрация моей криворукости и распиздяйства.
может просто делать тайп-хинт по классу?
Анон, я правильно понимаю, что сам по себе регистронезависимый запрос будет проще сделать в PDO из-за использование плейсхолдов в запроса, вместо переменных напрямую?
Pixel perfect
Да уже как дома буду.
Ubuntu, apache, php, mysql. Есть сайт, который лежит в папке, весь на пхп. Вчера вообще не работал, но разобравшись добавил его базу данных, дал доступ и почти всё работает.
Теперь вместо кучи ошибок высвечивает одну:
Error: [Template [menu/before.tpl] not found!], [no number specified]
Сам файл лежит в /var/www/x/tpls/default/menu/, т.е. врод на месте, и всё что в нём написано это <ul>. Как решить? В каком направлении гуглить?
Решил перебрать элементы ассоциативного массива в другой массив и воспользовался циклом:
foreach ($sline as $s=>$a){
$linkcity[] =$a;
}
Потом подошел друг и сказал, что эт как-то не очень красиво выглядит и предложил воспользоваться функцией array_values.
Ну я не будь дураком, сразу последовал стороннему совету и написал:
$linkcity = array_values($sline);
Но че-то в результат нихрена не то выходит.
Где моя ошибка?
Ебать ты наркоман!
>
не то это что?
вообще обычно конструкцию с foreach используют в том случае, если нужно реализовать какую-то логику, например что-то провалидировать или переименовать и т.д.
в таком случае пишут так:
$linkcity = [];
foreach ($sline as $a) {
// логика
$linkcity[] =$a;
}
то есть определяют массив в начале.
array_values же используют исключительно для переиндексации.
что значит "не то"? сделай var_dump($sline) и посмотри, что там.
https://ideone.com/TGcqYH
break убери и исправь очепятку в 21 строчке.
>>18082
Не знаю, у меня всё получилось
https://ideone.com/IO0Stu
Смотри что за ошибка у тебя и сдампь переменные с помощью var_dump(...)
>>18247
Не правильно
Ты каждый раз заполняешь строку в ручную, а нужно делать это программно, чтобы программа работала с заведомо неизвестным количеством массивов и элементов, как я говорил выше, как это и зачастую и бывает
Строку можно складывать с помощью оператора .=
$s = 'Hello';
$s .= ' World';
http://php.net/manual/ru/language.operators.string.php
Желательно выделить публичную папку, а не выкладывать весь проект в нее.
> https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2/blob/master/composer.json
Имена неймспейсов желательно писать с большой буквы, хотя в PSR-4, такого требования вроде нет.
> https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2/blob/master/dump.sql
Ключевые слова языка SQL принято писать заглавными: http://www.sqlstyle.guide/ru/#зарезервированные-слова
id обычно идет первым в списке полей.
> passwordhash
> second_name
Слова надо разделять единообразно.
> the_group
Лучше просто добавить кавычки `group` (это в MySQL так, в стандарте SQL используется "group", ссылку на стандарт дать не могу, так как он стоит денег: http://modern-sql.com/standard , в общем доступе есть черновики стандарта 2011).
> token text null
Тут нужно бы добавить комменатрий и указать тип поля поменьше.
> $routeWithoutGETParam = $this->delGETParametersFromRoute($routes);
Используй лучше parse_url
> 'studlist\\controllers\\'.$routeWithoutGETParam[1].'Controller
На линуксе имена файлов чувствительны к регистру.
> private $title = '';
> private $db;
> private $searchData;
А зачем сохранять эти данные в поля класса? Не лучше ли просто сделать их локальными переменными?
> https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2/blob/master/model/Student/Student.php
> public $parameters = array('login' => '', 'email' => ''
Это я называю "массиво-ориентированное программирование". Ты тут используешь массив, хотя и пытаешься сделать видимость использования ООП. Почему бы не сделать объект со свойствами login, email и тд?
> public function setStudentParametersFromForm()
Модель в MVC не должна обращаться к параметрам HTTP запроса в $_POST. Также, посмотри, как странно выглядит код в контроллере:
> $this->student->setStudentParametersFromForm();
В метод ничего не передается, он откуда-то сам берет данные.
> $this->parameters[$name] = trim(htmlspecialchars($_POST[$name], ENT_QUOTES));
Зачем тут использован htmlspecialchars? Его используют при вставке текстовых данных в HTML код. Но здесь, в модели, мы еще не знаем, как будут использованы данные, будут ли они когда-нибудь вставляться в HTML-код. Зачем тогда использовать htmlspecialchars?
Плюс, у тебя нет никаких проверок, какие поля ты берешь из $_POST. В этой задаче это не проблема, но в другой ситуации это позволяет пользователю модифицировать любые поля, установить себе признак администратора, например.
> return $stmt->fetch(\PDO::FETCH_ASSOC)["passwordhash"];
Есть метод в PDOSTatement для получения единственного значения.
> if ($stmt->fetch(\PDO::FETCH_ASSOC)["COUNT(*)"])
То же самое.
> public function getStudentsForTable($orderByLimitOffset)
Здесь передается массив. Но нигде не описано, что это за массив, какие в нем могут быть аргументы. Лучше либо сделать отдельные аргументы, либо передавать объект.
> $stmt = $this->db->prepare("SELECT name, second_name, the_group, points
> ORDER BY $orderBy
Здесь значения вставляются напрямую в запрос без проверки - возможна SQL инъекциия.
> return $stmt->fetchAll(\PDO::FETCH_CLASS, 'studlist\model\Student\Student');
Эта команда не поместит значения из БД в массив $parameters внутри объекта.
https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2/blob/master/model/UsersTableGateway/UsersTableGateway.php#L107
Что это за странный способ обработки исключений? С каких пор модель делает куда-то редиректы?
> ПОЧЕМУ ЕСЛИ Я ДЕЛАЮ БИНД orderBy ТО сортировка не работает?
Потому, что значения плейсхолдеров вставляются в запрос в кавычках, вроде 'name', и получается фиксированная строка (по которой идет сортирвка), а не название колонки.
> public function VerificationFormsStudent
Имена функций принято начинать с глагола, сделайЧтоТо().
https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2/blob/master/model/Verification/Verification.php#L138
> static public function verificationLogined(UsersTableGateway $db): bool
Лучше внедрить объект $db в валидатор с помощью DI, через конструктор.
Также, непонятно, почему валидатор сам лезет в куки. Модель в MVC не должна напрямую обращаться к кукам. Перечитай внимательно урок по MVC.
И непонятно, зачем ты там обрабатываешь значения кук с помощью htmlspecialchars. Это ни от чего не защищает.
Я бы советовал тебе сделать задачку про экранирование отсюда https://github.com/codedokode/pasta/blob/master/soft/web-server.md#Экранирование чтобы лучше разобраться с разными видами экранирования данных.
> https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2/blob/master/model/Pager.php
Здесь, по моему, не очень удачно спроектирован обьъект. Там есть публичное поле, которое заполняет метод setPager(). Но, когда у тебя есть этот объект в переменной, ты не знаешь, был ли ранее вызван метод или нет, и не понимаешь, есть ли нужные данные в поле или нет. Это не позволяет писать надежный код.
Вместо поля лучше сделать метод getPageNumbers(), который гарантирванно возвращает нужные значения. Сделать поля приватными и использовать инкапсуляцию.
Что-то у тебя слабовато знание ООП. Ты не решал задачу про Гостиницу или про Продюсерское Агентство? Они есть в треде. Я бы советовал отвлечься и решить их.
https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2/blob/master/model/StudentsBox.php
Не очень понятно, зачем вообще нужен этот класс? Что моделирует объект этого класса, какую сущность?
https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2/blob/master/model/ViewRender.php
Тут явное нарушение принципа единой ответственности (каждый класс решает свою задачу, имеет свою зону ответственности) - класс отвечает и за вывод view, и за расчет пагинации, хотя это никак не связанные между собой задачи.
Не очень понятно, зачем здесь сделано разделение страницы на "заголовок" и "тело".
https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2/blob/master/controllers/TableController.php#L98
Непонятно, почему контроллер вывода списка студентов отвечает за разлогинивание или залогинивание.
> if ($_GET['orderBy'] != ('points' || 'the_group' || 'name' || 'second_name')) {
Это так не работает. Оператор || - это оператор, который возвращает true или false. http://php.net/manual/ru/language.operators.logical.php
Получается в итоге выражение вроде
if ($_GET[...] == true)
И это явно не то, что нужно. Тебе наверно подойдет in_array.
https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2/blob/master/controllers/ErrorController.php
для страницы ошибки нужно выдавать отличный от 200 код HTTP: https://ru.wikipedia.org/wiki/Список_кодов_состояния_HTTP
Если ты не знаком с HTTP, прочти мой урок по нему: https://github.com/codedokode/pasta/blob/master/network/http.md
Для залогинивания/разлогинивания пользователей желательно сделать отдельный класс.
https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2/blob/master/view/login.phtml
Не надо использовать echo, лучше использовать <?= ?>
https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2/blob/master/view/profile.phtml
не вижу здесь защиту от XSS.
эти 2 файла очень похожи:
- https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2/blob/master/view/profile.phtml
- https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2/blob/master/view/reg.phtml
не лучше ли сделать из них один?
> https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2/blob/master/view/table.phtml
Для формирования ссылок для сортировки или пагинации лучше сделать специальную функцию, а не делать это прямо в шаблоне. Также, символ & в HTML коде надо вписывать как & amp;
Желательно выделить публичную папку, а не выкладывать весь проект в нее.
> https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2/blob/master/composer.json
Имена неймспейсов желательно писать с большой буквы, хотя в PSR-4, такого требования вроде нет.
> https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2/blob/master/dump.sql
Ключевые слова языка SQL принято писать заглавными: http://www.sqlstyle.guide/ru/#зарезервированные-слова
id обычно идет первым в списке полей.
> passwordhash
> second_name
Слова надо разделять единообразно.
> the_group
Лучше просто добавить кавычки `group` (это в MySQL так, в стандарте SQL используется "group", ссылку на стандарт дать не могу, так как он стоит денег: http://modern-sql.com/standard , в общем доступе есть черновики стандарта 2011).
> token text null
Тут нужно бы добавить комменатрий и указать тип поля поменьше.
> $routeWithoutGETParam = $this->delGETParametersFromRoute($routes);
Используй лучше parse_url
> 'studlist\\controllers\\'.$routeWithoutGETParam[1].'Controller
На линуксе имена файлов чувствительны к регистру.
> private $title = '';
> private $db;
> private $searchData;
А зачем сохранять эти данные в поля класса? Не лучше ли просто сделать их локальными переменными?
> https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2/blob/master/model/Student/Student.php
> public $parameters = array('login' => '', 'email' => ''
Это я называю "массиво-ориентированное программирование". Ты тут используешь массив, хотя и пытаешься сделать видимость использования ООП. Почему бы не сделать объект со свойствами login, email и тд?
> public function setStudentParametersFromForm()
Модель в MVC не должна обращаться к параметрам HTTP запроса в $_POST. Также, посмотри, как странно выглядит код в контроллере:
> $this->student->setStudentParametersFromForm();
В метод ничего не передается, он откуда-то сам берет данные.
> $this->parameters[$name] = trim(htmlspecialchars($_POST[$name], ENT_QUOTES));
Зачем тут использован htmlspecialchars? Его используют при вставке текстовых данных в HTML код. Но здесь, в модели, мы еще не знаем, как будут использованы данные, будут ли они когда-нибудь вставляться в HTML-код. Зачем тогда использовать htmlspecialchars?
Плюс, у тебя нет никаких проверок, какие поля ты берешь из $_POST. В этой задаче это не проблема, но в другой ситуации это позволяет пользователю модифицировать любые поля, установить себе признак администратора, например.
> return $stmt->fetch(\PDO::FETCH_ASSOC)["passwordhash"];
Есть метод в PDOSTatement для получения единственного значения.
> if ($stmt->fetch(\PDO::FETCH_ASSOC)["COUNT(*)"])
То же самое.
> public function getStudentsForTable($orderByLimitOffset)
Здесь передается массив. Но нигде не описано, что это за массив, какие в нем могут быть аргументы. Лучше либо сделать отдельные аргументы, либо передавать объект.
> $stmt = $this->db->prepare("SELECT name, second_name, the_group, points
> ORDER BY $orderBy
Здесь значения вставляются напрямую в запрос без проверки - возможна SQL инъекциия.
> return $stmt->fetchAll(\PDO::FETCH_CLASS, 'studlist\model\Student\Student');
Эта команда не поместит значения из БД в массив $parameters внутри объекта.
https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2/blob/master/model/UsersTableGateway/UsersTableGateway.php#L107
Что это за странный способ обработки исключений? С каких пор модель делает куда-то редиректы?
> ПОЧЕМУ ЕСЛИ Я ДЕЛАЮ БИНД orderBy ТО сортировка не работает?
Потому, что значения плейсхолдеров вставляются в запрос в кавычках, вроде 'name', и получается фиксированная строка (по которой идет сортирвка), а не название колонки.
> public function VerificationFormsStudent
Имена функций принято начинать с глагола, сделайЧтоТо().
https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2/blob/master/model/Verification/Verification.php#L138
> static public function verificationLogined(UsersTableGateway $db): bool
Лучше внедрить объект $db в валидатор с помощью DI, через конструктор.
Также, непонятно, почему валидатор сам лезет в куки. Модель в MVC не должна напрямую обращаться к кукам. Перечитай внимательно урок по MVC.
И непонятно, зачем ты там обрабатываешь значения кук с помощью htmlspecialchars. Это ни от чего не защищает.
Я бы советовал тебе сделать задачку про экранирование отсюда https://github.com/codedokode/pasta/blob/master/soft/web-server.md#Экранирование чтобы лучше разобраться с разными видами экранирования данных.
> https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2/blob/master/model/Pager.php
Здесь, по моему, не очень удачно спроектирован обьъект. Там есть публичное поле, которое заполняет метод setPager(). Но, когда у тебя есть этот объект в переменной, ты не знаешь, был ли ранее вызван метод или нет, и не понимаешь, есть ли нужные данные в поле или нет. Это не позволяет писать надежный код.
Вместо поля лучше сделать метод getPageNumbers(), который гарантирванно возвращает нужные значения. Сделать поля приватными и использовать инкапсуляцию.
Что-то у тебя слабовато знание ООП. Ты не решал задачу про Гостиницу или про Продюсерское Агентство? Они есть в треде. Я бы советовал отвлечься и решить их.
https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2/blob/master/model/StudentsBox.php
Не очень понятно, зачем вообще нужен этот класс? Что моделирует объект этого класса, какую сущность?
https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2/blob/master/model/ViewRender.php
Тут явное нарушение принципа единой ответственности (каждый класс решает свою задачу, имеет свою зону ответственности) - класс отвечает и за вывод view, и за расчет пагинации, хотя это никак не связанные между собой задачи.
Не очень понятно, зачем здесь сделано разделение страницы на "заголовок" и "тело".
https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2/blob/master/controllers/TableController.php#L98
Непонятно, почему контроллер вывода списка студентов отвечает за разлогинивание или залогинивание.
> if ($_GET['orderBy'] != ('points' || 'the_group' || 'name' || 'second_name')) {
Это так не работает. Оператор || - это оператор, который возвращает true или false. http://php.net/manual/ru/language.operators.logical.php
Получается в итоге выражение вроде
if ($_GET[...] == true)
И это явно не то, что нужно. Тебе наверно подойдет in_array.
https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2/blob/master/controllers/ErrorController.php
для страницы ошибки нужно выдавать отличный от 200 код HTTP: https://ru.wikipedia.org/wiki/Список_кодов_состояния_HTTP
Если ты не знаком с HTTP, прочти мой урок по нему: https://github.com/codedokode/pasta/blob/master/network/http.md
Для залогинивания/разлогинивания пользователей желательно сделать отдельный класс.
https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2/blob/master/view/login.phtml
Не надо использовать echo, лучше использовать <?= ?>
https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2/blob/master/view/profile.phtml
не вижу здесь защиту от XSS.
эти 2 файла очень похожи:
- https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2/blob/master/view/profile.phtml
- https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2/blob/master/view/reg.phtml
не лучше ли сделать из них один?
> https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist2/blob/master/view/table.phtml
Для формирования ссылок для сортировки или пагинации лучше сделать специальную функцию, а не делать это прямо в шаблоне. Также, символ & в HTML коде надо вписывать как & amp;
> if (($credit + $percent
на процент надо умножать, а не складывать.
> if (($credit + $percent + $tax) < $max)
> $max = $credit * $percent + $tax;
Этот if можно заменить на функцию min() или max(), сможешь? Надо сделать так:
выплата за этот месяц = наименьшему из (сколько осталось долга, сколько может заплатить школьник)
Также, у тебя break всегда срабатывает в конце первого шага (месяца) и делает выход из циклаю
>>18202
По идее твой цикл действительно можно заменить на array_values. Исопльзуй var_dump и посмотри, что в какой переменной, чтобы понять, где проблема.
>>18247
Тут много однообразного кода. Давай я тебе дам подсказку:
// варианты первого слова
$words1 = ['...', '...', '...'];
// варианты второго слова
$words2 - [..., ..., ...];
// массив, содержащий массивы слов
$allWords = [$words1, $words2, ...];
// Идем по массиву массивов слов и на каждом шаге выбираем 1 слово
foreach ($allWords as $variants) {
var_dump($variants);
}
>>18201
Скорее всего, он ищет файл не в той папке. С помощью var_dump выведи текущую папку (getcwd()) и путь к шаблону, который он пытается подключить.
> if (($credit + $percent
на процент надо умножать, а не складывать.
> if (($credit + $percent + $tax) < $max)
> $max = $credit * $percent + $tax;
Этот if можно заменить на функцию min() или max(), сможешь? Надо сделать так:
выплата за этот месяц = наименьшему из (сколько осталось долга, сколько может заплатить школьник)
Также, у тебя break всегда срабатывает в конце первого шага (месяца) и делает выход из циклаю
>>18202
По идее твой цикл действительно можно заменить на array_values. Исопльзуй var_dump и посмотри, что в какой переменной, чтобы понять, где проблема.
>>18247
Тут много однообразного кода. Давай я тебе дам подсказку:
// варианты первого слова
$words1 = ['...', '...', '...'];
// варианты второго слова
$words2 - [..., ..., ...];
// массив, содержащий массивы слов
$allWords = [$words1, $words2, ...];
// Идем по массиву массивов слов и на каждом шаге выбираем 1 слово
foreach ($allWords as $variants) {
var_dump($variants);
}
>>18201
Скорее всего, он ищет файл не в той папке. С помощью var_dump выведи текущую папку (getcwd()) и путь к шаблону, который он пытается подключить.
Есть расширения к браузеру, которые позволяют наложить полупрозрачную картинку поверх сайта. Ну или ты можешь сделать скриншот и сравнить. Или развивать глазомер. Или переключаться альт-табом между браузером и макетом. Или вывести их бок-о-бок, если у тебя большой монитор.
Вообще, во многих случаях попиксельной точности не требуется, но нужно, чтобы выдерждивалась сетка, поля, отступы, заданные в макете. Дело в том, что в разных ОС шрифты рендерятся немного по-разному и длина/высота строки текста может отличаться на несколько пикселей.
>>18155
Подстановка переменных напрямую в запрос создает риск SQL инъекции. Подстановка через плейсхолдеры предотвращает уязвимость. Урок https://github.com/codedokode/pasta/blob/master/security/sql-injection.md
>>18154
При отдаче ошибок очень важно разделять виды ошибок:
- есть ошибки, которые можно показать пользователю (вы ввели 5 символов, но пароль должен содержать не менее 8)
- есть детали, которые нельзя показывать пользователю, из соображений безопасности, и потому, что он их не поймет: "Не удалось подсоединиться к БД по адресу 10.0.0.1 с логином user и паролем 123456". Вместо таких ошибок нужно отдавать общее сообщение вроде "Произошла ошибка на сервере".
Потому не стоит, например, преобразовывать все исключения в объекты Error и отдавать их JSON. Но допустимо сделать интерфейс или базовый класс для исключений, которые сигнализируют об ошибке выполнения API запроса и корректно скрывают данные.
> Подскажите, хорошая ли идея взять за стандарт JSONAPI для обмена сообщениями между клиентом и api
Думаю, да, лучше брать что-то готовое, чем изобретать велосипед.
> в частности сделать php класс Error со свойствами как в Error Object ... и создавать по такому на каждую ошибку валидации поля формы?
Вообще, тут есть варианты - можно сделать класс специально для JSONAPI, а можно сделать класс для ошибок валидатора и настроить для него маппинг в JSON-объект. С одной стороны, если валидатор отдает объект, завязанный на JSON, то он превращается из валидатора общего назначения в валидатор специально для API на JSON, с другой стороны, если делать отдельно класс ошибки валидатора и отдельно класс ошибки для JSON, получается лишняя писанина.
Мне нравится идея класса, представляющего ошибку, который можно преобразовать в JSON-объект.
> Для привязки валидационной ошибки соответствующему полю формы в Error Object нужно указывать имя поля, походит ли source/parameter?
parameter это имя параметра из query string. Если у тебя API и ты отправляешь данные формы JSON то логичнее использовать source/pointer и указать им на элемент в отправленных на сервер данных.
А вообще, попробуй использовать этот стандарт, напиши потом, что вышло, какие подвохи. Я про него первый раз слышу, и за счет тебя смогу, ничего не делая, изучить его подводные камни ;)
Также, при отображении ошибки надо предусмотреть ситуацию, когда в source не указано поле или указано невидимое/несуществующее поле и все равно вывести сообщение.
Есть расширения к браузеру, которые позволяют наложить полупрозрачную картинку поверх сайта. Ну или ты можешь сделать скриншот и сравнить. Или развивать глазомер. Или переключаться альт-табом между браузером и макетом. Или вывести их бок-о-бок, если у тебя большой монитор.
Вообще, во многих случаях попиксельной точности не требуется, но нужно, чтобы выдерждивалась сетка, поля, отступы, заданные в макете. Дело в том, что в разных ОС шрифты рендерятся немного по-разному и длина/высота строки текста может отличаться на несколько пикселей.
>>18155
Подстановка переменных напрямую в запрос создает риск SQL инъекции. Подстановка через плейсхолдеры предотвращает уязвимость. Урок https://github.com/codedokode/pasta/blob/master/security/sql-injection.md
>>18154
При отдаче ошибок очень важно разделять виды ошибок:
- есть ошибки, которые можно показать пользователю (вы ввели 5 символов, но пароль должен содержать не менее 8)
- есть детали, которые нельзя показывать пользователю, из соображений безопасности, и потому, что он их не поймет: "Не удалось подсоединиться к БД по адресу 10.0.0.1 с логином user и паролем 123456". Вместо таких ошибок нужно отдавать общее сообщение вроде "Произошла ошибка на сервере".
Потому не стоит, например, преобразовывать все исключения в объекты Error и отдавать их JSON. Но допустимо сделать интерфейс или базовый класс для исключений, которые сигнализируют об ошибке выполнения API запроса и корректно скрывают данные.
> Подскажите, хорошая ли идея взять за стандарт JSONAPI для обмена сообщениями между клиентом и api
Думаю, да, лучше брать что-то готовое, чем изобретать велосипед.
> в частности сделать php класс Error со свойствами как в Error Object ... и создавать по такому на каждую ошибку валидации поля формы?
Вообще, тут есть варианты - можно сделать класс специально для JSONAPI, а можно сделать класс для ошибок валидатора и настроить для него маппинг в JSON-объект. С одной стороны, если валидатор отдает объект, завязанный на JSON, то он превращается из валидатора общего назначения в валидатор специально для API на JSON, с другой стороны, если делать отдельно класс ошибки валидатора и отдельно класс ошибки для JSON, получается лишняя писанина.
Мне нравится идея класса, представляющего ошибку, который можно преобразовать в JSON-объект.
> Для привязки валидационной ошибки соответствующему полю формы в Error Object нужно указывать имя поля, походит ли source/parameter?
parameter это имя параметра из query string. Если у тебя API и ты отправляешь данные формы JSON то логичнее использовать source/pointer и указать им на элемент в отправленных на сервер данных.
А вообще, попробуй использовать этот стандарт, напиши потом, что вышло, какие подвохи. Я про него первый раз слышу, и за счет тебя смогу, ничего не делая, изучить его подводные камни ;)
Также, при отображении ошибки надо предусмотреть ситуацию, когда в source не указано поле или указано невидимое/несуществующее поле и все равно вывести сообщение.
Ты пишешь foreach ($x as $k => $v) только если тебе нужен ключ $k. Если он не нужен, не пиши его. Это облечает чтение кода, не надо смотреть, как используется переменная $k.
> Разница между ними только в том, что в первом случае я могу делать манипуляцию И с ключом И со значением или же есть что-то ещё?
Разница только в том, что тебе не передается значение ключа текущего элемента.
> Если я собираюсь перебрать значения взятые из БД, мне стоит юзать foreach или while?
Лучше использовать fetchAll(). Не надо в одном месте кода получать значения из БД и тут же их выводить, почитай про шаблоны: https://github.com/codedokode/pasta/blob/master/php/templates.md
>>18078
Она дает одну и ту же картинку разным людям и сравнивает результаты. Там ведь еще бывает так, что непонятно, машина это вдали или что-то другое и на одну и ту же картинку могут приходить разные ответы. Это, я думаю, учитывается, по распределению ответов от разных людей.
Может, конечно, они и не используют эти данные, но по моему глупо отказываться от бесплатных размечальщиков. Раньше, я помню, там были куски текста из старых газет и фото улиц из Google Maps.
>>18076
У тебя по моему опечатка. В первой строке ты берешь 4 случайных ключа из массива $words['word1'], но во второй строке пытаешься взять элемент из другого массива $words['word'] (без цифры 1).
Также, если в массиве меньше 4 элементов, то взять 4 случайных ключа не получится.
>>18072
да:
$days = ['Понедельник', 'Вторник'];
$number = 0;
echo $days[$number];
>>18062
Метод fetch_array возвращает текущую строку результата, и передвигает "курсор" (указатель на текущую строку в результате) на следующую строку.
Ты пишешь foreach ($x as $k => $v) только если тебе нужен ключ $k. Если он не нужен, не пиши его. Это облечает чтение кода, не надо смотреть, как используется переменная $k.
> Разница между ними только в том, что в первом случае я могу делать манипуляцию И с ключом И со значением или же есть что-то ещё?
Разница только в том, что тебе не передается значение ключа текущего элемента.
> Если я собираюсь перебрать значения взятые из БД, мне стоит юзать foreach или while?
Лучше использовать fetchAll(). Не надо в одном месте кода получать значения из БД и тут же их выводить, почитай про шаблоны: https://github.com/codedokode/pasta/blob/master/php/templates.md
>>18078
Она дает одну и ту же картинку разным людям и сравнивает результаты. Там ведь еще бывает так, что непонятно, машина это вдали или что-то другое и на одну и ту же картинку могут приходить разные ответы. Это, я думаю, учитывается, по распределению ответов от разных людей.
Может, конечно, они и не используют эти данные, но по моему глупо отказываться от бесплатных размечальщиков. Раньше, я помню, там были куски текста из старых газет и фото улиц из Google Maps.
>>18076
У тебя по моему опечатка. В первой строке ты берешь 4 случайных ключа из массива $words['word1'], но во второй строке пытаешься взять элемент из другого массива $words['word'] (без цифры 1).
Также, если в массиве меньше 4 элементов, то взять 4 случайных ключа не получится.
>>18072
да:
$days = ['Понедельник', 'Вторник'];
$number = 0;
echo $days[$number];
>>18062
Метод fetch_array возвращает текущую строку результата, и передвигает "курсор" (указатель на текущую строку в результате) на следующую строку.
> $rand_keys = array_rand($words['word1'], 1);
Читай мануал http://php.net/manual/ru/function.array-rand.php
Если ты указал, что тебе нужен 1 ключ, то array_rand вернет не массив с 1 элементом, а сам ключ.
Это, кстати, пример неудачного проектирования функции. Лучше, когда функция всегда возвращает результат одного типа, если массив - то всегда массив. Как видишь, выбранный разработчиками PHP подход приводит к ошибкам. Не бери с них пример.
>>18055
Увы, тут наверно надо лезть в код Симфони (может быть HttpKernel?), чтобы понять, почему. За создание и вызов контроллера отвечает HttpKernel в компоненте http-kernel. Напомню, что компонент - это независимая от Симфони библиотека, и в Симфони настройки для этого компонента (в том числе аргументы для сервисов) задаются в бандле https://github.com/symfony/framework-bundle
- https://symfony.com/doc/current/components/http_kernel.html
- https://github.com/symfony/http-kernel/blob/master/HttpKernel.php#L132
- https://github.com/symfony/http-kernel/blob/master/Controller/ControllerResolver.php#L33
- https://github.com/symfony/http-kernel/blob/master/Controller/ArgumentResolver.php
Мы видим, что поведение HttpKernel и резолверов определяется тем, с какими аргументами они были созданы. Потому мы должны открыть исходники FrameworkBundle и найти место, где создаются объекты этих классов. В данном случае они опсианы в конфиге DI контейнера как сервисы (если ты не знаком с DI контейнером в Симфони, то познакомься):
- https://github.com/symfony/framework-bundle/blob/master/Resources/config/services.xml#L21
Здесь мы видим отсылку к сервису argument_resolver. Поищем его определение и код:
- https://github.com/symfony/framework-bundle/search?utf8=✓&q=argument_resolver&type=
- https://github.com/symfony/framework-bundle/blob/8089ce7d84e6fd96531b0b2fab20977b7b7b968e/Resources/config/web.xml#L24
- https://github.com/symfony/http-kernel/blob/master/Controller/ArgumentResolver.php
Вторым аргументом в конструкторе указано
> iterable $argumentValueResolvers = array()
Но в описании сервиса там нет значений, лишь строка
> <argument /> <!-- argument value resolvers -->
А ниже мы видим странные сервисы:
> <service id="argument_resolver.request_attribute
> <service id="argument_resolver.request"
....
Это неспроста. Используя опыт и интуицию, я открыл главный класс бандла, чтобы посмотреть, что именно бандла делает, на какие события подписывается, как вмешивается в процесс конфигурации, и не прогадал:
https://github.com/symfony/framework-bundle/blob/8089ce7d84e6fd96531b0b2fab20977b7b7b968e/FrameworkBundle.php
> $container->addCompilerPass(new RegisterControllerArgumentLocatorsPass());
> $container->addCompilerPass(new ControllerArgumentValueResolverPass());
Бандл добавляет свои этапы в процесс компиляции контейнера на основе конфигов бандлов и конфигов пользователя (прочитай про это, если не знаешь). Если мы посмотрим эти классы, то увидим:
https://github.com/symfony/http-kernel/blob/master/DependencyInjection/ControllerArgumentValueResolverPass.php
Этот класс при сборке контейнера находит сервисы, помеченные определенным тегом, и добавляет массив их как аргумент для arguments_resolver.
Второй класс, влияющий на ход сборки контейнера - это https://github.com/symfony/http-kernel/blob/master/DependencyInjection/RegisterControllerArgumentLocatorsPass.php
Предлагаю тебе самому изучить все перечисленные ссылки и попробовать найти причину проблемы. Если не найдешь - пиши.
Это тяжело поначалу, но поможет тебе всерьез разобраться в Симфони.
> $rand_keys = array_rand($words['word1'], 1);
Читай мануал http://php.net/manual/ru/function.array-rand.php
Если ты указал, что тебе нужен 1 ключ, то array_rand вернет не массив с 1 элементом, а сам ключ.
Это, кстати, пример неудачного проектирования функции. Лучше, когда функция всегда возвращает результат одного типа, если массив - то всегда массив. Как видишь, выбранный разработчиками PHP подход приводит к ошибкам. Не бери с них пример.
>>18055
Увы, тут наверно надо лезть в код Симфони (может быть HttpKernel?), чтобы понять, почему. За создание и вызов контроллера отвечает HttpKernel в компоненте http-kernel. Напомню, что компонент - это независимая от Симфони библиотека, и в Симфони настройки для этого компонента (в том числе аргументы для сервисов) задаются в бандле https://github.com/symfony/framework-bundle
- https://symfony.com/doc/current/components/http_kernel.html
- https://github.com/symfony/http-kernel/blob/master/HttpKernel.php#L132
- https://github.com/symfony/http-kernel/blob/master/Controller/ControllerResolver.php#L33
- https://github.com/symfony/http-kernel/blob/master/Controller/ArgumentResolver.php
Мы видим, что поведение HttpKernel и резолверов определяется тем, с какими аргументами они были созданы. Потому мы должны открыть исходники FrameworkBundle и найти место, где создаются объекты этих классов. В данном случае они опсианы в конфиге DI контейнера как сервисы (если ты не знаком с DI контейнером в Симфони, то познакомься):
- https://github.com/symfony/framework-bundle/blob/master/Resources/config/services.xml#L21
Здесь мы видим отсылку к сервису argument_resolver. Поищем его определение и код:
- https://github.com/symfony/framework-bundle/search?utf8=✓&q=argument_resolver&type=
- https://github.com/symfony/framework-bundle/blob/8089ce7d84e6fd96531b0b2fab20977b7b7b968e/Resources/config/web.xml#L24
- https://github.com/symfony/http-kernel/blob/master/Controller/ArgumentResolver.php
Вторым аргументом в конструкторе указано
> iterable $argumentValueResolvers = array()
Но в описании сервиса там нет значений, лишь строка
> <argument /> <!-- argument value resolvers -->
А ниже мы видим странные сервисы:
> <service id="argument_resolver.request_attribute
> <service id="argument_resolver.request"
....
Это неспроста. Используя опыт и интуицию, я открыл главный класс бандла, чтобы посмотреть, что именно бандла делает, на какие события подписывается, как вмешивается в процесс конфигурации, и не прогадал:
https://github.com/symfony/framework-bundle/blob/8089ce7d84e6fd96531b0b2fab20977b7b7b968e/FrameworkBundle.php
> $container->addCompilerPass(new RegisterControllerArgumentLocatorsPass());
> $container->addCompilerPass(new ControllerArgumentValueResolverPass());
Бандл добавляет свои этапы в процесс компиляции контейнера на основе конфигов бандлов и конфигов пользователя (прочитай про это, если не знаешь). Если мы посмотрим эти классы, то увидим:
https://github.com/symfony/http-kernel/blob/master/DependencyInjection/ControllerArgumentValueResolverPass.php
Этот класс при сборке контейнера находит сервисы, помеченные определенным тегом, и добавляет массив их как аргумент для arguments_resolver.
Второй класс, влияющий на ход сборки контейнера - это https://github.com/symfony/http-kernel/blob/master/DependencyInjection/RegisterControllerArgumentLocatorsPass.php
Предлагаю тебе самому изучить все перечисленные ссылки и попробовать найти причину проблемы. Если не найдешь - пиши.
Это тяжело поначалу, но поможет тебе всерьез разобраться в Симфони.
Тут надо учитывать такие особенности.
Во-первых, для каждой колонки БД задан collation - правила сравнения символов. collation определяет как сортируются записи по алфавиту, и какие символы при сравнении считаются одинаковыми. даже если ты не задавал явно collation, он все равно есть, и берется из настроек таблицы, базы данных или конфига mysql.
- https://dev.mysql.com/doc/refman/5.7/en/charset-general.html (англ)
- http://gahcep.github.io/blog/2013/01/05/mysql-utf8/
- http://itif.ru/kodirovka-mysql-kak-izbezhat-oshibok/
И когда ты пишешь WHERE column = ?, сравнение происходит в соответствии с заданным для колонки collation. То же относится к случаю WHERE column LIKE ?.
Выясни, какой collation используется для колонки в твоей таблице. Для этого есть ( https://stackoverflow.com/questions/7617412/discover-collation-of-a-mysql-column ) запрос вроде
SHOW TABLE STATUS ... и SHOW FULL COLUMNS ...
Казалось бы, то же относится и к регуляркам. Но не тут-то было:
- https://dev.mysql.com/doc/refman/5.7/en/regexp.html (англ)
> The REGEXP and RLIKE operators work in byte-wise fashion, so they are not multibyte safe and may produce unexpected results with multibyte character sets. In addition, these operators compare characters by their byte values and accented characters may not compare as equal even if a given collation treats them as equal.
То есть, регулярка работает на уровне байт и большая/маленькая буква для нее разные, независимо от collation. Плюс, она вообще не гарантирует корректной работы с мультибайтовыми кодировками (включая utf-8), а по сути корректно поддерживает только латиницу. Так-то. Баг зарепорчен 10 лет назад, но не исправляется:
- https://bugs.mysql.com/bug.php?id=30241
- https://bugs.mysql.com/bug.php?id=63439
Как видно, там рекомендуют поставить UDF (расширение) к mysql для поддержки юникода в регулярках. Ну или, как альтернатива, можно использовать другую СУБД.
Мой урок про кодировки (не в mysql, а вообще, что это такое): https://github.com/codedokode/pasta/blob/master/cs/strings.md
>>17573
> public function changeRank
Традиционно такие функции называют setRank (функция-сеттер).
> if ($this->isBoss == TRUE){
Можно просто if ($this->isBoss), if как раз проверяет выражение на равенство true/false.
Раз уж ты сделал классы профессий, можно было дял них задать и зарплату по умолчанию.
> public function getWorker(int $number): AbstractWorker
Мне не нравится эта функция. Чтобы получить работника, нам надо где-то взять его номер, а где? Я не вижу в классе работника функции получения номера. Как ей вообще пользоваться?
> public function deleteWorker(int $number): void
Та же проблема.
> public function sortWorkers(): void
непонятно назначение этой функции. Вот я смотрю только на класс Departament, не вижу остальной код, и мне даже в голову не приходит, зачем она нужна. И по какому критерию сортирует работников. По алфавиту?
> class Company
...
> $cloneOfDepartment = new Department($department->getName());
> foreach ($department->getWorkers() as $worker) {
> $cloneOfDepartment->addWorker(clone $worker);
Нарушение зон ответственности: почему класс Company заботится о клонировании содержимого департамента? Будет проблема, что при вызове
clone $company
работники клонируются, а при вызове
clone $department
не клонируются. за клонирование департамента должен отвечать код внутри этого класса.
> throw new Exception("Введено ошибочное название профессии");
В сообщение об ошибке стоит добавить, какое именно название было указано.
> class AnticrisisService
> public function cutEngineers(Company $basicCompany): void
Этот метод делает слишком много:
- клонирует Компанию
- применяет меры
- выводит отчет
Это неправильно. Что, если мы хотим применить 2 антикризисные меры, а только потом вывести отчет? Что, если мы не хотим создавать копию Компании?
Клонирование допустимо, но тогда метод должен возвращать новую копию.
Алгоритм отбора инженеров сложный, содержит следы копипасты, тяжело понять, есть ли в нем ошибки, и легко их не заметить. Предлагаю упростить так:
- отбираем работников (для этого можно сделать метод в Департаменте), соответствующих критериям
- сортируем их по приоритету, чтобы вначале шли наименее ценные (usort)
- отбираем из списка первые N работников (array_slice)
- увольняем
> if (get_class($worker) == Engineer::class
Может, лучше использовать instanceof?
Для замены босса я бы предложил сделать готовый метод в Департаменте, а не руками менять статусы. Очевидно, что этот метод может еще где-то пригодиться.
Могу похвалить за расстановку тайп-хинтов, с ними код смотрится хорошо. До антикризисных мер все выглядит очень аккуратно.
Тут надо учитывать такие особенности.
Во-первых, для каждой колонки БД задан collation - правила сравнения символов. collation определяет как сортируются записи по алфавиту, и какие символы при сравнении считаются одинаковыми. даже если ты не задавал явно collation, он все равно есть, и берется из настроек таблицы, базы данных или конфига mysql.
- https://dev.mysql.com/doc/refman/5.7/en/charset-general.html (англ)
- http://gahcep.github.io/blog/2013/01/05/mysql-utf8/
- http://itif.ru/kodirovka-mysql-kak-izbezhat-oshibok/
И когда ты пишешь WHERE column = ?, сравнение происходит в соответствии с заданным для колонки collation. То же относится к случаю WHERE column LIKE ?.
Выясни, какой collation используется для колонки в твоей таблице. Для этого есть ( https://stackoverflow.com/questions/7617412/discover-collation-of-a-mysql-column ) запрос вроде
SHOW TABLE STATUS ... и SHOW FULL COLUMNS ...
Казалось бы, то же относится и к регуляркам. Но не тут-то было:
- https://dev.mysql.com/doc/refman/5.7/en/regexp.html (англ)
> The REGEXP and RLIKE operators work in byte-wise fashion, so they are not multibyte safe and may produce unexpected results with multibyte character sets. In addition, these operators compare characters by their byte values and accented characters may not compare as equal even if a given collation treats them as equal.
То есть, регулярка работает на уровне байт и большая/маленькая буква для нее разные, независимо от collation. Плюс, она вообще не гарантирует корректной работы с мультибайтовыми кодировками (включая utf-8), а по сути корректно поддерживает только латиницу. Так-то. Баг зарепорчен 10 лет назад, но не исправляется:
- https://bugs.mysql.com/bug.php?id=30241
- https://bugs.mysql.com/bug.php?id=63439
Как видно, там рекомендуют поставить UDF (расширение) к mysql для поддержки юникода в регулярках. Ну или, как альтернатива, можно использовать другую СУБД.
Мой урок про кодировки (не в mysql, а вообще, что это такое): https://github.com/codedokode/pasta/blob/master/cs/strings.md
>>17573
> public function changeRank
Традиционно такие функции называют setRank (функция-сеттер).
> if ($this->isBoss == TRUE){
Можно просто if ($this->isBoss), if как раз проверяет выражение на равенство true/false.
Раз уж ты сделал классы профессий, можно было дял них задать и зарплату по умолчанию.
> public function getWorker(int $number): AbstractWorker
Мне не нравится эта функция. Чтобы получить работника, нам надо где-то взять его номер, а где? Я не вижу в классе работника функции получения номера. Как ей вообще пользоваться?
> public function deleteWorker(int $number): void
Та же проблема.
> public function sortWorkers(): void
непонятно назначение этой функции. Вот я смотрю только на класс Departament, не вижу остальной код, и мне даже в голову не приходит, зачем она нужна. И по какому критерию сортирует работников. По алфавиту?
> class Company
...
> $cloneOfDepartment = new Department($department->getName());
> foreach ($department->getWorkers() as $worker) {
> $cloneOfDepartment->addWorker(clone $worker);
Нарушение зон ответственности: почему класс Company заботится о клонировании содержимого департамента? Будет проблема, что при вызове
clone $company
работники клонируются, а при вызове
clone $department
не клонируются. за клонирование департамента должен отвечать код внутри этого класса.
> throw new Exception("Введено ошибочное название профессии");
В сообщение об ошибке стоит добавить, какое именно название было указано.
> class AnticrisisService
> public function cutEngineers(Company $basicCompany): void
Этот метод делает слишком много:
- клонирует Компанию
- применяет меры
- выводит отчет
Это неправильно. Что, если мы хотим применить 2 антикризисные меры, а только потом вывести отчет? Что, если мы не хотим создавать копию Компании?
Клонирование допустимо, но тогда метод должен возвращать новую копию.
Алгоритм отбора инженеров сложный, содержит следы копипасты, тяжело понять, есть ли в нем ошибки, и легко их не заметить. Предлагаю упростить так:
- отбираем работников (для этого можно сделать метод в Департаменте), соответствующих критериям
- сортируем их по приоритету, чтобы вначале шли наименее ценные (usort)
- отбираем из списка первые N работников (array_slice)
- увольняем
> if (get_class($worker) == Engineer::class
Может, лучше использовать instanceof?
Для замены босса я бы предложил сделать готовый метод в Департаменте, а не руками менять статусы. Очевидно, что этот метод может еще где-то пригодиться.
Могу похвалить за расстановку тайп-хинтов, с ними код смотрится хорошо. До антикризисных мер все выглядит очень аккуратно.
Переходите в новый тред >>1118555 (OP)
Если я кому-то не ответил, напомните о себе в новом треде.
Я не смог применить эти функции, у меня с ними не работает и я так до конца и не понял, каким образом их использовать.
>>18475
>Ты каждый раз заполняешь строку в ручную, а нужно делать это программно, чтобы программа работала с заведомо неизвестным количеством массивов и элементов
Ну эту проблему я тоже не смог решить, до оепратора точка не додумался.
>>18548
>// Идем по массиву массивов слов и на каждом шаге выбираем 1 слово
foreach ($allWords as $variants) {
var_dump($variants);
}
Но как он будет случайные слова подбирать? Он же их просто перебирает.
Занятных глаз долины края
Я обретаю начертанья"
Как в этой задачке про строки выдавать разные слова для первых двух строк, чтоб не так дико звучало? Спасибо.
Часть на шарпе я то напишу, но вот с пхп не знаю, что делать ;d
Гуглом пользоваться умею, там все советы по загрузке файла со страницы товара.
Дебил, это решается простым листингом файлов средствами веб-сервера. Пикрилейтед как раз то, что тебе нужно.
А что с пдф то происходит? Он в браузере открывается или что? Пиздец ты формулируешь мысль, аж кровь из глаз.
Установил я apache после теста сервера выбилась такая хуйня что делать?
Выкладывай httpd.conf. Ты неправильно задал имя папки ServerRoot. Апач же тебе написал, где ты проебался.
Ты чо сын шлюхи меня в суе поминаешь?! Я же русским языком тому петуху написал, что ему нужно и ты собака сутулая мне же пишешь тоже самое. Ты охуел что ли выродок?
Это копия, сохраненная 14 февраля 2018 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.