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

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

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

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

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

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

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

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

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

С чего начать

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

Устанавливать пока что ничего не требуется, разве что редактор кода вроде 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

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

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

Также, у нас есть задачи которые позволят тебе изучить или подтянуть до нормального уровня знания 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
- Новости IT на англ. https://news.ycombinator.com/

Оформляй код аккуратно!!! — например пропусти через phpformatter.com . Также, если ты пользуешься IDE вроде PhpStorm, Netbeans, Eclipse, то в них эта опция встроена, подробнее: https://gist.github.com/codedokode/8759492

У ОПа нет аккаунтов и групп вконтакте, в фейсбуке, в твиттере, все "пхп-треды" там поддельные.

Платиновые вопросы

- Почему PHP? Потому что вакансий море, и учить легко.
- Сайт опять упал!!!!! — Не паникуй, а открой http://rghost.ru/6bfCY9lfl и получи личную немного устаревшую оффлайновую копию сайта (можно читать хоть на андроиде без интернета)
- Что надо знать чтобы найти работу - разработчику: PHP, SQL, HTML/CSS, JS, ООП, Git, композер, MVC, фреймворк. Верстальщику - HTML/CSS, JS, jQuery. У нас в треде были люди, которые практически с нуля учились и смогли найти работу.
- Что будут спрашивать на собеседовании если 0 опыта - гонять по теории, по официальному мануалу PHP, давать дурацкие задачки на переворачивание строк, гонять по SQL (транзакции, внешние ключи, напиши запрос), по JS (как сделать анимацию при нажатии кнопки), ну погугли, не ленись
- Можно подробнее про поиск работы, собеседования - нет, ОП писать не будет, но может кто из анонов захочет рассказать. Поищите тред перезвонивших, а также раздел /wrk/
- Сколько времени надо изучать все это? - все зависит от тебя, но не меньше 6-8 месяцев
- Нужен ли ООП, фреймворки, MVC, git, composer? — Да, однозначно. Посмотри любую вакансию.
grammar-nazi.png56 Кб, 500x644
Оформляйте код будьте людьми 2 1135054
Код нужно писать не как попало, а аккуратно и по правилам. Почему? Потому, что на неакуратно написанный код не хочется даже смотреть.

Если тебе лень выравнивать код руками, закачай его на http://beta.phpformatter.com/ и нажми «format». Робот исправит выравнивание и отступы в мгновение ока (да, прогресс не стоит на месте). Если ты используешь мощную IDE вроде PhpStorm, там тоже есть функция форматирования кода.

Горячие клавиши для форматирования кода в разных IDE: https://gist.github.com/codedokode/8759492

Вообще, в PHP долгое время не было единого стандарта оформления кода, все писали как попало и было много бардака, но сейчас дело лучше — есть стандарты PSR-1 и 2. Вот как надо оформлять код:

- переменные и функции пишутся с маленькой буквы, подчеркивание не используется, используется camelCase, пример: $x, $numberOfPeople, printResults()
- Название функции начинается с глагола, в стиле «сделайЧтоТо»
- не знаешь английский? Не беда, в 21 веке есть решение этой проблемы. Не пиши транслитом, открой лучше Гугл Транслейт или slovari.yandex.ru и найди название для переменной там
- в именах классов используется CamelCase, первая буква большая, «_» может использоваться
- мы предпочитаем подстановку переменных вместо конкатенации строк: "I am $age years old" — хорошо, 'I am ' . $age . ' years old' — плохо из-за обилия точек и кавычек
- мы используем для отступов 4 пробела (можно настроить редактор, чтобы при нажатии Tab он вставлял 4 пробела)

Вот ссылка на стандарты, где все это описано подробнее и даны примеры оформления:

PSR-1: https://github.com/samdark/fig-standards-ru/blob/master/accepted/ru/PSR-1-basic-coding-standard.md
PSR-2: https://github.com/samdark/fig-standards-ru/blob/master/accepted/ru/PSR-2-coding-style-guide.md
3 1135056
В прошлом треде:

- написал еще комментарии по https://github.com/TheSidSpears/testhub/ >>1135039
- ответил про ER диаграмму базы данных: >>1135042
- проверил задачу про антикризисные меры >>1135043

Если я кому-то не ответил, напомните о себе тут.
4 1135068
ОП, подскажи плз статьи по вопросу >>1134788
а то задача прилетела, а я с синтаксическим разбором никогда не сталкивался
5 1135122
>>35068
>>1134788

Ты можешь посмотреть в сторону компонента Symfony ExpressionLanguage: https://symfony.com/doc/current/components/expression_language.html - там уже есть парсер выражений. Но если тебе интересно, как вообще это делается, читай пасту:

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

Для записи грамматики есть разные стандартные способы:

- BNF https://en.wikipedia.org/wiki/Backus–Naur_form
- EBNF https://en.wikipedia.org/wiki/Extended_Backus–Naur_form
- ABNF https://en.wikipedia.org/wiki/Augmented_Backus–Naur_form (спецификация на рус: https://rfc2.ru/5234.rfc )
- и даже можно использовать регулярки https://habrahabr.ru/post/171667/

Все эти грамматики определяют правила составления конструкций из минимальных неделимых кусочков языка (терминалы) и других составных конструкций. Например, для математического выражения терминалами могут быть числа и знаки арифметических операций, а составной конструкцией - "сумма", определенная как последовательность конструкций ЧИСЛО "+" ЧИСЛО.

Традиционно разбор выражения делают в 2 этапа:

1) В рамках лексического анализа лексер (токенайзер) разбивает выражение на массив токенов (лексем): "-(22 + 2) ^ 3 ^ 4" -> ['-', '(', '22', '+', '2', ')', '^', '3', '^', '4']. На этом этапе числа группируются в токен, удаляются незначащие символы. Токен может быть представлен строкой, массивом, объектом, в зависимости от задачи. Последовательность токенов можно представить в виде массива или объекта.

2) В рамках синтаксического анализа парсер получает на вход поток токенов и строит дерево выражения их узлов. Тут есть разные алгоритмы: https://ru.wikipedia.org/wiki/Синтаксический_анализ

Дерево выражения удобно представлять в виде дерева из объектов-узлов разного типа (AST). Ну например, математическое выражение 10 + 2 + 3 ^ 4 можно представить в виде дерева объектов:

SumNode(
NumberNode(10),
NumberNode(2),
PowerNode(
NumberNode(3),
NumberNode(4)
)
)

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

Для твоей задачи самым простым будет метод "рекурсивного спуска". На вход алгоритм получает "поток токенов", на выходе выдает объект-корень дерева выражения (AST). С деревом потом можно делать что угодно.

Мы представляем поток токенов в виде некоей сущности tokens (это может быть объект, итератор, и тд), которая поддерживает по сути 2 операции: "подглядеть" текущий токен (peek) и "поглотить" (consume) текущий токен с переходом к следующему. Таким образом, парсер читает последовательность токенов за один проход и никогда не "отступает" назад. Это позволяет нам подсоединить выход лексера так, что мы не накапливаем массив токенов, а сразу же разбираем их по мере получения. Вот пример потока токенов, представленного в виде класса:

class TokenStream
{
// Возвращает текущий токен либо null, если они закончились
public function peek(): ?Token { ... }

// Берет токен, проверяет, что он указанного типа, возвращает его
// и переходит к следующему токену
public function consume($type = null): Token { ... }
}

Для начала, мы записываем "грамматику", то есть полный набор правил, по которым разбираются выражения, начиная с верхнего уровня. Я использую синтаксис ABNF ( https://en.wikipedia.org/wiki/Augmented_Backus–Naur_form , советую почитать также про BNF и EBNF):

-------

; Правила записываются в виде "конструкция = определение"
; Например, ниже "операнд" может быть одной из перечисленных ниже конструкций
; Знак / обозначает "или"
; ЧИСЛО - это один токен, который далее не делится на части (терминал)
; строки в кавычках вроде "(" обозначают соответствующие символы (скобку)
операнд = ЧИСЛО / "(" выражение ")" / унарный-минус / унарный-плюс

унарный-минус = "-" операнд
унарный-плюс = "+" операнд

; * значит, что выражение в скобках повторяется сколько угодно раз, включая ноль,
; то есть конструкция "степень" может содержать много операндов и знаков ^,
; а может состоять из одного операнда без знака ^
степень-или-операнд = операнд *( "^" операнд )

; произведение - это набор конструкций "степень", разделенный
; знаками деления и умножения
произведение = степень-или-операнд *( ( "*" / "/" ) степень-или-операнд )
сумма = произведение *( ( "+" / "-" ) произведение )

выражение = сумма

-------

Читать правила удобнее снизу вверх (а писать - наоборот).

Эти правила по сути задают алгоритм разбора той или иной конструкции. Ну например, правило 'операнд = ЧИСЛО / "(" выражение ")" / унарный-минус / унарный-плюс' значит следующее:

Когда мы хотим разобрать конструкцию "операнд", мы должны:

- проверить, является ли токен ЧИСЛОм ? Если да - создаем из него узел и разбор закончен
- является ли первый токен скобкой? Если да, поглощаем его, затем вызываем правило разбора "выражение", затем поглощаем закрывающую скобку
- является ли первый токен минусом? Если да, разбираем конструкцию "унарный-минус"
- является ли первый токен плюсом? Если да, разбираем конструкцию "унарный-плюс"
- иначе, выдаем синтаксическую ошибку

Правило 'сумма = произведение *( ( "+" / "-" ) произведение )' надо читать так:

Конструкция "сумма" состоит из конструкции "произведение", за которой может идти любое число последоватльностей из знака плюс или минус и конструкции "произведение".

Эти правила можно записать и по-другому. Например, "степень-или-операнд" можно сформулировать так:

; правоассоциативное выражение
степень-или-операнд = операнд "^" степень-или-операнд / операнд

; левоассоциативное
произведение = степень-или-операнд ( "*" / "/" ) произведение / степень-или-операнд

Возвращаясь к методу "рекурсивного спуска". В нем мы для каждого правила грамматики пишем соответствующую функцию, которая его реализует. Она выглядит так:

function parseSomething(tokens): [Node, tokens]

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

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

Если взять правила выше, то у нас будут функции:

parseOperand
parseUnaryMinus
parseUnaryPlus
parsePower
parseMultiplication
parseSum = parseExpression

Опишу для примера алгоритм функции parseOperand(tokens):

- если текущий токен == ЧИСЛО, то создаем узел типа NumberNode и возвращаем его
- иначе, если текущий токен = "(", то поглощаем его, вызываем parseExpression и поглощам идущий далее токен ")". И возвращаем получившийся узел.
- если текущий токен - знак минус, то, вызываем parseUnaryMinus и возвращаем результат
- если текущий токен - знак плюс, то вызвыаем parseUnaryPlus и возвращаем результат
- сигнализируем об ошибке

Пример:

class Parser
{
...
function parseOperand(TokenStream $tokens)
{
$token = $tokens->peek();

if ($token->type == Token::TYPE_NUMBER) {
$tokens->consume();
return [new NumberNode($token), $tokens];
}

if ($token->value == "(") {
$tokens->consume("(");
list($node, $tokens) = $this->parseExpression($tokens);
$tokens->consume(")");
return [$node, $tokens];
}

if ($token->value == "-") {
return $this->parseUnaryExpression($tokens);
}

if ($this->value == "+") {
return $this->parseUnaryExpression($tokens);
}

$this->throwExpectedError("expected NUMBER, (, +, or -");
}

Мои правила предполагают, что узел может содержать не 2, а более детей. То есть для выражения "2 + 4 - 3" я создаю один узел SumNode с 3 детьми: 2, 4 и 3. Но это можно поменять и на узлы с 2 детьми, это не принципиально.

Я советую попробовать реализовать метод "рекурсивного спуска".

Если хочешь усложнить задачу, попробуй добавить в выражение: дроби (1/3), функции (sin(x)). Также, можешь попробовать сделать парсер какого-нибудь языка программирования, например, урезанной версии PHP, поддерживающей переменные, функции, конструкции if и for. Начать можешь с описания грамматики.

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

Потому для таких случаев придуманы генераторы парсеров. Довольно известный - ANTLR ( https://github.com/antlr/antlr4 ), он написан на Яве, но умеет генерировать парсеры на разных языках программирования. Для него, например, есть куча грамматик разных языков: https://github.com/antlr/grammars-v4.

Также, есть написанный на PHP PEG: https://github.com/hafriedlander/php-peg

Ты даешь им грамматику и они по ней генерируют код парсера. "Взрослые" парсеры для компьютерных программ делаются по такому принципу, так как вручную их писать долго и легко ошибиться.
5 1135122
>>35068
>>1134788

Ты можешь посмотреть в сторону компонента Symfony ExpressionLanguage: https://symfony.com/doc/current/components/expression_language.html - там уже есть парсер выражений. Но если тебе интересно, как вообще это делается, читай пасту:

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

Для записи грамматики есть разные стандартные способы:

- BNF https://en.wikipedia.org/wiki/Backus–Naur_form
- EBNF https://en.wikipedia.org/wiki/Extended_Backus–Naur_form
- ABNF https://en.wikipedia.org/wiki/Augmented_Backus–Naur_form (спецификация на рус: https://rfc2.ru/5234.rfc )
- и даже можно использовать регулярки https://habrahabr.ru/post/171667/

Все эти грамматики определяют правила составления конструкций из минимальных неделимых кусочков языка (терминалы) и других составных конструкций. Например, для математического выражения терминалами могут быть числа и знаки арифметических операций, а составной конструкцией - "сумма", определенная как последовательность конструкций ЧИСЛО "+" ЧИСЛО.

Традиционно разбор выражения делают в 2 этапа:

1) В рамках лексического анализа лексер (токенайзер) разбивает выражение на массив токенов (лексем): "-(22 + 2) ^ 3 ^ 4" -> ['-', '(', '22', '+', '2', ')', '^', '3', '^', '4']. На этом этапе числа группируются в токен, удаляются незначащие символы. Токен может быть представлен строкой, массивом, объектом, в зависимости от задачи. Последовательность токенов можно представить в виде массива или объекта.

2) В рамках синтаксического анализа парсер получает на вход поток токенов и строит дерево выражения их узлов. Тут есть разные алгоритмы: https://ru.wikipedia.org/wiki/Синтаксический_анализ

Дерево выражения удобно представлять в виде дерева из объектов-узлов разного типа (AST). Ну например, математическое выражение 10 + 2 + 3 ^ 4 можно представить в виде дерева объектов:

SumNode(
NumberNode(10),
NumberNode(2),
PowerNode(
NumberNode(3),
NumberNode(4)
)
)

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

Для твоей задачи самым простым будет метод "рекурсивного спуска". На вход алгоритм получает "поток токенов", на выходе выдает объект-корень дерева выражения (AST). С деревом потом можно делать что угодно.

Мы представляем поток токенов в виде некоей сущности tokens (это может быть объект, итератор, и тд), которая поддерживает по сути 2 операции: "подглядеть" текущий токен (peek) и "поглотить" (consume) текущий токен с переходом к следующему. Таким образом, парсер читает последовательность токенов за один проход и никогда не "отступает" назад. Это позволяет нам подсоединить выход лексера так, что мы не накапливаем массив токенов, а сразу же разбираем их по мере получения. Вот пример потока токенов, представленного в виде класса:

class TokenStream
{
// Возвращает текущий токен либо null, если они закончились
public function peek(): ?Token { ... }

// Берет токен, проверяет, что он указанного типа, возвращает его
// и переходит к следующему токену
public function consume($type = null): Token { ... }
}

Для начала, мы записываем "грамматику", то есть полный набор правил, по которым разбираются выражения, начиная с верхнего уровня. Я использую синтаксис ABNF ( https://en.wikipedia.org/wiki/Augmented_Backus–Naur_form , советую почитать также про BNF и EBNF):

-------

; Правила записываются в виде "конструкция = определение"
; Например, ниже "операнд" может быть одной из перечисленных ниже конструкций
; Знак / обозначает "или"
; ЧИСЛО - это один токен, который далее не делится на части (терминал)
; строки в кавычках вроде "(" обозначают соответствующие символы (скобку)
операнд = ЧИСЛО / "(" выражение ")" / унарный-минус / унарный-плюс

унарный-минус = "-" операнд
унарный-плюс = "+" операнд

; * значит, что выражение в скобках повторяется сколько угодно раз, включая ноль,
; то есть конструкция "степень" может содержать много операндов и знаков ^,
; а может состоять из одного операнда без знака ^
степень-или-операнд = операнд *( "^" операнд )

; произведение - это набор конструкций "степень", разделенный
; знаками деления и умножения
произведение = степень-или-операнд *( ( "*" / "/" ) степень-или-операнд )
сумма = произведение *( ( "+" / "-" ) произведение )

выражение = сумма

-------

Читать правила удобнее снизу вверх (а писать - наоборот).

Эти правила по сути задают алгоритм разбора той или иной конструкции. Ну например, правило 'операнд = ЧИСЛО / "(" выражение ")" / унарный-минус / унарный-плюс' значит следующее:

Когда мы хотим разобрать конструкцию "операнд", мы должны:

- проверить, является ли токен ЧИСЛОм ? Если да - создаем из него узел и разбор закончен
- является ли первый токен скобкой? Если да, поглощаем его, затем вызываем правило разбора "выражение", затем поглощаем закрывающую скобку
- является ли первый токен минусом? Если да, разбираем конструкцию "унарный-минус"
- является ли первый токен плюсом? Если да, разбираем конструкцию "унарный-плюс"
- иначе, выдаем синтаксическую ошибку

Правило 'сумма = произведение *( ( "+" / "-" ) произведение )' надо читать так:

Конструкция "сумма" состоит из конструкции "произведение", за которой может идти любое число последоватльностей из знака плюс или минус и конструкции "произведение".

Эти правила можно записать и по-другому. Например, "степень-или-операнд" можно сформулировать так:

; правоассоциативное выражение
степень-или-операнд = операнд "^" степень-или-операнд / операнд

; левоассоциативное
произведение = степень-или-операнд ( "*" / "/" ) произведение / степень-или-операнд

Возвращаясь к методу "рекурсивного спуска". В нем мы для каждого правила грамматики пишем соответствующую функцию, которая его реализует. Она выглядит так:

function parseSomething(tokens): [Node, tokens]

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

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

Если взять правила выше, то у нас будут функции:

parseOperand
parseUnaryMinus
parseUnaryPlus
parsePower
parseMultiplication
parseSum = parseExpression

Опишу для примера алгоритм функции parseOperand(tokens):

- если текущий токен == ЧИСЛО, то создаем узел типа NumberNode и возвращаем его
- иначе, если текущий токен = "(", то поглощаем его, вызываем parseExpression и поглощам идущий далее токен ")". И возвращаем получившийся узел.
- если текущий токен - знак минус, то, вызываем parseUnaryMinus и возвращаем результат
- если текущий токен - знак плюс, то вызвыаем parseUnaryPlus и возвращаем результат
- сигнализируем об ошибке

Пример:

class Parser
{
...
function parseOperand(TokenStream $tokens)
{
$token = $tokens->peek();

if ($token->type == Token::TYPE_NUMBER) {
$tokens->consume();
return [new NumberNode($token), $tokens];
}

if ($token->value == "(") {
$tokens->consume("(");
list($node, $tokens) = $this->parseExpression($tokens);
$tokens->consume(")");
return [$node, $tokens];
}

if ($token->value == "-") {
return $this->parseUnaryExpression($tokens);
}

if ($this->value == "+") {
return $this->parseUnaryExpression($tokens);
}

$this->throwExpectedError("expected NUMBER, (, +, or -");
}

Мои правила предполагают, что узел может содержать не 2, а более детей. То есть для выражения "2 + 4 - 3" я создаю один узел SumNode с 3 детьми: 2, 4 и 3. Но это можно поменять и на узлы с 2 детьми, это не принципиально.

Я советую попробовать реализовать метод "рекурсивного спуска".

Если хочешь усложнить задачу, попробуй добавить в выражение: дроби (1/3), функции (sin(x)). Также, можешь попробовать сделать парсер какого-нибудь языка программирования, например, урезанной версии PHP, поддерживающей переменные, функции, конструкции if и for. Начать можешь с описания грамматики.

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

Потому для таких случаев придуманы генераторы парсеров. Довольно известный - ANTLR ( https://github.com/antlr/antlr4 ), он написан на Яве, но умеет генерировать парсеры на разных языках программирования. Для него, например, есть куча грамматик разных языков: https://github.com/antlr/grammars-v4.

Также, есть написанный на PHP PEG: https://github.com/hafriedlander/php-peg

Ты даешь им грамматику и они по ней генерируют код парсера. "Взрослые" парсеры для компьютерных программ делаются по такому принципу, так как вручную их писать долго и легко ошибиться.
6 1135131
>>35122
спасибо! это как раз то, что нужно

еще вопрос: я правильно понимаю, что в QueryBuilder доктриновский (а именно в его метод where()) просто так не всунешь условие селекта типа '((ID = 10) OR (NAME = 'VASYA' AND ID < 5))' ну то есть которое в обычный sql бы переварил?
и для этого там есть всякие методы типа expr()?
7 1135133
>>35122
возможно ли вообще в некий свой метод типа filterNews('where ((id > 5 or (name = ... ))') в качестве аргумента подать подобное условие и на выходе каким-то образом получить queryBuilder, который подставляя свои методы-хелперы такую логику реализует? или лучше использовать доктриновский query() для таких целей?
8 1135138
бампану свои тесты:
https://2ch.hk/pr/res/1118555.html#1131535 (М)
35onan.jpg15 Кб, 310x280
sage 9 1135141
>>35053 (OP)
Великовозрастный долбоёб и php с pdo;

Вопросы такие: Как правильно добавлять данные с формы в таблицу? Допустим форма регистрации. Не забивать же каждое поле в переменную? В массив, а потом этот массив запихивать в бд?

Как правильно упаковать запись в таблицу с помощью pdo? Есть два файла: index.php, pdo.php. В индексе, в шапке, инклуд файла pdo.php, и сама форма с кнопкой. В файле pdo.php - простой коннект к бд. Пишу корявый prepare вместе с bindParam (допустим без массива, а данные с поля - попадают в переменную) - нихуя не происходит. В то время как форма по загрузке файла, с добавлением в бд инфы по нему - рабочие. Что за магия?

try {
$dbh = new PDO('mysql:host = localhost;dbname = $dbname', $user, $pass, array(PDO::ATTR_PERSISTENT => false));
// само подключение

$addUsr = $dbh->prepare("INSERT INTO user (group, name, pass, salt, email) VALUES (:group, :name, :passwd, :salt, :email)");
$addUsr->bindParam(':group', $group);
$addUsr->bindParam(':name', $usrName);
$addUsr->bindParam(':passwd', $salted);
$addUsr->bindParam(':salt', $salt);
$addUsr->bindParam(':email', $email);
// подготовленное выражение

} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
// закрываем трай

Допустим на подобном ублюдском примере с "значение поля = переменная". После условия формы, в индексе, стоит $addUsr->execute();

Ну и вариант "красивой" передачи, пожалуйста. Пробовал, кстати, $dbh->exec в начале скрипта, с болванистыми данными, которые должны забиваться при отработке скрипта, но ему похуй. В бд ничего не появляется. Как так, ёбаный в рот? Вопрошал в факе, но там всем настолько похуй, что нихуя вообще не написали.
35onan.jpg15 Кб, 310x280
sage 9 1135141
>>35053 (OP)
Великовозрастный долбоёб и php с pdo;

Вопросы такие: Как правильно добавлять данные с формы в таблицу? Допустим форма регистрации. Не забивать же каждое поле в переменную? В массив, а потом этот массив запихивать в бд?

Как правильно упаковать запись в таблицу с помощью pdo? Есть два файла: index.php, pdo.php. В индексе, в шапке, инклуд файла pdo.php, и сама форма с кнопкой. В файле pdo.php - простой коннект к бд. Пишу корявый prepare вместе с bindParam (допустим без массива, а данные с поля - попадают в переменную) - нихуя не происходит. В то время как форма по загрузке файла, с добавлением в бд инфы по нему - рабочие. Что за магия?

try {
$dbh = new PDO('mysql:host = localhost;dbname = $dbname', $user, $pass, array(PDO::ATTR_PERSISTENT => false));
// само подключение

$addUsr = $dbh->prepare("INSERT INTO user (group, name, pass, salt, email) VALUES (:group, :name, :passwd, :salt, :email)");
$addUsr->bindParam(':group', $group);
$addUsr->bindParam(':name', $usrName);
$addUsr->bindParam(':passwd', $salted);
$addUsr->bindParam(':salt', $salt);
$addUsr->bindParam(':email', $email);
// подготовленное выражение

} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
// закрываем трай

Допустим на подобном ублюдском примере с "значение поля = переменная". После условия формы, в индексе, стоит $addUsr->execute();

Ну и вариант "красивой" передачи, пожалуйста. Пробовал, кстати, $dbh->exec в начале скрипта, с болванистыми данными, которые должны забиваться при отработке скрипта, но ему похуй. В бд ничего не появляется. Как так, ёбаный в рот? Вопрошал в факе, но там всем настолько похуй, что нихуя вообще не написали.
10 1135297
подскажите, кто шарит.
есть доктрина и симфони. есть некие входные данные (прилетают по апи), в которых лежит sql-условие where типа "(name='ABC' AND (category1 = 'X' OR category2 = 'X' OR category3 = 'X')
AND price > 10)" в виде строки. оно всегда валидное, т.к. проверяется до попадания и может быть очень сложным с большим уровнем вложенности. задача - отдать выборку по нему.

оно всегда относится к выборке одной и той же сущности. как это условие скормить доктрине?
11 1135368
>>35297
addWhere(), не?
12 1135377
Вопрос: делал приложение на Symfony c Doctrine, понял, что зря создавал отдельные сущности, так как в будущем их слишком много может быть и не понятно, как потом поддерживать. Сейчас думаю сделать все же одну сущность Product, одну Appearance и одну Variant, ну и Category общую тоже. Однако не понял, как хранить разные характеристики, ну есть, конечно, json, ну как по нему условия, читай фильтры в каталоге, делать. Сейчас у меня есть <select> и в нем все размеры кроватей, все размеры матрасов, где надо, чекбоксы всякие и так далее. Какой есть современный удобный подход. Может, тут даже и Doctrine не нужна.
13 1135380
>>35377
EAV вроде как уродство и все значения в строках. Как вообще делаются современные интернет-магазины/витрины, не особо крупные, например
14 1135389
>>35377
смотрю в сторону NoSQL
15 1135464
>>35141
Какие у тебя ошибки появляются?
sage 16 1135467
>>35464
А вот никаких. Данные в переменные передаются, проверял. Оно просто не пишет в базу. Я хуй знает чому. Скрипт отрабатывает и... пусто. Попробую ещё параноидальный режим ошибок ебануть, чтоб на каждый пёрд выводилось, посмотрю. поле id имеется, оно автоинкрементируемое, его, я так понял, в запросе можно не указывать - оно само ложится. По крайней мере то что мне файл в бд кладёт - так и делает
https://github.com/moabit/student-list/ 17 1135481
>>35138
>>1131535

По тестам. Их лучше вынести в отдельную папку (например, /tests), и классы в отдельный неймспейс, чтобы отделить продакшен-код от тестов. Написать для них отдельное правило автозагрузки в autoload-dev, чтобы оно не применялось на продакшене.

Тестировать код можно на разных уровнях. Можно тестировать отдельный метод, класс, группу классов или все приложение в сборе. Что касается юнит-тестов, ими можно протестировать не любой код. Если, например, код вызывает die(), то его через юнит-тест не протестировать.

Вот, например, твой роутер явно не проверить юнит-тестом, так как он может подключать контроллеры, делать там кучу вещей. Это ведь по сути фронт-контроллер, который занимается роутингом и вызовом контроллера страницы. Как можно его протестировать? Есть разные подходы:

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

На мой взгляд, тут разве что третий вариант подходит. В фреймворках вроде Симфони контроллеры лучше поддаются тестированию: там используются объекты Request (вместо $_GET, POST) и Response (вместо вывода страницы напрямую), и там мы можем создать Request, вызвать контроллер и проверить Response. У тебя, к сожалению, это невозможно и контроллер можно тестировать только через end-to-end тесты.

Вдобавок, у тебя в тесте ошибка: REQUEST_URI почти всегда начинается со слеша (еще я видел вариант, когда он начинается с вопроса), а не с букв.

По https://github.com/moabit/student-list/blob/master/app/Tests/UtilTest.php

Для readJson() можно было добавить еще позитивный сценарий: чтение файла с правильным путем и извлечение из него какой-то строчки. Файл можно положить в папку вроде assets, resources или создать перед тестом во временной папке (наверно, не стоит).

Далее, если мы посмотрим на testCheckCSRFToken(), то видим, что тут явно не очень удобный для тестирования код. Он не принимает входные параметры явно, а берет их из каких-то глобальных переменных. Тестировать код, который работает с объектами вроде Request было бы конечно удобнее.

Тут конечно в тесте заложено знание подробностей работы защиты от CSRF: тест знает, какие куки проверяет код, какой алгоритм он использует. Если в алгоритме защиты что-то поменять, тест может сломаться. Это можно было бы попробовать исправить, организовав тестирование по-другому:

- вызвать setCSRFToken() и записать выставленные им куки (это было бы удобно делать, если бы он не работал с setcookie(), а записывал бы куки в объект Response), сохранить возвращенный токен
- сформировать объект Request с запросом от формы, подставить туда полученный токен и выданные куки
- вызвать проверку

Но это требует добавления Request/Response. Еще один вариант - использовать end-to-end тест - сделать тестовую страницу с формой и защитой от CSRF, поднять временный веб-сервер, зайти на страницу, заполнить форму, отправить, проверить ответ. Опять же, требует значительных усилий.

Но зато оба этих варианта могут дать более надежные тесты.

Есть разные точки зрения по организации тестов, но мне кажется, что удобно делать один тестовый метод на каждое требование. Ну то есть, мы думаем, какие мы требования предъявляем к коду проверки CSRF?

- если дан токен в POST и кука, то проверка проходит
- если дан токен и кука, но они не совпадают, проверка не проходит
- если токен в POST пустой, проверка не проходит
- если куки нет, проверка не проходит

На каждое требование можно написать свой метод: testCheckSuccessWIthCookieAndToken, testCheckFailsWithInvalidToken, checkTestFailsWithMissingToken, итд. Для надежности, сам токен можно генерировать с помощью setCSRFToken, чтобы он был гарантированно правильный. Это потребует немного больше писанины, но зато:

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

То же можно сказать и про тест валидатора. Можно было бы тестировать каждую проверку в отдельности (testInvalidEmailFails, testInvalidNameFails и тд). Также, если бы у тебя валидатор не был заточен только на проверку студентво, а был бы разбит на компоненты (отдельно метод или класс проверки email, отдельно имени), то их тоже можно было бы тестировать по отдельности.

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

Также, в тесте testStudentValidation() у тебя есть одно слабое место - там ведь есть проверка уникальности email, и если в БД есть email rabinovicC-vhANUSgm%qqailPUNCTUMco]%am, то она может провалиться. Можно наверно этим пренебречь, а можно попробовать придумать email, которого в базе точно не может быть. Тем более, что этот же email используется в тесте вставки студента.

https://github.com/moabit/student-list/blob/master/app/Tests/StudentDataGatewayTest.php#L30

> public function testCountStudents()


> {


> $this->assertNotFalse($this->studentDataGateway->countStudents());


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

> public function testGetStudentsWithWrongField()


> {


> $this->expectException(\PDOException::class);


> $this->studentDataGateway->getStudents('wrongOrderField', 'asc', 15, 0);


Этот тест полагается на знание внутреннего устройства StudentGateway. Что, если ым там поменяем PDO на mysqli? Решить это можно, сделав специальный класс исключений на такой случай или взяв одно из SPL исключений: http://php.net/manual/ru/spl.exceptions.php

В README:

> To add more students uncomment addStudents function in index.php file


лучше написать про вызов cli-скрипта

> echo "Please enter a number of students you want to add to the database:\n";


> $input=intval(fgets(STDIN));


В CLI-скриптах обычно параметры передают как аргументы командной строки, то есть пишут

php addStudents.php 10

Почитай про $argv, $argc и getopt:

- http://php.net/manual/ru/features.commandline.usage.php
- http://php.net/manual/ru/reserved.variables.argv.php
- http://php.net/manual/ru/reserved.variables.argc.php
- http://php.net/manual/ru/function.getopt.php

getopt довольно примитивный (он например не умеет формировать подсказку по аргументам), потому для более сложных случаев ты можешь захотеть поискать какие-то библиотеки для разбора аргументов. Как минимум, такие классы есть в компоненте Symfony Console, ну и наверно есть отдельные библиотеки для этого.

Также, ты в cli скрипте почему-то не подключил ErrorHandler.

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

> ucfirst


Эта функция не поддерживает кириллицу в utf-8: https://github.com/codedokode/pasta/blob/master/php/strings-utf8.md

Плюс, ты не делаешь проверку, что в POST есть нужный элемент. Лучше писать $_POST['name'] ?? ''.

https://github.com/moabit/student-list/blob/master/app/Entities/Student.php
тут не помешали бы тайп хинты.

https://github.com/moabit/student-list/blob/master/app/Helpers/Authorisation.php
Вот этот класс обладает состоянием. Было бы логичнее в контейнере пометить его ,чтобы при каждом обращении создавался бы новый экземпляр. А иначе, представь что ты попробуешь обработать 2 запроса подряд: обработчик первого запроса поменяет состояние объекта и это может повлиять на обработку заипроса от второго пользователя.

Также, метод getStudent возвращает объект студента, но signIn() принимает токен, а не студента. Было бы лучше и тут сделать аргументом студента и таким образом скрыть подробности авторизации (какие поля используются) внутри класса. Это позволит нам менять алгоритм авторизации, не трогая остальной код.

https://github.com/moabit/student-list/blob/master/views/templates/profileForm.twig#L22

> {% if user.gender is defined and user.gender =="f" %}


лучше сделать, чтобы user всегда бы передавался в шаблон. Если это так, то is defined можно убирать.

Класс pager назван не очень удачно, он же не только за пагинацию отвечает. Лучше назвать его ViewParams, TableParams или TableFilter. И тогда можно добавить туда методы вроде isSearchActive() вместо {% if pager.search is not null %}.
https://github.com/moabit/student-list/ 17 1135481
>>35138
>>1131535

По тестам. Их лучше вынести в отдельную папку (например, /tests), и классы в отдельный неймспейс, чтобы отделить продакшен-код от тестов. Написать для них отдельное правило автозагрузки в autoload-dev, чтобы оно не применялось на продакшене.

Тестировать код можно на разных уровнях. Можно тестировать отдельный метод, класс, группу классов или все приложение в сборе. Что касается юнит-тестов, ими можно протестировать не любой код. Если, например, код вызывает die(), то его через юнит-тест не протестировать.

Вот, например, твой роутер явно не проверить юнит-тестом, так как он может подключать контроллеры, делать там кучу вещей. Это ведь по сути фронт-контроллер, который занимается роутингом и вызовом контроллера страницы. Как можно его протестировать? Есть разные подходы:

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

На мой взгляд, тут разве что третий вариант подходит. В фреймворках вроде Симфони контроллеры лучше поддаются тестированию: там используются объекты Request (вместо $_GET, POST) и Response (вместо вывода страницы напрямую), и там мы можем создать Request, вызвать контроллер и проверить Response. У тебя, к сожалению, это невозможно и контроллер можно тестировать только через end-to-end тесты.

Вдобавок, у тебя в тесте ошибка: REQUEST_URI почти всегда начинается со слеша (еще я видел вариант, когда он начинается с вопроса), а не с букв.

По https://github.com/moabit/student-list/blob/master/app/Tests/UtilTest.php

Для readJson() можно было добавить еще позитивный сценарий: чтение файла с правильным путем и извлечение из него какой-то строчки. Файл можно положить в папку вроде assets, resources или создать перед тестом во временной папке (наверно, не стоит).

Далее, если мы посмотрим на testCheckCSRFToken(), то видим, что тут явно не очень удобный для тестирования код. Он не принимает входные параметры явно, а берет их из каких-то глобальных переменных. Тестировать код, который работает с объектами вроде Request было бы конечно удобнее.

Тут конечно в тесте заложено знание подробностей работы защиты от CSRF: тест знает, какие куки проверяет код, какой алгоритм он использует. Если в алгоритме защиты что-то поменять, тест может сломаться. Это можно было бы попробовать исправить, организовав тестирование по-другому:

- вызвать setCSRFToken() и записать выставленные им куки (это было бы удобно делать, если бы он не работал с setcookie(), а записывал бы куки в объект Response), сохранить возвращенный токен
- сформировать объект Request с запросом от формы, подставить туда полученный токен и выданные куки
- вызвать проверку

Но это требует добавления Request/Response. Еще один вариант - использовать end-to-end тест - сделать тестовую страницу с формой и защитой от CSRF, поднять временный веб-сервер, зайти на страницу, заполнить форму, отправить, проверить ответ. Опять же, требует значительных усилий.

Но зато оба этих варианта могут дать более надежные тесты.

Есть разные точки зрения по организации тестов, но мне кажется, что удобно делать один тестовый метод на каждое требование. Ну то есть, мы думаем, какие мы требования предъявляем к коду проверки CSRF?

- если дан токен в POST и кука, то проверка проходит
- если дан токен и кука, но они не совпадают, проверка не проходит
- если токен в POST пустой, проверка не проходит
- если куки нет, проверка не проходит

На каждое требование можно написать свой метод: testCheckSuccessWIthCookieAndToken, testCheckFailsWithInvalidToken, checkTestFailsWithMissingToken, итд. Для надежности, сам токен можно генерировать с помощью setCSRFToken, чтобы он был гарантированно правильный. Это потребует немного больше писанины, но зато:

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

То же можно сказать и про тест валидатора. Можно было бы тестировать каждую проверку в отдельности (testInvalidEmailFails, testInvalidNameFails и тд). Также, если бы у тебя валидатор не был заточен только на проверку студентво, а был бы разбит на компоненты (отдельно метод или класс проверки email, отдельно имени), то их тоже можно было бы тестировать по отдельности.

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

Также, в тесте testStudentValidation() у тебя есть одно слабое место - там ведь есть проверка уникальности email, и если в БД есть email rabinovicC-vhANUSgm%qqailPUNCTUMco]%am, то она может провалиться. Можно наверно этим пренебречь, а можно попробовать придумать email, которого в базе точно не может быть. Тем более, что этот же email используется в тесте вставки студента.

https://github.com/moabit/student-list/blob/master/app/Tests/StudentDataGatewayTest.php#L30

> public function testCountStudents()


> {


> $this->assertNotFalse($this->studentDataGateway->countStudents());


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

> public function testGetStudentsWithWrongField()


> {


> $this->expectException(\PDOException::class);


> $this->studentDataGateway->getStudents('wrongOrderField', 'asc', 15, 0);


Этот тест полагается на знание внутреннего устройства StudentGateway. Что, если ым там поменяем PDO на mysqli? Решить это можно, сделав специальный класс исключений на такой случай или взяв одно из SPL исключений: http://php.net/manual/ru/spl.exceptions.php

В README:

> To add more students uncomment addStudents function in index.php file


лучше написать про вызов cli-скрипта

> echo "Please enter a number of students you want to add to the database:\n";


> $input=intval(fgets(STDIN));


В CLI-скриптах обычно параметры передают как аргументы командной строки, то есть пишут

php addStudents.php 10

Почитай про $argv, $argc и getopt:

- http://php.net/manual/ru/features.commandline.usage.php
- http://php.net/manual/ru/reserved.variables.argv.php
- http://php.net/manual/ru/reserved.variables.argc.php
- http://php.net/manual/ru/function.getopt.php

getopt довольно примитивный (он например не умеет формировать подсказку по аргументам), потому для более сложных случаев ты можешь захотеть поискать какие-то библиотеки для разбора аргументов. Как минимум, такие классы есть в компоненте Symfony Console, ну и наверно есть отдельные библиотеки для этого.

Также, ты в cli скрипте почему-то не подключил ErrorHandler.

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

> ucfirst


Эта функция не поддерживает кириллицу в utf-8: https://github.com/codedokode/pasta/blob/master/php/strings-utf8.md

Плюс, ты не делаешь проверку, что в POST есть нужный элемент. Лучше писать $_POST['name'] ?? ''.

https://github.com/moabit/student-list/blob/master/app/Entities/Student.php
тут не помешали бы тайп хинты.

https://github.com/moabit/student-list/blob/master/app/Helpers/Authorisation.php
Вот этот класс обладает состоянием. Было бы логичнее в контейнере пометить его ,чтобы при каждом обращении создавался бы новый экземпляр. А иначе, представь что ты попробуешь обработать 2 запроса подряд: обработчик первого запроса поменяет состояние объекта и это может повлиять на обработку заипроса от второго пользователя.

Также, метод getStudent возвращает объект студента, но signIn() принимает токен, а не студента. Было бы лучше и тут сделать аргументом студента и таким образом скрыть подробности авторизации (какие поля используются) внутри класса. Это позволит нам менять алгоритм авторизации, не трогая остальной код.

https://github.com/moabit/student-list/blob/master/views/templates/profileForm.twig#L22

> {% if user.gender is defined and user.gender =="f" %}


лучше сделать, чтобы user всегда бы передавался в шаблон. Если это так, то is defined можно убирать.

Класс pager назван не очень удачно, он же не только за пагинацию отвечает. Лучше назвать его ViewParams, TableParams или TableFilter. И тогда можно добавить туда методы вроде isSearchActive() вместо {% if pager.search is not null %}.
18 1135482
>>35467

PDO по умолчанию никак не сообщает об ошибках. Включи в PDO ERRMODE_EXCEPTION и увидишь подробности ошибки.

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

Также, если какая-то функция может вернуть false или другой признак ошибки, ты обязан его проверять.
19 1135489
>>35368
cпасибо, анон. я жестко тупанул
20 1135505
Ребятки, есть вопрос по Доктрине!

Дано две таблицы mysql, их условная структура:

orders(
id,
created,
... // всякие обычные неинтересные поля
)

orders_properties(
id,
order_id,
param enum('height', 'weight', 'length', 'color'),
value varchar(100)
)

Получается между таблицами связь один-ко-многим: у каждого заказа может быть ни одного, одно или несколько свойств, которые указаны в поле param таблицы orders_properties. На мой взгляд, решение странное, но такая таблица уже есть, с ней ничего не сделать.

Как из этого сделать сущность Доктрины?

Типа такой:
class Order
{
private $id;
private $created;
private $height;
private $weight;
private $length;
private $color;
...
}

Чтобы оно обновлялось само и значения брались из orders_properties либо были пустыми, если там нужных нет.

Те способы, которые я нашел (например, http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/cookbook/mysql-enums.html) мою проблему, увы, не решают.
20 1135505
Ребятки, есть вопрос по Доктрине!

Дано две таблицы mysql, их условная структура:

orders(
id,
created,
... // всякие обычные неинтересные поля
)

orders_properties(
id,
order_id,
param enum('height', 'weight', 'length', 'color'),
value varchar(100)
)

Получается между таблицами связь один-ко-многим: у каждого заказа может быть ни одного, одно или несколько свойств, которые указаны в поле param таблицы orders_properties. На мой взгляд, решение странное, но такая таблица уже есть, с ней ничего не сделать.

Как из этого сделать сущность Доктрины?

Типа такой:
class Order
{
private $id;
private $created;
private $height;
private $weight;
private $length;
private $color;
...
}

Чтобы оно обновлялось само и значения брались из orders_properties либо были пустыми, если там нужных нет.

Те способы, которые я нашел (например, http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/cookbook/mysql-enums.html) мою проблему, увы, не решают.
21 1135541
>>35505

Сущности Доктрины должны довольно-таки близко соответствовать таблицам. Но это касается только полей. Методы ты можешь делать любые.

Соответственно, ты можешь сделать метод Order#getWeight(), а он будет искать вес в связанных с Order свойствах OrderProperty.

Многие задачи решаются именно через методы. Ну например, ты можешь сделать поле неизменяемым, убрав метод setX().
22 1135546
>>35541
То есть не делать такие поля вообще?
А как тогда задавать условия поиска по этим полям в QueryBuilder?
23 1135578
>>35541
Пошел по твоему пути (но не совсем), сделал так:

В классе сущности написал
private $weight;

public function getWeight(OrderRepository $repo)
{
return $repo->findWeightByOrder($this->getId());
}

Затем в классе репозитория:
public function findWeightByOrder(int $id)
{
$conn = $this->getEntityManager()->getConnection();
$sql = 'SELECT o.value FROM orders_properties o WHERE o.param = \'weight\' AND o.order_id = :id';
$stmt = $conn->prepare($sql);
$stmt->execute(['id' => $id]);
return $stmt->fetch();
}

Плюс тут в том, что не надо заморачиваться с привязкой поля типа ENUM к сущности, т.к. он по дефолту в Доктрине не поддерживается (хотя если бы это была единственная заморочка, было бы заебись), но у меня есть ощущение, что это пиздец костыли и можно как-то намного лучше и изящнее.
24 1135580
>>35541
То есть, мне кажется, не должно быть такого, чтобы Entity обращался к Repository. По идее должно быть Controller > Repository > Entity
25 1135658
Короче целый день проебался с этой Доктриной и понял, что там невозможно вменяемым путем объединить две таблицы в одну сущность. Печально, что для такой хуйни придется делать сущность с названием OrderProperties
3101661+d9a797272d1514de594caf30d77352b0.jpg11 Кб, 228x200
sage 26 1135720
>>35482
Да, я помню что в ПЕДЕО надо отдельно включать обработку ошибок. В общем че я выяснил:

- каким-то хуем я указал путь до файла с подключением в относительном виде "./pdo.php", вместо просто "pdo.php" - начало мне ошибки выводить;
- ошибка такая:

> Warning: PDOStatement::execute(): SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near



По гуглению понял, что из формы данные по POST не экранируются и получается пиздос. Но я сонный и нихуя не понял. Данный из формы жкранировать отдельно? Форма загрузки файла не предполагает введённые данные, а только путь до файла.

алсо, как, всё-таки, более правильно формочки такие ебенить? По минимуму и аккуратно. В массив всё подбивать?
27 1135741
Господа, почему нельзя в дочернем классе присвоить значения родительским(унаследованным) параметрам?

Делаю вот такую штуку

abstract class A
{
protected $var;
}

class B extends A
{
$this->var = '2ch';
}

И шторм начинает светить мол unexpected assign, и пiзда.
Но та же хуйня через метод работает. Как без метода то переназначить?
28 1135813
Чем лучше слить содержимое чьего-то твиттера и сделать из него новости на своем сайте? Guzzle? Twitter Api client? Может есть какой-то бандл для Symfony?
29 1135827
Хочу вкатиться в symphony, стоит сразу переходить в 4 версию?
Посоветуйте годный курс, можно платный. Пока только нашел на английском https://knpuniversity.com
30 1135836
>>35827
в симфони без английского делать вообще нечего. если хочешь на русском, иди битрикс учи.

основные источники начальной инфы - это документация, потом их демо-проект, этот knpuniversity и исходники. другой я пока не нашел (сам учу около месяца). конечно было бы круто посмотреть на код какого-то реального большого опенсорс приложения на 4.

кстати на knpuniversity платно только видео, а оно везде дублируется бесплатным текстом, даже где видео само по себе скрыто. то есть, тебе бесплатно доступны ЛЮБЫЕ уроки. я думаю, там люди платят, чтобы поддержать проект (другая ментальность мол).

стоит сразу на 4, конечно.
31 1135864
>>35827
алсо, все эти материалы (особенно мануал) знать нужно, но они достаточно базовые. самый лучший курс - это взять на хх.ру какое-нибудь тестовое задание на симфони мидла-удаленщика и попробовать его решить в срок.
32 1135993
>>35741
потому что надо сначала ее переопределить. иначе это динамически объявленная переменная, что считается плохой практикой из-за своей неявности
33 1136012
Аноны, я вкатываюсь, но у меня видимо какой-то стандартный вопрос.
Вот я написал скрипт на пхп, который перебирает 100 миллионов значений (допустим, там только массив и цикл перебора, ничего более) и тратит на это 1 минуту. В течении этой минуты я хочу запустить другой скрипт с этого же домена (допустим test.localhost), но второй скрипт не запускается до тех пор, пока не отработает первый, перебирающий значения. Из-за чего это? Сессий внутри скрита нет, но второй всегда ждет выполнения первого? Какова "природа" этого явления и как по возможности это обойти?
34 1136015
>>36012
cli-cкрипт? если да, то тебе нужно запускать его со значком &, чтобы запустить в бэкграунде. либо открыть новую вкладку с консолью.
35 1136017
>>36015

>cli-cкрипт?


Нет, скрипт я запускаю через сервер, например так:
запускаю test.localhost/1.php и он выполняется минуту, параллельно в другой вкладке я запускаю test.localhost/2.php и он не "отрабатывает" до тех пор, пока первый не завершит работу.
36 1136023
>>36017

> я запускаю через сервер


Через какой сервер?
Кто запускает твой php скрипт? Кто принимает запрос? апач, нгникс?
37 1136025
>>36023
Апач.
Я запускаю скрипты через браузер, ну а дальше, как тут: >>36017
38 1136027
>>36025
Как именно ты понимаешь, что ждет завершение первого скрипта? Работаешь ли ты с какими-то файлами в этих скриптах? Что в процессах у тебя в этот момент происходит? Сколько процессов php висит\запускается?
39 1136032
>>36025
Уверен, что браузер не использует тот же коннект к серверу? Попробуй, запустить второй скрипт в другом браузере параллельно. Или вовсе вызвать через какой-нибудь wget
40 1136037
>>36027

>Как именно ты понимаешь, что ждет завершение первого скрипта?


Да я же на тестовом серве делаю на тестовых скриптах. Запускаю первый скрипт, он выполняется, вертится "загрузка" на вкладке. Параллельно запускаю второй скрипт во второй вкладке, в нем одна строка "echo 1", но он выполняется и выводит "1" только после того, как первый скрипт закончит перебирать массивы отработает. Если я запускаю второй отдельно (то есть, первый на этот момент не запущен), то он сразу мне выдает в браузер"1", выполняется он меньше секунды. Короче, я делаю вывод, что он ждет выполнение первого.

>Работаешь ли ты с какими-то файлами в этих скриптах?


Нет, там просто огромный цикл, который перебирает миллионные массивы несколько раз, он вообще выполняется дольше минуты (почти 2).
>>36032
Если запускаю в другом браузере - то он выполняется сразу, то есть, второй скрипт не ждет выполнение первого.
41 1136049
>>36037

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


Поясняю. Причины может быть две.
Одна - браузер использует одно и тоже соединение до сервера, а так как ты не написал\не заточил сервер для такого юзкейса, то он ждет, и поэтому все тсопорится. Гугли http 1.1вот это все.

Вторая - браузер может использовать для рендеринга вкладок на одном домене один и тот же процесс с целью оптимизации, в заивисмости от браузера и его настроек. Поэтому у тебя просто стопарится рендеринг, пока не будут получены результаты от первого.
42 1136051
>>36049
А какая причина наиболее вероятная? Мне кажется, что первая. И где можно поподробнее почитать про это? Или если нагуглю http 1.1 - то понимание придет?
43 1136052
>>36051

>И где можно поподробнее почитать про это?


Начинай отсюда https://ru.wikipedia.org/wiki/Постоянное_HTTP-соединение

>А какая причина наиболее вероятная?


Замени во втором скрипте echo на file_put_cintents в какой-нибудь файл. И смотри, если файл появился сразу, до завершения первого скрипта, значит дело в рендеринг. Если после, значит в запросах.
44 1136053
>>36052
Окей, спасибо большое!
45 1136085
>>36017

Если ты используешь сессии, то они блокируются: https://habrahabr.ru/company/bitrix/blog/179803/

Нефиг их везде использовать.

Также, длительные скрипты надо запускать через командную строку.
46 1136099
>>36085
Он же написал, что неиспользует сессии. И ко всему прочему, мы выяснили, что при одновременном запросе из разных браузеров, все отрабатывает нормально. Так что дело либо в общей песочнице webview, либо в кип-аливе.
47 1136207
пацаны, а что это за такой архитектурный ход, когда ты mysql-таблицу делаешь таким образом
attributes(param enum('param1','param2','param3'), value varchar)

зачем так делать? какая выгода? как связывать такие сущности с другими в контексте ОРМ?
48 1136211
>>36099

В браузере есть ограничение на число параллельных коннектов к серверу, но оно в районе 6-8. Правда, там еще есть HTTP/2, у которого все как-то по другому.

> либо в кип-аливе.


вряд ли

> в общей песочнице webview


Какой песочнице?
49 1136214
>>1135048

>Также, открою секрет за 1 евро в мес. можно у арубы арендовать.


Благодарю, так и сделал. Единственное что мне не понравилось у арубы - это плохой дизайн. Я ожидал выбор датацентра в процессе создания, а оказалось (потом), что выбор был вкладками в личном кабинете. Поднял OpenVPN - всё отлично, пинг правда 200 (Италия по умолчанию, хотел Германию).

Такой вопрос, ОП у тебя нет статей по настройке рабочего окружения через системы виртуализации?
50 1136224
>>36214

Наверно нет. Это вопрос про vagrant/docker? Там нужно просто знание линукса и bash.
51 1136225
>>36214

То есть прочесть любой учебник по линуксу, команды, оболочка, файлы, права, сервисы и тд.
52 1136317
>>36224
>>36225
Меня не сами юникс-системы интересуют, скорее процесс развертывания проектов на докере и для чего он.
Я работаю на win10, на vbox у меня ubuntu17.04, в /var/www я примаунтил проекты. Удобно,
так как IDE работает с локальными файлами, а сам проект поднят на апаче убунту.
Встречал в интернете упоминания о том, что на докере/вагранте разворачивают себе рабочее окружение и мне стало интересно насколько это будет удобнее (и будет ли)
53 1136321
Аноны, изучаю laravel и не понимаю некоторые моменты в маршрутизации.
Сайт состоит из разных статей и их разделов. Например, при переходе к статьям articles_IT, в раздел PHP выводятся данные из таблицы БД - articles_it, где в записи указана секция PHP. И в итоге есть 4 вида статей articles_X, в которых разное количество их секций. Главное, что в итоге модель узнает, что это за статьи и их секции, и в итоге выполняет необходимое действие исходя из этих данных. Меняется по факту только один лишь запрос к БД.
Сейчас написал действие только для главной страницы, в роутах вызывается метод контроллера:
Route::get('/', 'MainController@showArticle');
Этот метод возвращает вид, с данными из модели Article:
return view('index', ['article'=> Article::loadArticle()]);
В модели формируется одна запись из рандомных статей, рандомной секции.
Так как передать модели вид статей и их секцию исходя из запроса, как правильно описать в этом случае роут? Посмотрел в документации, дошёл до параметров роутов, но плохо понимаю, как их применять.
54 1136355
Анон, как можно в конце лучше сделать? Ну т.е. чем можно заменить повторное написание удаление последнего массива?

<?
$x= __DIR__;
$y= explode( '/', $x);
array_pop($y);
array_pop($y);
var_dump($y);
?>

Типа (array_pop($y)) * 2 ;
56 1136361
>>36207
выгода -- удобная запись в одну строку, всё

вопрос по контексту ORM неясен.
57 1136362
>>36360
Благодарю.
58 1136373
>>36361
запись в одну строку - это что имеется в виду? я не очень понял.

>вопрос по контексту ORM неясен.


если у нас есть доп.таблица user_attributes(age, sex)
то мы сущности User (которая лежит в таблице users) можем задать поле $sex, которое по связи OneToOne будет ссылать на столбец sex из таблицы с аттрибутами.

а если у таблицы структура users_attributes(param enum('age','sex'), value), то мы так сделать уже не можем.

можно было бы сказать, что так мы можем добавлять любое количество параметров без изменения таблицы, но это не так - все равно придется менять столбец param - добавлять в него разрешенные значения.

короче я не понимаю, в чем плюсы. может, это во времена динозавров так делали
59 1136375
>>36361
а еще тебя ждет огромное веселье, если нужно в одном запросе сделать where по произвольному количеству этих param. попробуй напиши автоматизацию where с подготовленными запросами. чтобы на вход подавать условие типа 'age = m AND age >= 18' а на выходе получать соответствующие сущности.
60 1136376
>>36375

>sex = m AND age >= 18

61 1136406

>Используй математику. Есть 2 функции для разделения чисел на части, $x % 1000 - берет 3 последние цифры, floor($x / 1000) - отбрасывает 3 последние цифры.



А если я не знаю, что там за число?
Допустим, я подобрал для сотен тысяч форму слова, отбросив по три цифры с концов, а на деле число оказалось миллиардом. Остальные шесть цифр не переведутся же.
Или нужно делать сперва проверку, не будет ли делимое меньше делителя?
62 1136720
как с помощью Symfony ExpressionLanguage превратить такую строку '((ID >= 10) OR (Gravatar = true))' во что-то типа:

$result[0] = $this->repo->findByWhereCondition('u.id >= 1000'); // дернулись из репозитория 10, 11, 12
$result[1] = $this->repo->findByGravatarCondition('equals', 'true'); // дернулись по АПИ 7, 11
$result[2] = $this->repo->findByLogicCondition('OR', [$result[0], [$result[1]]) // отдал 7, 10, 11, 12

?
63 1136722
>>36720

>findByWhereCondition('u.id >= 10');


быстрофикс
64 1136741
>>36720

Изучи Query Builder. Symfony Expression может превратить строку в AST (дерево выражения). Ты должен обойти это дерево и составить соответствующее ему условие для Query Builder:

http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/query-builder.html

Обрати внимание на выражение

$qb->expr()->orX(
$qb->expr()->eq('u.id', '?1'),
$qb->expr()->like('u.nickname', '?2')
)

Тебе надо что-то похожее составить на основе AST.
65 1136744
Планирую по работе не айти создать приложение для расчётов. Выбрал js, небольшой опыт имеется. Так вот, есть несколько вопросов:
1. Можно ли расчёты будет сохранять в каком-нибудь формате прямо из браузера, а потом их туда загружать?
2. В чем сейчас актуально рисовать? Канвас или уже что-то лучше и новее есть? Может существуют библиотеки для построения простых чертежей/эскизов в браузере?
3. Не ошибся ли я с выбором джс? Сейчас считаем в экселе.
66 1136794
>>36741
благодарю, анон
67 1136816
>>36744
1.Local storage
2.SVG
3.Ошибся
68 1136831
>>36816

>1.Local storage


У него есть лимит.
Ничто не мешает загружать файлы с пеки, работать с ними и потом сохранять на пеку.
69 1136836
>>36816

>Ошибся


Ну так на чем писать?
70 1136840
>>36744

Если тебе надо работать с чертежами, может тебе лучше писать скрипты для какого-то CAD приложения? Ну там автокад, компас, или какой-нибудь из открытых CAD ( https://opensource.com/alternatives/autocad )?

А так, трудно прокомментировать, не зная задачу. Сам по себе JS неплохой, и к нему много библиотек есть.
71 1136855
>>36840
Это была бы хорошая идея, если бы потом за программой не должно было бы сидеть пол офиса дамочек. И каждой ставить автокад, хехмда. Я там один его знаю, мне нужно чтобы канвас или что-то подобное само отрисовывало картинку на основе 3.5 введённых данных, чтобы дамочки могли распечатать и сохранить на будущее. Эксель норм, но там нельзя адаптивно рисовать. Плюс нужно расширить функционал, и я подумал, что сделать уже нужно нормально.
72 1136874
сап аноны, у меня такой вопрос, можно ли создать регулярку типа как 0-9 или а-яё, только чтоб она искала символы? В самом гайде я видел про поиск только одного символа
73 1136894
>>36855
С задачей идеально справитс php. Сам писал подобное. Данные в файле (а лучше в майскул базе), отрисовку делает пхп (вместе с расчётами), а отображение в браузере на хтмл+цсс+жс.
74 1136902
>>36894
Пхп не считает на ходу, я должен сабмиты хуярить с формами или учить ту хуйню, забыл название. Джс удобнее 100% в этом случае.
75 1136958
>>36741
анон, ты умный, можешь еще по >>35813 подсказать? какие инструменты оптимально использовать для такой задачи?
76 1137038
>>36375
для меня это всё уже не сложно

>>36373

>я не очень понял


ну что тут непонятного? краткость записи.
77 1137079
>>37038

краткость записи чего? явно не селекта, если ты хочешь прописать алиас колонке из такой таблицы.

также если для тебя уже все несложно, расскажи как в доктрине запись из таблицы users_attributes с енамами, допустим 'param = age' указать в качестве поля $age сущности User(@ORM\Table(name="users"))
78 1137083
>>37079
Мне конкртно сейчас лень, для меня это уже слишком мелочи. Мб на днях загляну в тред.
79 1137100
Yii2 или ждать Yii2.1?
80 1137108
>>37083
лол. ну заглядывай.
81 1137134
>>37100
для РАБотки Yii2

а для себя это вообще не нужно
82 1137138
>>37108
...ну на прощание: просто не заморачивайся и делай.
83 1137146
>>37138
ага. как сердце подсказывает
84 1137150
>>36902

>Пхп не считает на ходу


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

Если же тебе хочется всё-в-одном-флаконе, то используй Access, царствие тебе небесное.

JS, в принципе, тоже это может, но скорее всего будут подводные камни и тебе придётся осваивать не только кондовый жс, но и серверную ноду.
15097526132231.png1,6 Мб, 1000x814
85 1137154
>>37150
Такой-то поток мысли...

Только не ajax, а sockets, с которыми шикарно работает РНР. И асинхронного РНР также полно, если вдруг ноде-дауны начнут кукарекать.

https://www.youtube.com/watch?v=i07m_TFR9no
86 1137155
>>37100
для работы здесь и сейчас yii2, т.к. его используют только в легаси и динозавры-тимлиды, которым лень переучиваться. они не будут обновляться еще 10 лет.

а для будущего развития более современные и актуальные фреймворки.
87 1137166
>>37155

>динозавры-тимлиды


любой убогий вкатывальщик пытается скомпрометировать реалии корпоративного сегмента, за что ему и гореть в аду нищеты.
large.jpg161 Кб, 500x299
88 1137170
>>37166
проблема двощей в том, что долбоёбы-вкатывальщики 2010+ тут имеют какое-то анонимное мнение, хотчя из приличных контор их гонят ссаными тряпками, ха
89 1137196
>>37166
я с симфони работаю и мне заебись. через месяцок перекатимся на четверку, а ты дальше сиди и правь легаси. сказочки про жестокую реальность и проверенные технологии рассказывай на вебмастер.ру
90 1137202
>>37196
Оставь свои фантазии себе. Что я делаю, никогда тут не заплалю, ты, ссаный неудачник.
91 1137223
>>35813
Умный анон не пришел, я в итоге дернул все с помощью Goutte и Symfony DomCrawler. Охуенно получилось.
15099279882892 (1).png1,3 Мб, 1191x799
92 1137268
смотрю https://rutracker.org/forum/viewtopic.php?t=5158544 ,уважаемые программеры и вкатывальщики-обсоски 2010+ могут присоединиться
93 1137278
>>1132552

Задача про вклад.

> $investor = вкладчику;


Строку надо брать в кавычки.

А так, решено верно.

>>1133423

> Чем отличается инструкция error_reporting(-1) от error_reporting(E_ALL)?


В error_reporting передается число. Функция преобразует его в двоичную систему счисления (двочичные числа - это числа, состоящие только из цифр 0 и 1 вроде 001011001, подробнее http://www.reshinfo.com/dvoichnaya_systema.php ). В этом двоичном числе каждый разряд соответствует виду ошибок, и если он установлен в 0, то PHP игнорирует этот вид ошибок. А если в 1 - то не игнорирует и сообщает о них.

Вообще, мне очень не нравится сама эта идея, что можно игнорировать какие-то ошибки и мне кажется, это очень вредная опция. Но оставим мое мнение в стороне.

E_ALL - это константа, в которой для всех видов ошибок стоит единица (ее значение можно увидеть тут http://php.net/manual/ru/errorfunc.constants.php ). -1 в двоичной форме выглядит как число из всех единиц (то есть единицы стоят даже там, где это не требуется). Зачем писать -1 вместо E_ALL? В старых версиях PHP была такая проблема, что E_ALL раньше не включала в себя определенный вид ошибок (E_STRICT), несмотря на название. Потому люди начали писать -1, чтобы гарантированно все ошибки и предупреждения были включены.

Сейчас конечно писать -1 нет никакого смысла и можно просто использовать E_ALL.

>>1133839

> Создавать класс-валидатор, который будет смотреть сколько файлов было отправлено, их размер и т.д. , или все это через middleware можно сделать?


Миддлвеар не для этого. Оно для вмешательства в процесс обработки запроса (оно может менять Request или Response), например:

- ограничение доступа (требовать пароль для доступа в админку)
- шифрование и подпись содержимого кук
- логгирование обрабатываемых запросов
- модификации HTTP-ответа, например, поддержка gzip-сжатия
- кеширование страниц целиком
93 1137278
>>1132552

Задача про вклад.

> $investor = вкладчику;


Строку надо брать в кавычки.

А так, решено верно.

>>1133423

> Чем отличается инструкция error_reporting(-1) от error_reporting(E_ALL)?


В error_reporting передается число. Функция преобразует его в двоичную систему счисления (двочичные числа - это числа, состоящие только из цифр 0 и 1 вроде 001011001, подробнее http://www.reshinfo.com/dvoichnaya_systema.php ). В этом двоичном числе каждый разряд соответствует виду ошибок, и если он установлен в 0, то PHP игнорирует этот вид ошибок. А если в 1 - то не игнорирует и сообщает о них.

Вообще, мне очень не нравится сама эта идея, что можно игнорировать какие-то ошибки и мне кажется, это очень вредная опция. Но оставим мое мнение в стороне.

E_ALL - это константа, в которой для всех видов ошибок стоит единица (ее значение можно увидеть тут http://php.net/manual/ru/errorfunc.constants.php ). -1 в двоичной форме выглядит как число из всех единиц (то есть единицы стоят даже там, где это не требуется). Зачем писать -1 вместо E_ALL? В старых версиях PHP была такая проблема, что E_ALL раньше не включала в себя определенный вид ошибок (E_STRICT), несмотря на название. Потому люди начали писать -1, чтобы гарантированно все ошибки и предупреждения были включены.

Сейчас конечно писать -1 нет никакого смысла и можно просто использовать E_ALL.

>>1133839

> Создавать класс-валидатор, который будет смотреть сколько файлов было отправлено, их размер и т.д. , или все это через middleware можно сделать?


Миддлвеар не для этого. Оно для вмешательства в процесс обработки запроса (оно может менять Request или Response), например:

- ограничение доступа (требовать пароль для доступа в админку)
- шифрование и подпись содержимого кук
- логгирование обрабатываемых запросов
- модификации HTTP-ответа, например, поддержка gzip-сжатия
- кеширование страниц целиком
94 1137291
>>35133

Надо написать преобразователь дерева AST, которое дает Symfony Expressions, в критерии для Query Builder.

>>35141

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


Во-первых, есть урок про обработку данных формы: https://github.com/codedokode/pasta/blob/master/forms.md

Во-вторых, полученные данные надо вставиь в БД. Для этого достаточно подготовить запрос с помощью PDO, а затем выполнить его с данными из формы. Это описывается в любой статье про PDO.

Также, наверно не надо ловить исключения и выводить их содерждимое пользователю. Логичнее логгировтаь подробности ошибки в лог, а пользователю показывать страницу-заглушку. Описано например тут: https://github.com/codedokode/pasta/blob/master/php/exceptions.md

>>35377

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


А в чем проблема? Я не понимаю. Никак специально их поддерживать не надо.

> Однако не понял, как хранить разные характеристики, ну есть, конечно, json,


Есть паттерн EAV.

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


По JSON - если БД поддерживает разбор и индексацию JSON (например Postgres), то ещ можно что-то сделать, если нет то EAV. Хотя у тебя с десятком кроватей проблем с производительностью в любом случае не будет.
95 1137292
>>35389

Получишь свалку нетипизированных данных, только и всего.

>>35546

Никак. Искать по связанным полям:

SELECT o FROM Order o
JOIN o.properties p
WHERE p.type = ? AND p.value = ?

Доктрина не позволяет произвольно мапить таблицы на сущности. Одна таблица - одна сущность.

>>35578

Сущность не должна работать с репозиторием. Она лишь представляет одну запись в таблимце и не занимается извлечением оттуда чего-то еще. Твой метод getWeight элементарно реализуется через отношения. Ты можешь почитать про отношения между сущностями в Доктрине: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html

Если получать weight напрямую неэффективно или невозможно (у тебя тысячи свойств на один заказ), и тебе надо работать с репозиторием, то метод getWeight придется перенести в репозиторий тоже:

public function findWeight(Order $order)

> не надо заморачиваться с привязкой поля типа ENUM к сущности, т.к. он по дефолту в Доктрине не поддерживается


Ставится string и вроде как все работает.

> и можно как-то намного лучше и изящнее.


Можно взять в Order свойства заказа, перебрать их и найти то, которое отвечает за weight. Хотя я не понимаю, зачем это свойство сделано через EAV. Если оно есть у всех товаров, его проще было просто как поле сделать.

>>35658

Не понимаю, что печального. Так и надо делать.
95 1137292
>>35389

Получишь свалку нетипизированных данных, только и всего.

>>35546

Никак. Искать по связанным полям:

SELECT o FROM Order o
JOIN o.properties p
WHERE p.type = ? AND p.value = ?

Доктрина не позволяет произвольно мапить таблицы на сущности. Одна таблица - одна сущность.

>>35578

Сущность не должна работать с репозиторием. Она лишь представляет одну запись в таблимце и не занимается извлечением оттуда чего-то еще. Твой метод getWeight элементарно реализуется через отношения. Ты можешь почитать про отношения между сущностями в Доктрине: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html

Если получать weight напрямую неэффективно или невозможно (у тебя тысячи свойств на один заказ), и тебе надо работать с репозиторием, то метод getWeight придется перенести в репозиторий тоже:

public function findWeight(Order $order)

> не надо заморачиваться с привязкой поля типа ENUM к сущности, т.к. он по дефолту в Доктрине не поддерживается


Ставится string и вроде как все работает.

> и можно как-то намного лучше и изящнее.


Можно взять в Order свойства заказа, перебрать их и найти то, которое отвечает за weight. Хотя я не понимаю, зачем это свойство сделано через EAV. Если оно есть у всех товаров, его проще было просто как поле сделать.

>>35658

Не понимаю, что печального. Так и надо делать.
96 1137293
>>35720

У тебя ошибка в синтаксисе SQL-запроса. Значения из формы тут вряд ли при чем. Попробуй такой же запрос руками в консоли выполнить и посмотреть, что будет.

>>35741

Потому что в теле класса нельзя писать код вроде $this->var = '2ch';, а можно писать только определения констант, полей и методов. А вот уже в методах писать код можно. Класс это не функция.

Если что, у нас есть в шапке учебник и там есть глава про ООП.

>>36049

> Вторая - браузер может использовать для рендеринга вкладок на одном домене один и тот же процесс с целью оптимизации, в заивисмости от браузера и его настроек.


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

Проверить можно, открыв инструменты разработчика (Ctrl + Shift + I) на вкладке Network и посмотрев, где висит. Также, можно попробовать strace на сервере посмотреть, где ждет php-fpm/apache.

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

>>36207

Это EAV.
97 1137298
Оп спасибо за прошлую проверку.
Посмотри новую версию студентов https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist3
98 1137299
>>36317

Производительность при такой схеме с монтированием файлов не очень высокая может быть.

Вагрант пытается решить проблему настройки окружения для проекта. Современные горекодеры это слово я сам придумал пишут такой код, что он ломается даже от смены минорной версии библиотеки (не говоря о смене дистрибутива или, упаси, замене ОС на винду), потому они придумывают способы как-то зафиксировать конфигурацию системы, в которой проект точно работает, и запускать приложение именно в этой системе. Разработчики языков вроде Го тоже любят периодически ломать совместимость, что добавляет мотивации.

Вдобавок, если у тебя несколько проектов, то они могут требовать разные версии программ, а в линуксе (в отличие от виндоуз) поставить параллельно разные версии программ сложно - попробуй поставь без компилятора несколько версий PHP или mysql. (линуксоиды делают пакетный менеджер nix/guix, который должен решить эти и другие проблемы и вообще хорош, но им никто не пользуется).

В принципе, ничего плохого в этом нет. Мы ведь используем менеджер пакетов composer для указания зависимостей. Логично, что серверный софт вроде mysql или nginx это тоже зависимости приложения и их стоит описывать. Но почему для этого нужна целая виртуальная машина?

В моем понимании, хватило бы просто строчки в ридми apt-get install php mysql nginx. Не знаю, почему другие так не могут. Для моих проектов обычно этого хватает.

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

Вагрант - позволяет настраивать виртуальную машину (virtual box) с помощью конфига на Руби. Обычно используется для описания среды для разработчика. При этом в конфиг можно включить установку в ВМ нужных программ. Про плюсы надо наверно читать документацию. Ну например, плюс то, что новый разработчик не должен мучаться с поиском и установкой программ, а просто выполняет одну команду и получает работающее окружение.

Как я понимаю, идея в том, что разработчик кладет в проект конфиг с описанием ВМ, а ты скачиваешь проект, запускаешь вагрант, он гудит пару часов и ты (если все хорошо и использованные пакеты не удалили из репозитория ОС) получаешь настроенную ОС в виртуалке, в которой проект 100% (а может и не 100) работает. Из минусов, как я понимаю, то, что там например может быть не тот дистрибутив, который тебе нравится, там может быть vi вместо нормального редактора, то есть все настроено не под тебя (как разработчик захотел, так и настроил). Плюс, виртуалка может работать медленно, занимать много места на диске. Ну например, вместо маленького дебиана кто-нибудь засунет туда многогигабайтный центос или десктопную убунту. Также, у тебя может быть например 3 Гб памяти, а кто-нибудь пропишет для виртуалки 2 Гб и она съест всю память.

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

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

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

Из плюсов - там есть хранилище готовых образов (Docker Hub).

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

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

Докеру есть альтернатива - lxc. Это свободный инструмент для запуска линукс-контейнеров. Плюсы в том, что его пишут не хипстеры на Го, а серьезные дядьки из Интел и они не навязывают какие-то паттерны использования, минусы в том, что когда я его последний раз пробовал, там многие вещи не работали вообще. Ну и фич меньше чем у докера.

Ансибл - позволяет на основе конфига (они называются плейбуки) настраивать по SSH сервер или группу серверов, можно использовать для деплоя (когда серверов много), для настройки серверов. Ну например, админ может сделать плейбук "поставить nginx, php, postgres" и в одну команду сконфигурировать чистый сервер или несколько серверов вместо того, чтобы заходить на каждый и что-то там править руками.

Хотя мне он не нравится тем, что ему нужен inventory файл и нельзя просто IP сервера в командной строке указать. Плюс, не работает под виндой нормально и под cygwin. Я хотел сделать на его основе playbook, который разворачивает VPN на произвольной чистой машине, но из-за inventory это не удобно и я вернулся к bash скриптам, у которых конечно корявый синтаксис, но нет такой проблемы.

> Встречал в интернете упоминания о том, что на докере/вагранте разворачивают себе рабочее окружение и мне стало интересно насколько это будет удобнее (и будет ли)



Ну проверь.
98 1137299
>>36317

Производительность при такой схеме с монтированием файлов не очень высокая может быть.

Вагрант пытается решить проблему настройки окружения для проекта. Современные горекодеры это слово я сам придумал пишут такой код, что он ломается даже от смены минорной версии библиотеки (не говоря о смене дистрибутива или, упаси, замене ОС на винду), потому они придумывают способы как-то зафиксировать конфигурацию системы, в которой проект точно работает, и запускать приложение именно в этой системе. Разработчики языков вроде Го тоже любят периодически ломать совместимость, что добавляет мотивации.

Вдобавок, если у тебя несколько проектов, то они могут требовать разные версии программ, а в линуксе (в отличие от виндоуз) поставить параллельно разные версии программ сложно - попробуй поставь без компилятора несколько версий PHP или mysql. (линуксоиды делают пакетный менеджер nix/guix, который должен решить эти и другие проблемы и вообще хорош, но им никто не пользуется).

В принципе, ничего плохого в этом нет. Мы ведь используем менеджер пакетов composer для указания зависимостей. Логично, что серверный софт вроде mysql или nginx это тоже зависимости приложения и их стоит описывать. Но почему для этого нужна целая виртуальная машина?

В моем понимании, хватило бы просто строчки в ридми apt-get install php mysql nginx. Не знаю, почему другие так не могут. Для моих проектов обычно этого хватает.

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

Вагрант - позволяет настраивать виртуальную машину (virtual box) с помощью конфига на Руби. Обычно используется для описания среды для разработчика. При этом в конфиг можно включить установку в ВМ нужных программ. Про плюсы надо наверно читать документацию. Ну например, плюс то, что новый разработчик не должен мучаться с поиском и установкой программ, а просто выполняет одну команду и получает работающее окружение.

Как я понимаю, идея в том, что разработчик кладет в проект конфиг с описанием ВМ, а ты скачиваешь проект, запускаешь вагрант, он гудит пару часов и ты (если все хорошо и использованные пакеты не удалили из репозитория ОС) получаешь настроенную ОС в виртуалке, в которой проект 100% (а может и не 100) работает. Из минусов, как я понимаю, то, что там например может быть не тот дистрибутив, который тебе нравится, там может быть vi вместо нормального редактора, то есть все настроено не под тебя (как разработчик захотел, так и настроил). Плюс, виртуалка может работать медленно, занимать много места на диске. Ну например, вместо маленького дебиана кто-нибудь засунет туда многогигабайтный центос или десктопную убунту. Также, у тебя может быть например 3 Гб памяти, а кто-нибудь пропишет для виртуалки 2 Гб и она съест всю память.

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

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

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

Из плюсов - там есть хранилище готовых образов (Docker Hub).

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

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

Докеру есть альтернатива - lxc. Это свободный инструмент для запуска линукс-контейнеров. Плюсы в том, что его пишут не хипстеры на Го, а серьезные дядьки из Интел и они не навязывают какие-то паттерны использования, минусы в том, что когда я его последний раз пробовал, там многие вещи не работали вообще. Ну и фич меньше чем у докера.

Ансибл - позволяет на основе конфига (они называются плейбуки) настраивать по SSH сервер или группу серверов, можно использовать для деплоя (когда серверов много), для настройки серверов. Ну например, админ может сделать плейбук "поставить nginx, php, postgres" и в одну команду сконфигурировать чистый сервер или несколько серверов вместо того, чтобы заходить на каждый и что-то там править руками.

Хотя мне он не нравится тем, что ему нужен inventory файл и нельзя просто IP сервера в командной строке указать. Плюс, не работает под виндой нормально и под cygwin. Я хотел сделать на его основе playbook, который разворачивает VPN на произвольной чистой машине, но из-за inventory это не удобно и я вернулся к bash скриптам, у которых конечно корявый синтаксис, но нет такой проблемы.

> Встречал в интернете упоминания о том, что на докере/вагранте разворачивают себе рабочее окружение и мне стало интересно насколько это будет удобнее (и будет ли)



Ну проверь.
99 1137300
>>36321

Я не очень понимаю, как что у тебя сделано, но конечно, тут надо использовать параметры роутов, чтобы был роут вроде /articles/{topic}/, то есть где раздел задан параметром. Контроллер смотрит на параметр и находит статьи из нужного раздела.

Если у тебя 2 уровня категорий, разделы и секции, то нужен еще роут /articles/{topic}/{section}/

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

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

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

- Чем раздел отличается от секции.

> Например, при переходе к статьям articles_IT


Что такое "статьи articles_IT"? Название роута? Название категории статей?

>>36373

Твой вопрос какой-то странный. Давай лучше рассмотрим товары. Правильно было написать "Есть таблица товаров, товары разной категории, у них бывают разные свойства. В чем плюсы/минусы EAV в сравнении с просто добавлением полей в таблицу с товарами (single table)". И как разные варианты реализовать с помощью ORM.

Вообще, надо начать с формулирования задачи. А она ставится так: есть сущность товар, есть разные варианты товаров, у каждого варианта есть свои наборы свойств (у телевизора - размер экрана, у стиральной машины - число оборотов).

Это называется "наследование таблиц", и там есть разные паттерны:

- http://design-pattern.ru/patterns/single-table-inheritance.html
- http://design-pattern.ru/patterns/concrete-table-inheritance.html
- http://design-pattern.ru/patterns/class-table-inheritance.html

То, что ты предлагаешь, добавлять колонки в одну таблицу - это как раз паттерн Single Table Inheritance.

Два других паттерна плохо работают для товаров, так как потребуют много таблиц, по числу категорий товаров. Тут-то на помощь и приходит EAV.

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

Сравниваем:

Плюсы EAV:

- в EAV новые свойства можно добавлять не меняя схему базы данных (не делая ALTER TABLE). Менеджер может делать это через админку, не привлекая программиста. В случае ORM, надо еще переделывать код при добавлении новых свойств.
- в схеме с single table (когда у нас есть одна таблица товара с кучей колонок), если свойств много, то колонок тоже будет очень много - сотни, и мы упремся в разные ограничения БД и потери производительности. В случае ORM, у нас еще будет гигантский класс с сотней полей, с которым неудобно работать.
- в single table, если свойств много, то большинство колонок будут хранить null и просто зря расходовать место
- в single table никак не определено, какие свойства могут быть у той или иной категории товара. В EAV это можно определить через связи.
- в single table для эффективного поиска надо создавать огромное число (десятки и сотни) индексов, что негативно скажется на производительности и требует кучу места

Минусы EAV:

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

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

Если ты знаешь еще минусы, напиши. Но я смотрю на список плюсов/минусов и не понимаю, где выигрыш в использовании Single Table Inheritance.

> если у нас есть доп.таблица user_attributes(age, sex)


То не очень понятно, зачем она нужна и что мешает эти колонки сразу поместить в таблицу users. Не понятно, зачем вы городите EAV для таблицы пользователей, которые явно отличаются от товаров. Ради производительности?

> то мы сущности User (которая лежит в таблице users) можем задать поле $sex, которое по связи OneToOne будет ссылать на столбец sex из таблицы с аттрибутами.


Не можем. Мы не можем в одном классе замапить поле на колонку из другой таблицы. Мы можем только связать поле с другой сущностью (user_attributes).

> а если у таблицы структура users_attributes(param enum('age','sex'), value), то мы так сделать уже не можем.


Доктрина так не работает. Она мапит таблицы на классы так, что одна таблица обычно соответствует одному классу, а колонки в таблице - полям класса. Нельзя в один класс замапить колонки из разных таблиц.

Но это и не нужно. Ты в сущности User можешь получить атрибуты и найти в них то, что тебе нужно.

> можно было бы сказать, что так мы можем добавлять любое количество параметров без изменения таблицы, но это не так - все равно придется менять столбец param - добавлять в него разрешенные значения.


Это у вас не EAV. В EAV для разрешенных значений обычно делают таблицу.

> короче я не понимаю, в чем плюсы.


Скорее всего там у пользователя много атрибутов, большинство их не заполняет и им не хочется хранить NULL. Но вообще, почему так сделано, надо спрашивать у тех, кто это делал.
99 1137300
>>36321

Я не очень понимаю, как что у тебя сделано, но конечно, тут надо использовать параметры роутов, чтобы был роут вроде /articles/{topic}/, то есть где раздел задан параметром. Контроллер смотрит на параметр и находит статьи из нужного раздела.

Если у тебя 2 уровня категорий, разделы и секции, то нужен еще роут /articles/{topic}/{section}/

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

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

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

- Чем раздел отличается от секции.

> Например, при переходе к статьям articles_IT


Что такое "статьи articles_IT"? Название роута? Название категории статей?

>>36373

Твой вопрос какой-то странный. Давай лучше рассмотрим товары. Правильно было написать "Есть таблица товаров, товары разной категории, у них бывают разные свойства. В чем плюсы/минусы EAV в сравнении с просто добавлением полей в таблицу с товарами (single table)". И как разные варианты реализовать с помощью ORM.

Вообще, надо начать с формулирования задачи. А она ставится так: есть сущность товар, есть разные варианты товаров, у каждого варианта есть свои наборы свойств (у телевизора - размер экрана, у стиральной машины - число оборотов).

Это называется "наследование таблиц", и там есть разные паттерны:

- http://design-pattern.ru/patterns/single-table-inheritance.html
- http://design-pattern.ru/patterns/concrete-table-inheritance.html
- http://design-pattern.ru/patterns/class-table-inheritance.html

То, что ты предлагаешь, добавлять колонки в одну таблицу - это как раз паттерн Single Table Inheritance.

Два других паттерна плохо работают для товаров, так как потребуют много таблиц, по числу категорий товаров. Тут-то на помощь и приходит EAV.

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

Сравниваем:

Плюсы EAV:

- в EAV новые свойства можно добавлять не меняя схему базы данных (не делая ALTER TABLE). Менеджер может делать это через админку, не привлекая программиста. В случае ORM, надо еще переделывать код при добавлении новых свойств.
- в схеме с single table (когда у нас есть одна таблица товара с кучей колонок), если свойств много, то колонок тоже будет очень много - сотни, и мы упремся в разные ограничения БД и потери производительности. В случае ORM, у нас еще будет гигантский класс с сотней полей, с которым неудобно работать.
- в single table, если свойств много, то большинство колонок будут хранить null и просто зря расходовать место
- в single table никак не определено, какие свойства могут быть у той или иной категории товара. В EAV это можно определить через связи.
- в single table для эффективного поиска надо создавать огромное число (десятки и сотни) индексов, что негативно скажется на производительности и требует кучу места

Минусы EAV:

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

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

Если ты знаешь еще минусы, напиши. Но я смотрю на список плюсов/минусов и не понимаю, где выигрыш в использовании Single Table Inheritance.

> если у нас есть доп.таблица user_attributes(age, sex)


То не очень понятно, зачем она нужна и что мешает эти колонки сразу поместить в таблицу users. Не понятно, зачем вы городите EAV для таблицы пользователей, которые явно отличаются от товаров. Ради производительности?

> то мы сущности User (которая лежит в таблице users) можем задать поле $sex, которое по связи OneToOne будет ссылать на столбец sex из таблицы с аттрибутами.


Не можем. Мы не можем в одном классе замапить поле на колонку из другой таблицы. Мы можем только связать поле с другой сущностью (user_attributes).

> а если у таблицы структура users_attributes(param enum('age','sex'), value), то мы так сделать уже не можем.


Доктрина так не работает. Она мапит таблицы на классы так, что одна таблица обычно соответствует одному классу, а колонки в таблице - полям класса. Нельзя в один класс замапить колонки из разных таблиц.

Но это и не нужно. Ты в сущности User можешь получить атрибуты и найти в них то, что тебе нужно.

> можно было бы сказать, что так мы можем добавлять любое количество параметров без изменения таблицы, но это не так - все равно придется менять столбец param - добавлять в него разрешенные значения.


Это у вас не EAV. В EAV для разрешенных значений обычно делают таблицу.

> короче я не понимаю, в чем плюсы.


Скорее всего там у пользователя много атрибутов, большинство их не заполняет и им не хочется хранить NULL. Но вообще, почему так сделано, надо спрашивать у тех, кто это делал.
100 1137301
>>36406

> Допустим, я подобрал для сотен тысяч форму слова, отбросив по три цифры с концов, а на деле число оказалось миллиардом. Остальные шесть цифр не переведутся же.



Если тебе нужно число тысяч (от 0 до 999) то ты сначала берешь 6 последних цифр числа, потом отбрасываешь 3 последние цифры. И остается ровно 3 цифры, больше 1000 там никогда не получится.

Если тебе нужно число единиц, ты опять же, берешь только 3 последние цифры и больше 999 там не получится.

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

>>36720

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

Иначе тебе придется делать полноценный планировщик запросов, который должен формировать SQL запросы, запросы к API и объединять их результаты. Попробуй написать выражение посложнее чем A AND B и ты увидишь, как там все запутанно.

Тебе надо формировать условие из того, что предлагает Query Builder, все эти $expr->equals(...).

>>36874

Какие именно символы? Вот, например, регулярка, которая ищет восклицательные и вопросительные знаки:

/[?!]/u

Это символьные классы: http://php.net/manual/ru/regexp.reference.character-classes.php

Или тебе надо искать "все символы из всех алфавитов мира"? для этого есть юникодные свойства: http://php.net/manual/ru/regexp.reference.unicode.php
100 1137301
>>36406

> Допустим, я подобрал для сотен тысяч форму слова, отбросив по три цифры с концов, а на деле число оказалось миллиардом. Остальные шесть цифр не переведутся же.



Если тебе нужно число тысяч (от 0 до 999) то ты сначала берешь 6 последних цифр числа, потом отбрасываешь 3 последние цифры. И остается ровно 3 цифры, больше 1000 там никогда не получится.

Если тебе нужно число единиц, ты опять же, берешь только 3 последние цифры и больше 999 там не получится.

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

>>36720

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

Иначе тебе придется делать полноценный планировщик запросов, который должен формировать SQL запросы, запросы к API и объединять их результаты. Попробуй написать выражение посложнее чем A AND B и ты увидишь, как там все запутанно.

Тебе надо формировать условие из того, что предлагает Query Builder, все эти $expr->equals(...).

>>36874

Какие именно символы? Вот, например, регулярка, которая ищет восклицательные и вопросительные знаки:

/[?!]/u

Это символьные классы: http://php.net/manual/ru/regexp.reference.character-classes.php

Или тебе надо искать "все символы из всех алфавитов мира"? для этого есть юникодные свойства: http://php.net/manual/ru/regexp.reference.unicode.php
101 1137302
>>37154

Сокеты тут зачем? Тут же не чат. Тут просто пользователь меняет параметры и у него должна обновиться картинка. Сокеты тут не нужны и только все осложнят. Хватит аякса. А может даже это все можно рендерить на стороне браузера не дергая сервер.

> с которыми шикарно работает РНР


Если ты про ReactPHP, то он на мой взгляд не шикарный. Работа с исключениями там сломана везде - в промисах, в потоках. Как и в ноде, впрочем.
102 1137303
>>37298

Нужен ридми. Прочитай комментарии к задаче, там это написано: https://github.com/codedokode/pasta/blob/master/student-list.md#Публикация-проекта

А то открываешь, видишь кучу файлов и даже непонятно, что это.
103 1137304
>>37298

Файлы примеров желательно удалить. Вот зачем нужен этот файл например? https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist3/blob/master/tests/Feature/ExampleTest.php

Если ты не используешь тесты, то файлы от них не нужно добавлять.
104 1137309
>>36317

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

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

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

Ну и статью вот сегодня увидел про контейнеры: https://queue.acm.org/detail.cfm?id=3185224
105 1137350
Товарищи, подскажите, хватит планшета на винде с 1гб ОЗУ для изучения азов php+mysql+js?
106 1137371
>>37350

Читать учебники - хватит. А вот можно ли туда поставить php/mysql - большой вопрос. Какой там процессор? Какая архитектура? Есть ли рут?

То, что там windows не значит, что приложения для десктопа там запустятся. Или все же запустятся?
107 1137381
>>37371
Запустятся, проц - слабенький атом
108 1137385
>>37381
Процессор
Intel Atom Z3735G 1330 МГц
Количество ядер
4
15183091514260.jpg319 Кб, 1536x2048
109 1137393
>>37371
Что бы заниматься на php достаточно поставить Notepad++?
110 1137402
>>37300
спасибо! не знал про EAV, буду изучать.

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

>>37301

>придется делать полноценный планировщик запросов


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

>Попробуй написать выражение посложнее чем A AND B



да, там получаются пугающие конструкции
111 1137403
>>37393
atom/vscode?
112 1137410
>>37393
Львиная доля работы, у меня, проходила только в нотпаде. Его хватало с головой. А так, есть ещё Brackets, от Adobe. Сорта говен. Когда пд рукой тяжелые проекты, то потребуется какая-нибудь IDE, чтоб проводник в интерфейсе был, да и наглядность проекта не страдала.
113 1137419
Алсо, для локального пхп сервера с мускулем гига не хватит?
114 1137444
>>37419

Хватит конечно, даже меньше. Майскул будет потреблять столько, сколько ты ему пропишешь в конфиге, если база маленькая, то сотни Мб хватит. PHP скрипты обычно потребляют в районе 50 Мб, но композер с большим числом пакетов может иногда и гиг откушать - тут вся надежда на своп.
115 1137474
Как лучше назвать класс, который занимается тем, что добавляет спарсенные новости из твиттера в качестве сущностей "статьи" на сайт?

Что-то типа "СоздательКонтента", но не так по-уебански. Фантазия закончилась
116 1137483
>>37474
ContentMaker
117 1137490
Хочу глянуть 1 глазком на решения задач из учебника. конкретно задача про поиск пути по карте. Кто-то даст ссылку на idone
118 1137509
>>37483
лол, ты не поверишь, я пока так и назвал сам.
хотя это не совсем точно, он ведь его не делает, а добавляет - делает-то его твиттер.

но думаю, так тоже ок.
119 1137514
>>37444
Хорошо, большое спасибо!
120 1137558
>>37299
Большое спасибо, именно то, что мне хотелось прочитать!
121 1137577
Дайте чего толкового почитать по редиректу, сессиям и кукам. Желательно с рабочим примером.
122 1137580
>>37577
ЗЫ редирект надо на то место на странице, откуда был произведен переход. Т.е. скроллю страницу, клацнул линк, перешел и что-то сделал, затем обратно.
124 1137582
>>37580
header('Location: '. $_SERVER['HTTP_REFERER']);
125 1137589
Собираюсь учить по 5 часов в сутки / 5 дней в неделю. Будут ли шансы при таком режиме устроиться джуном в конце лета? Первый яп, в универе только бейсик и матлаб ковыряли.
Кун с тех вышкой, не ит
126 1137595
В задаче "Игра в кубики" что я де так делаю?
127 1137596
>>37595
у тебя кавычки в фигурных скобках
128 1137597
>>37589
Да, шансы высоки.
Screenshot83.png41 Кб, 996x492
129 1137600
>>37596
Всё равно не работает!
130 1137601
>>37589
будут большие шансы, что через неделю ты без вести пропадешь из треда
131 1137603
>>37474

TweetLoader, TweetScraper.

>>37490

Берешь любой алгоритм поиска пути вроде https://ru.wikipedia.org/wiki/Алгоритм_Дейкстры и ищешь его реализации на нужном тебе языке.

>>37577

Не дам тебе ничего по сессиям, но редиректы и куки описаны в моем уроке по HTTP: https://github.com/codedokode/pasta/blob/master/network/http.md

>>37582

Это плохой вариант, плюс нет никакой проверки что в реферере, и есть ли он вообще, лучше явно указывать ?from=feed для указания, куда надо вернуться. Естественно, надо этот параметр тщательно проверять, чтобы не отправить юзера по какой-то плохой ссылке.
132 1137610
Как пользоваться функцией str_getcsv(...)?

https://secure.php.net/manual/ru/function.str-getcsv.php

>enclosure


>Устанавливает символ ограничителя поля (только один символ).


Что такое ограничитель поля?

>escape


>Устанавливает экранирующий символ (только один символ). По умолчанию равен обратному слешу (\).


И от чего и что будет экранироваться?

Данные примерно в таком варианте

NAME
SOME_STRING = SOMEDATA
COLUMNS = something,another,somethinganother,...
1,135.02,135.09,133.25,133.47,33226223
2,135.51,136.27,134.62,135.52,35623100
3,135.345,135.9,134.8398,135.67,22584555

Нужно получить что-то вроде

[
"NAME",
"SOME_STRING" => "SOMEDATA",
"COLUMNS" => ["something", "another", "somethinganother", ...],

"DATA" => [[1, 135.02, 135.09, 133.25, 133.47, 33226223 ], [2, 135.51, 136.27, 134.62, 135.52, 35623100], [3, 135.345, 135.9, 134.8398, 135.67, 22584555]]
]

Текущих знаний мне хватает чтобы спарсить каждую строчку с помощью str_getcsv($s, "\n"), и затем вручную преобразовать массив с помощью регулярных выражений
Это лучший способ и данная функция не предусматривает лучших решений?
132 1137610
Как пользоваться функцией str_getcsv(...)?

https://secure.php.net/manual/ru/function.str-getcsv.php

>enclosure


>Устанавливает символ ограничителя поля (только один символ).


Что такое ограничитель поля?

>escape


>Устанавливает экранирующий символ (только один символ). По умолчанию равен обратному слешу (\).


И от чего и что будет экранироваться?

Данные примерно в таком варианте

NAME
SOME_STRING = SOMEDATA
COLUMNS = something,another,somethinganother,...
1,135.02,135.09,133.25,133.47,33226223
2,135.51,136.27,134.62,135.52,35623100
3,135.345,135.9,134.8398,135.67,22584555

Нужно получить что-то вроде

[
"NAME",
"SOME_STRING" => "SOMEDATA",
"COLUMNS" => ["something", "another", "somethinganother", ...],

"DATA" => [[1, 135.02, 135.09, 133.25, 133.47, 33226223 ], [2, 135.51, 136.27, 134.62, 135.52, 35623100], [3, 135.345, 135.9, 134.8398, 135.67, 22584555]]
]

Текущих знаний мне хватает чтобы спарсить каждую строчку с помощью str_getcsv($s, "\n"), и затем вручную преобразовать массив с помощью регулярных выражений
Это лучший способ и данная функция не предусматривает лучших решений?
Screenshot1.png48 Кб, 1142x563
133 1137615
>>37596
Заработало, спасибо.
134 1137620
почему на сегодняшний таймстамп

dump(new \DateTime(1518441713));die;

выдает
DateTime @-8106433893 {#1894
date: 1713-02-12 15:18:44.0 Europe/Moscow (+02:30)
}

?
135 1137629
>>37620
понял. он не понимает таймстамп, ему надо дату слать.
136 1137664
ОП, как знать столько же, сколько и ты? я знаю некоторых синьоров-тимлидов, у них даже близко таких знаний нет.
137 1137667
>>37610

Глянь https://ru.wikipedia.org/wiki/CSV

Прочти это, там немного и на русском: http://tradeincome.ru/useful-content/RFC 4180 rus.pdf

Там определены 3 символа:

- разделитель полей (по ум. запятая)
- ограничитель поля, символ кавычки (то есть символ, в который можно заключать строки с пробелами и запятыми внутри)
- экранирующий символ (по ум. бекслеш). Он позволяет например вставить кавычку внутрь строки как \" Я не вижу его в RFC, может это какое-то дополнение. В RFC написано что кавычка вставляется как 2 кавычки и значит экранирующим символом должен быть не бекслеш, а кавычка.

> Что такое ограничитель поля?


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

> И от чего и что будет экранироваться?


Если у тебя есть строка в кавычках "xxx" и тебе надо внутрь нее вставить кавычку, то можно писать "xx\"x" c использованием экранирующего символа. Я не вижу этой особенности в RFC, наверно это какое-то дополнение. В RFC экранирующий символ это кавычка и надо писать "xx""x"

> Это лучший способ


Вполне хороший способ.
138 1137669
>>37664

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

Ну и я не так и много знаю - на Хаскелле написать программу не смогу и рассчитать нейронную сеть тоже вряд ли.
139 1137670
>>37664

Также, не ограничивай себя одним языком, или только высокоуровневыми скриптовыми языками, изучай разные вещи.
140 1137678
>>37664
шо там в вашей деревне называют синьерами тогда )
141 1137694
>>37669
сенкс. решаю задачку про тестхаб, чтобы послушать твои комменты, но мало свободного времени, поэтому небыстро идет.

>>37678
такое дело, я из дс, братюнь
142 1137701
>>37664
Разве в похапе используется такая же классификация как и у программистов?
143 1137705
>>37701
твои попытки троллить вызывают жалость, братюнь
144 1137738
>>37705
Ответить на вопрос не смог.
Так и запишем.
145 1137743
>>37701
define программист
146 1137790
Мда, ОП. Какая же сложная хуйня этот Angular. Да и остальные варианты не лучше. Без этого вот всего не получится SPA?
147 1137791
>>37790
vk это тоже spa
и они не использзуют ни ангуляров ни реактов, ничего, все на ваниле
так что дело лишь в твоих прямых руках
148 1137807
>>37791
Счас бы вк написать.

>Таким образом, у тебя есть выбор из как минимум



>backbone + knockout angular 2 react + redux vue.js



ОП требует фреймворк!

И да, на ванилле я охуею писать все это, я не смогую.
149 1137814
>>37790
Пиши на ваниле. Потихонечку захочется согласованности данных, инъекций зависимостей, реактивности и прочего. В результате через пару лет напишешь свой гуляр, только кривой.
Сложный он потому, что сложен из множества решений, которые необходимы для больших команд и длительной поддержки. А тебе они не очевидны потому, что у тебя таких потребностей не возникает пока.
150 1137817
>>37807

>Счас бы вк написать.


Это как пример большого весьма сложно SPA, написанного без хайп-фреймворков. И работающий, заметь, быстрее чем те же фейсбук и инстаграм на реактах.
151 1137837
>>37301

>Какие именно символы?


Я имел ввиду всё, кроме букв и цифр, но сейчас внезапно сам во всём разобрался
оказалось достаточно было написать \\D вместо \D
152 1137896
если у меня в доктрине есть две сущности, Article и Tag (связь many-to-many), то как мне выбрать теги с сортировкой по количеству статей, с которыми они связаны?

т.е.

class Tag
{
/
@var ArrayCollection

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

пока придумал только так:
return $qb
->select('t')
->from('App:Tag', 't')
->addSelect('COUNT(a.id) as HIDDEN articles')
->join('t.articles', 'a')
->groupBy('t.id')
->orderBy('articles', 'DESC')
->getQuery()
->getResult();

есть какой-то более очевидный способ? задача-то, мне кажется, типовая
153 1137984
>>37791

Вконтакте не SPA. Там используется штука вроде pajax, то есть оно перехватывает клики по ссылкам, отправляет аякс-запрос и обновляет DOM. По сути только экономит немного времени на перезагрузке страницы. Он не хранит данные локально, не работает в оффлайне, итд.
154 1138010
Ананасы, ищу пхпшника на текущий проект (уии2) на удаленочку. Где вас можно найти? Какие ресурсы?
155 1138022
>>37984
А когда просто фреймы использовали...
156 1138043
>>38022

Просто фреймы это очень неудобно для разработчика и плохо для SEO.
157 1138080
Не понимаю, что сделал не так и почему вообще ничего не выводит мне из echo?
158 1138091
>>38080

>procent


>komisia


>zaplacheno


>nachalo


>mesyac


Прекрати.
159 1138099
>>38091

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

Но, конечно, когда ты показываешь код другому, этот транслит в именах переменных или функций бросается в глаза. Потому, что так сложилось, что переменные называют по-английски, и не нам эти правила менять. (хотя сам PHP позволяет использовать кириллицу в именах: $месяц = 1; например).

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

Ну и конечно, анону, если он не знает английский, стоило бы потихоньку начинать его осваивать. Наверняка на собеседовании про знание английского спросят, и знать какие-то основы лучше, чем ничего. Уроков для начинающих, я думаю, в интернете полно.
160 1138101
>>38080

У тебя в условии цикла for стоит $mesyac <=0 то есть цикл выполняется только ПРИ УСЛОВИИ ЧТО месяц меньше или равен нулю. Это условие не выполняется и цикл потому не выполняется не разу.
blob28 Кб, 420x480
161 1138102
>>38080

Вот кстати у меня в уроке даже картинка с алгоритмом нарисована ведь.
162 1138109
>>38010
fl.ru, upwork если на проект
Screenshot9.png46 Кб, 982x547
163 1138166
>>38091
Что прекратить? Ну не знаю я английский и денег нет пойти на курсы.
>>38101
Спасибо, частично заработала.
>>38102
Отдельное спасибо тебе за гайд с примерами, ты молодец! :3
164 1138209
>>38166
с таким подходом денег и не будет много. какие блядь курсы? в инторнете что ли мало бесплатных ресурсов для изучения языка?
165 1138215
Пацаны, есть вопросик по регуляркам.

Есть две переменные: $query и $content.
В $query, например, лежит "foo bar", а в $content "bar baz baz foo".

Задача: заменить в $content каждое найденное слово на его же, окруженное в <i></i>. Я делаю это костыльно вот так:

$pattern = explode(' ', $query);
foreach ($pattern as $item) {
$content = preg_replace("~$item~", "<i>$item</i>", $content);
}

Но это говно, т.к. несколько раз выполняется preg_replace. Думал сделать как-то типа

$pattern = preg_replace(' ', '|', $query);
$content = preg_replace("~($item)~", "<i>$item</i>", $content);

Но каждый раз подставляется foo|bar. Как можно решить задачу, используя переменные рерулярок типа (?<item>.+?)?
166 1138224
>>38209

>какие блядь курсы?


Alibra School например, в прошлом году хотел пойти туда, но денег нет (они простят 30к за 9 месяцев обучения).
В интернете тяжело учить, пробовал duolingo, но мотивации не хватило и обучение мне показалось сомнительным.
167 1138226
Кстати о курсах. Что лучше выбрать из этого? будет возможность поехать на обучение на 8 месяцев.
168 1138322
>>38224
не знаю, я начинал с того, что смотрел симпсонов на английском, а щас вообще не употребляю русский контент (кроме двачей, конечно). правда я этой хуйней много лет занимаюсь
169 1138327
>>38224
у меня просто пунктик такой, мол стыдно английский не знать. поэтому я всегда если незнакомое слово встречаю, не подаю вида, а потом бегу в словарь смотрю.
171 1138456
>>38102
Хотел сделать задачку, а она не решается (ну скорее Я тупой).

Типо:
1 год :
10000руб. x 1.1 = 11000 руб.
2год:
11000 руб. x 1.1 = 12100 руб.
3год:
12100 руб. x 1.1 = 13310 руб.

и т.д.
Но что-то пошло не так.
172 1138462
Нужно реализовать такую вещь: есть сайт, на нем нужно сделать GUI реализацию смены бэкграунда по css. То есть есть кнопка - жмем, загружаем на сервак файл и этот файл применяется как фон сайта. Всяко разно пробовал гуглить, но не нашел
173 1138471
>>38462
Ну а хули тут сложного, анонче? Нужно css загружать, да, чтобы он заменял собой исходный?
Ну, я бы сделал так.
Написал бы форму, которая отправляла бы css на сервер и упаковывала его в отдельную папочку. Путь к этому новому файлику прописывался бы куда-нибудь (в базу, например).
В базе (опять же, например), указано какой из файлов является в данный момент активным.
Вместо пути к статическому файлу в ссылке можно указать ссыль на файл-обработчик, типа ttps://site.ru/getcss.php
Там файл бы отдавал нужный (активный) файл, указывая необходимые заголовки.
Ну или тупо заменять один файл другим, если старый не нужен.

Я не уверен, что правильно понял твою задачу, анон, но она, в любом случае, не сложная. Тут не гуглить нужно, а включать воображение. Решить можно разными способами.
174 1138472
>>38462
Две части задачи: загрузка файла на сервер и изменение css
По первому куча примеров в гугле. По второму, в принципе, тоже. Изменение css - это что-то типа вот этого кода (вытащил со своего проекта, суть, думаю, понятна):
$('#overlay').fadeIn(400, function(){ $('#popup')
.css('display', 'block')
.animate({opacity: 1, top: '50%'}, 200);});
175 1138473
>>38471
Бля, я тупой, кажется. Неправильно понял. Сорянъ.
176 1138477
>>38472

>$('#overlay').fadeIn(400, function(){ $('#popup')


>.css('display', 'block')


>.animate({opacity: 1, top: '50%'}, 200);});


Как я понимаю это окошко для загрузки и правило его анимации. Я полный нуп, крайне сложно вникать в это все.
177 1138489
>>38477
Я в своей cms-ке сделал настройку темы через GUI (ну там, размеры шрифтов, цвета основных элементов, отступы и пр.) самым тупым способом - все данные храняться в базе в одном поле, которое сериализовано (количество полей статично, поэтому undefined index не будет), но в html-ке вся эта залупа выводится в теге style после подключения основных css.
Ну что-то типа

<style>
<?php if( $theme["background-color"] ):?>
body {background-color: #<?php echo $theme["background-color"]; ?>}
<?php endif; ?>
...
</style>

Да, довольно нубски, но какая разница? Работате же.

В противном случае, может есть шанс при загрузке генерировать отдельный css для background-image? Дополнительный css для фонового изображения типа. Там тупо вставляешь строку, дополняя путем до новой имаги.
178 1138490
>>38489

>храняться


Стыдно пиздец
179 1138491
>>38477
Я имел в виду, что таким же образом ты можешь работать и с другими свойствами css. Например, backround-color
180 1138560
>>38471

Там анону нужно только фоновую картинку загружать. Вместо скрипта генерации CSS проще нужные стили вписать в <style>.
181 1138593
>>37790
Попробуй Vue.js, он проще и совместим с jQuery
правда, это бед практис

И вообще SPA можно и на jQuery написать

Вопрос в тему, на чем лучше попробовать написать фронтенд для браузерной игры?

>>38224
В /fl есть годные гайды по изучению английского. В этом, как раз главное погружение, та что когда пишешь код представляй что ты флюент и используй только английский.
182 1138624
183 1138652
>>37694

>я из дс


Я тоже. Видимо, соц. слои разные ;)
НИД ХЕЛП YII2 184 1138662
Сап народ, хочу оседлать yii2, до этого на другом языке использовал другой фреймворк, но не суть. У меня есть 2 модели, товар и категории товара. Модель категории содержит поля - id name, модель товары содержит поля, id, name, category_id - связанное с моделью категории. В greedview товары я вывожу id, name, category.name, при создании нового товара вместо category.name приходится указывать category_id. В идеале хочу добиться чтобы в форме создания было выпадающее меню с именами категорий.
185 1138698
Обязательно нужно уметь верстать бекендеру ?
186 1138713
>>38698
Нет, но стоит понимать что происходит и как делается на фронте.

Но все сейчас хотят фулстеков т.е. бек + фронт,
правда во фронт не всегда входит вёрстка
htaccess.jpg30 Кб, 462x262
187 1138863
Подскажите, будет ли такая конфигурация htaccess (пикрелейтед) безопасной.

По умолчанию открывается доступ ко всему, но все, кроме статики (js, css, картинки и прочее) редиректится на /index.php, где уже будет парситься REQUEST_URI и выдаваться 404-ошибка как для несуществующих файлов, так и для запрещенных к просмотру.

Есть ли у такого подхода какие-нибудь изъяны по сравнению со стандартным, когда с помощью htaccess закрывается доступ к папкам и файлам?
188 1138889
Вообщем попытался решить задачу.Получилось как-то со скрипом.Дайте советов мудрых как всё это надо нормально делать.
189 1138892
>>38889

>Вообщем


>у.П


>м.Д


Прекрати.
190 1138893
>>38892
Ну извини я нервный и не заметил
191 1138894
>>38893
Процент по-английски это percent
192 1138904
>>38889

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

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

a = a + b;

можно записывать короче с помощью оператора

a += b;

Это может тут пригодиться.

Также, если ты посмотришь, то в шапке цикла стоит условие $total <= 1000000. Раз оно есть, то if с break не очень-то и нужен. Единственное, в условии неточность - если у нас уже есть ровно миллион, то цикл продолжать не надо. Выполнять цикл надо только пока денег меньше чем миллион.

>>38892

Не надо замусоривать тред не имеющими пользы комментариями. У нас учебный тред, а не пикабушечка.
193 1138931
>>38863

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

Вот тут немного описано это: https://github.com/codedokode/pasta/blob/master/student-list.md#Выносим-код-за-корень-сервера

>>38698

Какие-то простые вещи сверстать или поправить существующую верстку - конечно. Кстати, в ОП посте есть набор задач по HTML/CSS, после прохождения которого как раз будет нужный уровень.

>>38215

Тебе нужен preg_replace_callback либо preg_replace с массивом слов и замен. Посмотри мануал по этим функциям.

>>38456

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

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

$x = ... - создает переменную или меняет значение существующей
echo ... - выводит строки и числа, в том числе переменные
if (условие) { действия } - выполняет действия, если выполняется условие
for (...) { ... } - выполняет одни и те же действия много раз в цикле
break - немедленно выходит из цикла

Если ты забыл эти команды, перечитай предыдущие уроки или мануал PHP.

Если мы посмотрим на твой код, то мы увидим там куски, которые не имеют никакого смысла, например:

($rubley < 1000000);

Эта строчка проверяет, меньше ли $rubley чем указанная сумма, но с результатом проверки ничего не делает - она не сохраняет результат в переменную и не использует его в конструкции if. То есть она бесполезна.

Далее, если мы посмотрим сюда, то увидим другую ошибку:

$rubley = ($seychas * $procent) + $rubley;

Здесь справа использована переменная $seychas, но на момент выполнения команды такой переменной еще не существует. Строчка, которая ее создает, расположена ниже.

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

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

Вернемся к алгоритму. Как бы его записать, используя только перечисленные выше команды? Ну например, так:

------

пусть суммаНаСчету равна 10000;
пусть процент равен 1.1;

меняем возраст вкладчика от 16 до 108 лет с шагом 1 год, выполняя каждый год {

увеличить суммуНаСчету на процент;

если (на счету миллион или больше) {
выйти из цикла;
}

увеличить возраст вкладчика;
}

вывести ответ к задаче;

------

Ну а дальше надо переписать это с помощью команд выше.

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

пока (на счету меньше миллиона) {
увеличить сумму на счету;
увеличить возраст на 1;
}

Но как эту конструкцию "пока" перевести в код? Тут есть такой вариант:

for (; $sum < 1000000 ;) {
...
}

(если ты забыл,что это значит, перечитай урок про циклы внимательно). Мы не пишем в шапке цикла начальное действие и действие, которое выполняется после каждого шага, а оставили только условие продолжения. Но для таких случаев есть более короткая запись - цикл while:

while ($sum < 1000000) {
тело цикла выполняется до тех пор, пока условие вверху выполняется;
}

Подробнее: http://php.net/manual/ru/control-structures.while.php

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

Если что-то непонятно, задавай вопросы.
193 1138931
>>38863

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

Вот тут немного описано это: https://github.com/codedokode/pasta/blob/master/student-list.md#Выносим-код-за-корень-сервера

>>38698

Какие-то простые вещи сверстать или поправить существующую верстку - конечно. Кстати, в ОП посте есть набор задач по HTML/CSS, после прохождения которого как раз будет нужный уровень.

>>38215

Тебе нужен preg_replace_callback либо preg_replace с массивом слов и замен. Посмотри мануал по этим функциям.

>>38456

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

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

$x = ... - создает переменную или меняет значение существующей
echo ... - выводит строки и числа, в том числе переменные
if (условие) { действия } - выполняет действия, если выполняется условие
for (...) { ... } - выполняет одни и те же действия много раз в цикле
break - немедленно выходит из цикла

Если ты забыл эти команды, перечитай предыдущие уроки или мануал PHP.

Если мы посмотрим на твой код, то мы увидим там куски, которые не имеют никакого смысла, например:

($rubley < 1000000);

Эта строчка проверяет, меньше ли $rubley чем указанная сумма, но с результатом проверки ничего не делает - она не сохраняет результат в переменную и не использует его в конструкции if. То есть она бесполезна.

Далее, если мы посмотрим сюда, то увидим другую ошибку:

$rubley = ($seychas * $procent) + $rubley;

Здесь справа использована переменная $seychas, но на момент выполнения команды такой переменной еще не существует. Строчка, которая ее создает, расположена ниже.

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

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

Вернемся к алгоритму. Как бы его записать, используя только перечисленные выше команды? Ну например, так:

------

пусть суммаНаСчету равна 10000;
пусть процент равен 1.1;

меняем возраст вкладчика от 16 до 108 лет с шагом 1 год, выполняя каждый год {

увеличить суммуНаСчету на процент;

если (на счету миллион или больше) {
выйти из цикла;
}

увеличить возраст вкладчика;
}

вывести ответ к задаче;

------

Ну а дальше надо переписать это с помощью команд выше.

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

пока (на счету меньше миллиона) {
увеличить сумму на счету;
увеличить возраст на 1;
}

Но как эту конструкцию "пока" перевести в код? Тут есть такой вариант:

for (; $sum < 1000000 ;) {
...
}

(если ты забыл,что это значит, перечитай урок про циклы внимательно). Мы не пишем в шапке цикла начальное действие и действие, которое выполняется после каждого шага, а оставили только условие продолжения. Но для таких случаев есть более короткая запись - цикл while:

while ($sum < 1000000) {
тело цикла выполняется до тех пор, пока условие вверху выполняется;
}

Подробнее: http://php.net/manual/ru/control-structures.while.php

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

Если что-то непонятно, задавай вопросы.
194 1138932
>>38166

Пока еще не все, надо, чтобы выводился тот ответ, который требуется в задаче. А у тебя только какие-то отладочные данные, и непонятно, где окончательный ответ.
195 1138941
Анон, проблема с JS помоги.я немного туп
window.onload = function() {
btn.onclick = function() {
var test = document.getElementById('test'),
btn = document.getElementById('btn'),
my_img = document.createElement('img');
my_img.src = 'picture134.jpg';
test.appendChild(my_img);

что мне тут пофиксиить, чтобы появлялась только одна картинка и чтобы была пауза 5 секунд перед появлением.
196 1138959
>>38593

>бед практис


чому же? всё, что работает = вери гуд практис
197 1139003
>>38941
добавь функцию setTimeOut. Получится так
btn.onClick = setTimeOut(function(){...}, 5000);
198 1139125
>>39003
Понял, спасибо, но не понял куда ее добавить
199 1139153
>>39125
Алсо добавь проверку, что картинка уже прикреплялась.

>Понял, спасибо, но не понял


Так ты понял или нет?
original.png25 Кб, 300x300
200 1139156
>>39153
Нет
201 1139178
Нужно ли использовать функцию addslashes? Для работы с базой данных используются ведь специальные функции типо real_escape_string или плейсхолдеры. Могут ли неэкранированные строки нанести какой-то вред в самом php-скрипте или экранирование нужно исключительно для работы с бд?
202 1139181
>>38959
Не троллируй тутъ
203 1139203
Прочитал шапку, не нашёл рекомендованного списка литературы. Мне нужен учебник по пхп, по которому я могу ВЫЗУБРИТЬ основные моменты (список функций для массивов и строк, арифметические действия, типы переменных и прочая справочная информация). Нужно для собеседований.
204 1139233
>>38931

>Тебе нужен preg_replace_callback либо preg_replace с массивом слов и замен


благодарю
205 1139239
>>39203
по пхп нет хороших книг. их просто нет, прими это. зубри по мануалу. все твои вопросы (типы, функции для работы с массивами) там описаны.

алсо, на собеседованиях задают очень заковыристые вопросы, которые лучше искать в гугле по запросу "вопросы с собеседований".
206 1139286
Внезапно возник такой вопрос, можно ли в регулярку запихать переменную? К примеру если мне надо в тексте перебрать каждую букву по отдельности, то надо тупо копировать код овердахуя раз?
207 1139339
>>39286
Короткий ответ, можно.
Опиши задачу.
208 1139361
>>39239
Мне уже второй интервьюер (или как там их называют) втирает про то, что мне НАСТОЯТЕЛЬНО надо прочитать какую-нибудь книжку, потому что там "подробно разбирают сложные моменты" и "дают базу".

>"вопросы с собеседований".


Уже. Но там короткие ответы, а мне кроме них нужно потихоньку подтягивать "базу", чтобы отвечать более осмысленно.
209 1139373
>>39361
На каких вопросах ты сыпался?
210 1139417
Как выпилить праздничную тему, о веб девы?
211 1139419
Анон, помоги составить регулярку!

Поле должно обрабатывать возраст спиногрызов.
Есть пример:

12
7 лет
1 год
4года
2,5
3 месяца
4 месяца
1.6
8 месяцев
1,5 года
1,7 года на время вылета
1год и 6месяцев
инфант
до 2х лет
6-7

Нужно как-то обрабатывать по формату число и его значение. Типа "9 лет", "8 месяцев" или "2 годика".

Я запилил свою:
'/[0-9месяцев\s]|[0-9года\s]|[0-9лет\s]*|[0-9]{1,2}/ui'
Но она почему-то пидорасит значения.
212 1139424
>>39417
Выпадающее меню в самом верху справа
213 1139431
>>39339
надо посчитать каждую букву в тексте по отдельности, типа сколько а, б, в и тд,
215 1139437
>>39424
Спааааасибо, мил человек!
216 1139452
>>39373
На простейших. Не помню html тег для нумерованного списка. Не помню название функций "переворачивания" массива и строки. Знаю, что они есть, но на память не помню. В общем, нужно именно зазубривание. Так-то уже начал с общей справочной информации, но в книгах ведь и правда более структурированный подход обычно.
217 1139529
>>39452
Это нет смысла зубрить, это тупо.
Важно именно знать возможность наличия того или иного функционала в языке.
Обычно это приходит с практикой.
Я вот вообще плохо помню точные имена функций или тегов, всегда гуглю что бы перепроверить и всегда гуглю перед тем, как пилить какой либо свой велосипед.

По моему все книги это просто переписывание документации, ещё и пропущенной через автора, который сам мог многого не знать.

Можешь попробовать https://www.codewars.com,
это сборник задач, есть много базовых и 'классических',
как раз в том же PHP многие решает одна функция или так может показаться,
можно нарешать кучу задач и подтянуть эту базу.

>>39431
Копай в сторону preg_match_all

>>39419
Покажи код
218 1139539
>>39529

>Это нет смысла зубрить, это тупо.


Согласен.

>Важно именно знать возможность наличия того или иного функционала в языке.


>Обычно это приходит с практикой.


Без пройденного собеседования нет практики. Я пилю свои проекты, но этого мало. Сегодня что-то использовал, а завтра уже забыл. Во всяком случае я забываю. Память плохая.
219 1139629
>>39178

>в самом php-скрипте


Имеешь в виду, можно ли так исковеркать вводимые данные, чтобы выйти из строки и поменять логику скрипта? Нет.
Строка - это переменная, которая содержит последовательность байтов. И поебать вообще, что ты там напишешь. Проблемы начинаются, когда одна строка соединяется с другой. Для генерации SQL-запроса, например.
220 1139630
>>39178

>в самом php-скрипте


Имеешь в виду, можно ли так исковеркать вводимые данные, чтобы выйти из строки и поменять логику скрипта? Нет.
Строка - это переменная, которая содержит последовательность байтов. И поебать вообще, что ты там напишешь. Проблемы начинаются, когда одна строка соединяется с другой. Для генерации SQL-запроса, например.
221 1139631
Как так получилось, что жмякнув на энтер один раз, я отправил два сообщения, при этом "моим" подсвечивается только одно из них?
222 1139633
>>39539
Што за долбоебизм? Невозможно помнить всё, да и не получится. Всё равно использовать 100% возможностей того или иного инструмента ты постоянно не будешь, что-то ты будешь помнить лучше, что-то хуже.
Знать, безусловно, нужно. Но знать нужно не названия функций, а возможности, которыми располагает тот или иной инструмент.
Я тоже не помню названий некоторых функций, но если мне понадобится, я за 15 секунд их найду, т.к. знаю что мне нужно.

Хороший интервьюрер будет проверять именно твое мышление, т.к. способность находить выход из трудных ситуаций, способность решать нестандартные задачи и пр. А не дрочить названия функций и тегов.
223 1139725
>>39633
Они мне перезвонят.

По итогу у меня оффер на 40к. В ДС. Когда собеседовался на что-то повыше, каждый раз не проходил.
224 1139735
есть какие-то сертификаты в пхп, которые стоит получать?
225 1139788
>>39735
Zend сертификаты котируются

>>39725
А ты анон, можешь еще полистать книгу подготовки к Zend сертификации, там как раз много вопросов по документации
226 1140070
>>39529

>Покажи код


Зачем?
Сам код здесь https://ideone.com/zQztaf , но я просто не видел смысла выкладывать его.

Но сразу кое-что скажу: это часть кода на 200 строк.
Я тогда его здесь выложу https://ideone.com/Lz5R9P .

Если не считать отсутствие PDO (мамой клянусь, на этой неделе исправлю это!), могут быть какие-то рекомендации по коду?
ind4:не пиши его больше
Capture.JPG37 Кб, 436x536
227 1140073
>>40070
Доложил.

По факту: так некрасиво, что даже не хочется разбирать.
228 1140074
>>40073
Ват? Это ж комменты, чтобы сам код был понятен! Что с ними не так-то?
229 1140076
>>39419

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

Так ты будешь всегда знать, насколько хорошо работает код, где он делает ошибки, улучшилось ли что-то после изменений.
230 1140078
>>39529
https://ideone.com/P6YQPN
Я молодец или можно было сделать лучше?
231 1140110
Сап, как делать бэкап БД, при возможной потере самой бд? Скажем есть совсем совсем плохой сценарий при котором я потеряю доступ к бд и вообще серверу. Как в таком случае делать бэкапы? Засылать дамп изменений на почту в конце каждого рабочего дня? Или на FTP? Или как-то так?
232 1140120
Пехач, как надо ставить на пеху библиотеки? Я хотел накатить imagick и phpv8, но у меня windows вместо серверной ос.
233 1140121
>>40120
скачать библиотеку в файле dll, положить в директорию c:\path\to\php\ext и прописать её в файле php.ini:
extension=php_yourlibrary.dll

Важный нюанс, что php.ini может находиться где угодно. Нужно найти все и прописать в каждый.
234 1140153
>>40121

Узнать, где находится php.ini, можно вставив в скрипт phpinfo() и открыв его через браузер и веб-сервер.

Обратите внимание, что при запуске из командной строки может использоваться один php.ini, а из-под Апача - другой.
235 1140167
Кто шарит в Симфони, подскажите, как по уму сделать.

Допустим, у меня есть сайт с новостями, там на главной странице слева новости, а справа теги, допустим.

Я на ShowIndex() на ретурн подаю что-то типа
return this->render('index.html.twig', ['news' => $someNews, 'tags' => $popularTags]);

Далее у меня есть еще ShowArticle(), где в основной части страницы уже другая инфа - одна новость с комментами, а справа те же теги.

В итоге можно сделать так:
return this->render('article.html.twig', ['article' => $someArticle, 'tags' => $popularTags]);

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

Как принято избавляться от такого дублирования? Ведь на каждой странице может дублироваться инфа типа свойств аккаунта, всяких виджетов и еще кучи говна

Я пока придумал только что-то типа return this->render('article.html.twig', ['article' => $someArticle, 'tags' => $this->getPopularTags()]);

и наследовать контроллер от своего базового (который наследуется от симфоневского AbstractController) в котором в защищенные методы вынести эти обращения к доктрине. Есть еще варианты?
236 1140176
>>39361
возможно интервьюер говорит тебе о книжках по программированию независимо от языка, а не про книжки на пхп.

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

нормальных книг по пхп нет, забудь про них. тебе никто не разжует и не вложит в голову инфу как стать программистом с нуля. только всякие высеры котеровых с кодом типа
if($peremennaya = '2') echo '<b>'.$_GET['ADMIN'].' вы админ!</b>';

но есть пиздатый мануал по языку, читай его.

вот хорошие книги: https://github.com/jupeter/clean-code-php
http://www.phptherightway.com/

но они не "дают базу". "базу" ты соберешь по кусочкам потом, через год изучения. также есть много хороших книг по джаве, по ооп.
237 1140179
Так что? Нобади керс мой пост >>40070 ?
238 1140202
>>40073
Просто, если ты про отступы - то там они на месте, кроме как на 82-ой строке.
Там же нет вложенных циклов/условий и прочего.
239 1140224
>>40167

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

Почитай где нибудь про Fat Ugly Conttollers.
240 1140236
>>40224
братюнь, я читал. в контроллере получаю теги - это занчит обращаюсь к репозиторию, который занимается получением. тонкий контроллер как раз это и делает - обращается к модели за данными и отдает их представлению.

у меня контроллер из 5 строк состоит и тем не менее, там есть это дублирование.
241 1140238
>>40176
Спсибо за ссылки.

Практика у меня уже была. Полтора года (даже год и 9 месяцев). А вот теорию знаю (вернее помню) слабо.
242 1140243
>>40167

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

- базовый контроллер, который выставляет глобальные переменные для твига (глобальные переменные конечно не очень хорошо): http://symfony.com/doc/current/templating/global_variables.html
- то же самое, но вызывающееся не через базовый контроллер, а через события kernel вроде before request или before controller. То есть перед вызовом контроллера вызывается твой код и что-то передает в твиг (опять же, глобальные переменные)
- специальный "хелпер", который передается в шаблон и из которого в нем берутся нужные данные (вроде {% set tags = pageHelper.getPopularTags() %})
- сделать функции получения данных как расширение к твигу и писать там {% set tags = getPopularTags() %}. Минус - эти функции скорее всего ничего не "знают" о запросе, непонятно как передавать в них какие-то параметры.
- заменить объект твига на расширенный, который дополняет переменные нужными данными
243 1140246
>>40238
под практикой я имею в виду работу в нормальной конторе с аудитами, отгрузками и прочим. без битриксов с версткой и прокладываний витой пары.

ты под теорией что понимаешь?
244 1140249
>>40167

Вот еще такой подход предлагают https://symfony.com/doc/current/templating/embedding_controllers.html
245 1140267
>>40243
>>40249
благодарю. правда смущает, что некоторые из вариантов нарушают принципы взаимодействия компонентов mvc.
246 1140374
>>35053 (OP)
ОП, не знаю, говорили тебе тутошние антоны или нет, но большое тебе спасибо за всю информацию в этом тредике. Очень грамотно и развернуто
247 1140414
>>40202
Ну зацени мой код четырехлетней давности
https://ideone.com/IiGQvQ

До сих пор работает как часики.

Одна проблема, понимаю в нем хоть что-то только я.
248 1140447
Пилю свой бложик, хочу что бы категории в шапку сайта выводило прям из бд.
код:
https://pastebin.com/0zsCzrkQ
Вся страница завалена первым значением из массива.

> $menu_array = mysqli_fetch_assoc($menu_query)


Если переместить эту конструкцию в цикл то все работает. Не могу догнать, разве не одно и тоже записать в цикле $menu_array = mysqli_fetch_assoc($menu_query) и $menu_array ?
249 1140496
>>40153

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



Именно поэтому

>Нужно найти все и прописать в каждый.


>>40121
250 1140499
>>39419
>>40070
Я так и не понял что должно получиться на выходе, сори я сонный.

>>40447
Ты используешь неверный цикл, почитай, как работает while
251 1140527
>>40499
Намекаешь на for ?
252 1140577
Как такое может быть?

Я комментирую строчку $date->modify("+{$matches[1]} day"), которая находиться в ложном условии, которая не должна выполниться, и к датам не добавляется астрономическое значение.

Вот копипаста этого кода: https://3v4l.org/uEeGP
25.png6 Кб, 281x320
253 1140636
Нубо-вопрос: на пикрелейтед "делаю что-то 2" всегда ли гарантированно выполнится только после полной отработки функции check() ? Или нужно обернуть "делаю что-то 2" в if?

Посоветуйте, как вообще делать такой алгоритм, где в одной функции вызывается много проверок
254 1140686
>>40636
"2" не выполнится только если в ф-ции check будет выброшено исключение throw new Exeption() или где-нибудь там встретится ф-ция exit, die. Еще мог бы быть вариант, если ф-ция check() асинхронная, но в php такого нет, там все выполняется последовательно, даже запросы к удаленным серверам.
255 1140699
>>40577
Починилось после того как каждой новой итерации создавалась новая дата. Но почему при первой, всё равно, выполнялось ложное условие, и добавлялось астрономическое число?
256 1140790
>>40636
Да, анон. Когда вызывается функция, управление передается именно ей, а также в стек добавляется адрес возврата, там же существует локальная область памяти для данной функции. Функция выполняется, сохраняет данные в определенном месте, а затем управление передается вызывающей функции, которая получает адрес в памяти данных, которые вернула функция.

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

Об этом же вопрос был?
c6cc2eef13.jpg58 Кб, 515x445
257 1140793
>>40636

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



Я всегда делаю в таком йоба-стиле. Если нужно сделать множество проверок внутри какой-то функции, вместо кучи вложенностей, отбрасываю неудачные варианты. Хз красивое это решение или нет.
258 1140831
if (isset(
$foo,
$bar,
$baz
)
) {
...
}

Это приемлемая конструкция?
259 1140848
>>40793

Лучше писать

$result= check();
if (!$result) {
...
}

Во-первых, не стоит совмещать 2 действия в 1 строке. Во-вторых, ты нарушаешь правило приоритетов операторов - !$result = ... эквивалентно (!$result) = ... и некорректно. Это просто в PHP стоят костыли, которые такое разрешают.
260 1140849
>>40831

Это странная конструкция. Зачем проверять, существует ли переменная? Ты сам не видишь по коду выше, создавал ты ее или нет?
261 1140902
>>40848
Спасибо, буду знать
262 1141013
Помогач, помоги!
Нужно подгрузить скрипт в зависимости от выбранной страницы. Скрипт для страницы/2/ отказывается работать. Как я понял — загвоздка скорее в wordpress, а не в пхп.

https://developer.wordpress.org/reference/functions/is_page/ — тут описывается подобный случай, но пхп я совсем не знаю. Если не сложно, помогите с кодом:

add_action('wp_enqueue_scripts', 'qg_enqueue');
function qg_enqueue() {
if (is_page( 'new-page-testing/2/' )) {
wp_enqueue_script(
'qgjs',
plugin_dir_url(__FILE__).'cae2.js'
);
} elseif (is_page( 'new-page-testing' )) {
wp_enqueue_script(
'qgjs',
plugin_dir_url(__FILE__).'cae1.js'
);
}
}
263 1141083
давайте расскажу свою success стори.

32 года, полтора года назад решил перекатиться из своей предыдущей профессии в ойти. начал учить пхп, прошел курсы, сделал несколько учебных проектов, через какое-то время пошел на свою первую работу в одну крупную контору. прокачки было дохуя, но там платили как бомжу (меньше 40к, контора в дс). отработал чуть меньше года и ушел. решил, что нужно учить фреймворк и работать конкретно по нему. начал учить симфони, там как раз подоспела четверка. параллельно фрилансил, учил базы данных, всякие редисы и прочее говно, коммитил в опенсорс. недавно решил потестить свои знания, по приколу нашел мидловские вакансии по удаленке, связанные с симфони, чтобы взять там тестовые задания. выполнил первое, потом мне сказали мол "давайте созвонимся попиздим с эйчаром и техническим директором", попиздели мне прислали оффер на удаленку 100к мидлом плюс пиздатый стек. пригодился и мой предыдущий опыт (задавали вопросы из серии "что вы будете делать, если", а я как раз решал эти вопросы на прошлой работе), и в меру наполненный активностью гитхаб.

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

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

алсо, могу сказать, что на работе по предыдущей специальности я получал больше, чем 100к, но в любом случае 100к больше, чем 40, лол.
264 1141133
>>41083
ну да, "успех" уровня вкатывальщика, большего ты и не заслуживаешь
265 1141136
>>40848

>в PHP стоят костыли, которые такое разрешают


Тем PHP и хорош. И одновременно плох.
266 1141167
>>41133
конечно пока не заслуживаю. этапы карьеры не перескочить, очевидно, что сразу синьором не стать и я радуюсь каждому небольшому достижению. к чему призываю всех анонов.

если ты ждешь 500к в месяц, чтобы начать радоваться, мне тебя жаль. хотя я сомневаюсь, что у тебя в принципе есть реальный опыт работы.
267 1141173
>>41083

Я вообще не понимаю тех кто переживает что им уже аж целых 30 лет. Вы в 30 лет на пенсию что ли выходите, или у вас руки в 30 лет отваливаются? Люди на заводе и в 30, и в 40, и в 50 бодро работают. Вот исполнится вам 50-60, тогда и можете жаловаться
268 1141189
>>41173
ну многие паникуют, кто более трусливый. кто посмелее, хуй кладет я где-то посередине
269 1141223
>>40848
да, "одна строка - одно действие". правда часто даже в современном "правильном" коде это правило не выполняется, например

return $this->someMethod();

$someVar = array_map($callback, array_values($result));

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

но в примере >>40793 в одной строке даже не 2, а 4 действия и все абсолютно разноплановые. налицо желание анона изобрести свой велосипед и всех наебать вместо того, чтобы открыть какой-то реальный код (из того же symfony) и посмотреть, как там сделано. тот же код можно посмотреть для ознакомления с такой штукой как PSR-1/PSR-2
270 1141330
https://ideone.com/hEJMlZ
Застрял на задании в строках с массивами и стихотворением.
Проблема следующая: я изначально делал задание не через array_rand (так же, как и предыдущие), потому что не понял как это в принципе работает. Мануал читал, в английский могу, но я не въехал, как сделать так, чтобы он выбирал случайное число и при этом выводил из массива его значение. В мануале же описано по сути перемешивание значений и вывод случайного через соотв. команду (echo $input[$rand_keys[1]]), или я что-то не так понимаю?
Короче, решал через mt_rand, нашел решение в гугле. Но если с предыдущими заданиями это прокатило, то тут первая и вторая строки (где значения из 1, 2 и 3 массива) получаются абсолютно идентичными. Подскажите плз, можно ли это решить таким путем, чтобы строки были разными или поясните за array_rand, или я вообще все не так делаю, и там нужно использовать что-то другое?
271 1141341
Пару раз в коде видел синтаксис такого вида:
getHuita()['huita']. Что он обозначает?
272 1141344
>>41341
Я думаю эта функция возвращает элемент массива с ключом ['huita']
phpunit 273 1141356
Привет, есть вопрос про тестирование.

Я написал несколько классов-мапперов для сохранения и получения объектов из базы данных, а также мапперы для трансформации этих объектов в JSON объекты. Поскольку их нужно тестировать, я подумал что это хороший случай, чтобы разобраться с phpunit. И как всегда у меня есть несколько вопросов:
1. Что курить кроме Зандстры и доков phpunit?
2. С чего начать?
3. Как организовать тестирование мапперов для ДБ и JSON, чтобы в дальнейшем при добавлении новых связок "сущность-мапперДБ-мапперJSON" создание тестов не требовало много усилий?
274 1141364
>>41356

>1. Что курить кроме Зандстры и доков phpunit?


Хабр

>2. С чего начать?


С написания тестов, очевидно же!
Для преобразования в JSON функции протестируй. Это не маппер как ты называешь, а сериализатор (php объект -> json обьект).
>>41356

>3. Как организовать тестирование мапперов для ДБ и JSON, чтобы в дальнейшем при добавлении новых связок "сущность-мапперДБ-мапперJSON" создание тестов не требовало много усилий?



Не нужно писать тесты на каждый свой пердёж. Тестируй только то что будешь переиспользовать. Добавление НОВЫХ сущностей вообще ничего не должно менять, это ведь тоже самое что и другие сущности, просто в них информация другая. А вот если ты добавил функционал в базовый класс, то этот функционал уже можно (по идее нужно) тестировать, чтобы эта йоба не ломалась при добавлении новой йобы.

Писать тесты заебывать пиздец, нудное и не интересное занятие.
Ещеесли напишешь кучу ебланских тестов, то их тоже придется ПРАВИТЬ, лол.
275 1141402
>>41356

Для начала, а ты смотрел мою статью по тестированию? https://gist.github.com/codedokode/a455bde7d0748c0a351a

Дальше, ты должен решить, что и как ты будешь тестировать. Для этого мы берем каждый класс (или группу классов, работающих вместе) и определяем требования к ним. Что они должны уметь делать? Каждое требование будет проверяться тестом. Затем придумываем, как это требование проверить (тут может потребоваться смекалка) и пишем код тестов.

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

Но обычно сценарии тестов строятся по схеме "Дано - Если - То". Ну например, "ЕСТЬ пустая база данных, ЕСЛИ вызвать метод подсчета числа записей в ней, ТО он вернет ноль".

Сценарии бывают позитивные и негативные, позитивные проверяют, что при правильных входных данных функция работает, а негативные проверяют ее поведение при неправильных входных данных.

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

Рассмотрим пример составления сценария тестирования.

Например, у тебя есть класс для сохранения и получения объектов из БД. Какие к нему есть требования? Ну очевидно, первое что в голову приходит:

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

дальше там могут быть дополнительные требования вроде "маппер должен присваивать id создаваемым объектам", "маппер должен уметь считать число объектов в БД", это ты должен наверно знать, из описания не ясно.

Как проверить требования выше? Тут могут быть разные идеи. Например:

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

А можно чуть схитрить и проверить обе функции сразу:

- сделать пустую БД
- вызвать функцию вставки сущности в БД
- вызвать функцию загрузки сущности из БД
- проверить, что данные вернулись корректные

Как-то так.

Помни еще, что тесты должны быть независимы и не полагаться на очередность вызова, или на то, что другой тест вообще будет вызван.
275 1141402
>>41356

Для начала, а ты смотрел мою статью по тестированию? https://gist.github.com/codedokode/a455bde7d0748c0a351a

Дальше, ты должен решить, что и как ты будешь тестировать. Для этого мы берем каждый класс (или группу классов, работающих вместе) и определяем требования к ним. Что они должны уметь делать? Каждое требование будет проверяться тестом. Затем придумываем, как это требование проверить (тут может потребоваться смекалка) и пишем код тестов.

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

Но обычно сценарии тестов строятся по схеме "Дано - Если - То". Ну например, "ЕСТЬ пустая база данных, ЕСЛИ вызвать метод подсчета числа записей в ней, ТО он вернет ноль".

Сценарии бывают позитивные и негативные, позитивные проверяют, что при правильных входных данных функция работает, а негативные проверяют ее поведение при неправильных входных данных.

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

Рассмотрим пример составления сценария тестирования.

Например, у тебя есть класс для сохранения и получения объектов из БД. Какие к нему есть требования? Ну очевидно, первое что в голову приходит:

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

дальше там могут быть дополнительные требования вроде "маппер должен присваивать id создаваемым объектам", "маппер должен уметь считать число объектов в БД", это ты должен наверно знать, из описания не ясно.

Как проверить требования выше? Тут могут быть разные идеи. Например:

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

А можно чуть схитрить и проверить обе функции сразу:

- сделать пустую БД
- вызвать функцию вставки сущности в БД
- вызвать функцию загрузки сущности из БД
- проверить, что данные вернулись корректные

Как-то так.

Помни еще, что тесты должны быть независимы и не полагаться на очередность вызова, или на то, что другой тест вообще будет вызван.
Безымянный.png53 Кб, 1068x626
276 1141450
Привет, возник вопрос о том, как лучше будет выбрать 3 последних ответа каждого треда? Решил, что можно сделать как на пике(union'ы склею потом).
Может, есть какое-нибудь более лучшее решение? Буду благодарен.
277 1141452
>>41364
Маппер - тоже подходящее название, не придирайся. Есть даже функция Map в функциональном программировании и она как раз обозначает отображение одного списка на другой: https://en.wikipedia.org/wiki/Map_(higher-order_function)

> Писать тесты заебывать пиздец, нудное и не интересное занятие.


Проверять руками ещё нуднее, особенно с ростом приложения. Верно, что править тесты нужно, если они слишком много знают о внутренностях тестируемого кода, тогда при изменении внутренностей нужно будет править тесты. Ещё хорошо юнит-тестируется только код с нормальными разделением ответственности, то есть появляется хоть какая-то объективная метрика хорошего кода - сложно написать тест, значит код скорее всего запутанный.

>>41364
На хабре старьё, читай доки PHPUnit и смотри как пишут тесты другие люди на гитхабе:
- https://github.com/slimphp/Slim/tree/3.x/tests
- https://github.com/silexphp/Pimple/tree/master/src/Pimple/Tests
- https://github.com/j0k3r/banditore/tree/master/tests/AppBundle
278 1141455
>>41364
>>41402
спасибо
279 1141469
>>41452
Что делать с ситуациями, когда тебе нужен чужой код, а у него нет тестов?
280 1141487
>>41450

У тебя не написано, как выглядит схема БД. Альтернатива - сделать денормализацию и явно хранить связь между тредом и последними 3 постами.
281 1141488
>>41469

Можно понадеяться, что он проверен, и ничего не делать.

Можно написать небольшие приемочные тесты, тестирующие его в целом.

Если это опен сурс, можно предложить разработчикам помощь в добавлении и написании тестов.
Безымянный2.png38 Кб, 886x270
282 1141492
>>41487
Схема.
283 1141528
Подскажите, что можно почитать по алгоритмам и структурам данных для гуманитария. Я накачал седжвика и всяких книжек типа алгоритмы на джава скрипте. Код, который там опубликован, и его логику я понимаю, но теорию не очень. Может есть совсем что то простое?
284 1141531
>>41528
Введение в Алгоритмы Кормена
15182647902600.jpg51 Кб, 750x728
285 1141532
Кстати о тестах, есть какой-нибудь минимальный путь/метод их написания?

Все движки тестов, которые я видел, слишком занудные (слишком подробный синтаксис, слишком много времени уходит).
286 1141533
>>41531
Вернее, называется "Алгоритмы. Вводный курс". Но я хз что там, ибо читал "Алгоритмы. Построение и анализ".
287 1141534
>>41532
Олсо, как лучше тестировать void-функции?
288 1141539
>>41532
Selenium?
289 1141595
3 неделю назад я попробовал вкатиться в это ваше погроммирование, ибо сижу на шее у мамки вот уже 28 лвл. Полная залупа оказалось! Буду дальше смотреть аниме и пить пиво и кушать пончики, которые мне принесла бабка. Удачи, ботаны!
290 1141597
>>41595
Тонко шутишь, фраерок
291 1141710
>>41167
ха-ха, сладкие оправдания

а о себе рассказывать не буду, не заслужил, вкатывальщик
292 1141711
>>41539
ну как вариант, но тоже достаточно занудно
293 1141716
>>41083
Поздравляю!
294 1141811
Какого черта в каждой статье про Ларалев тонны кода с вызовами статичных методов? Что за склонение к нетестируемому говнокоду?
295 1141834
Хосспаде!
Оно не работает! Оно не живо! Оно мертво!
https://ideone.com/9P02fe
Оно даже ошибок не выдаёт! Оно пусто! Что я не так сделал?
Очевидно же, что проблема в spellSmallNumber. Но где?
Я кусочек этой функции запускал отдельно, оно работало. Господи, горе мне!

А ещё PDO истязает мою и без того измученную душу.
Как в PDO заменить mysql_real_escape_string так, чтобы оно работало? Нужно при неверном наборе символов перенаправлять на другую страницу с помощью header. Без строки PDO:Quote, которую я пытался использовать, всё работает, но как только я её вставляю, оно не перестаёт переходить, а лишь перезагружает текущую страницу без вывода чего-либо. Отправившись на покорение просторов интернета, я попытался использовать и с try и с prepare, но это было неверным действием. Вот так. Я не понимаю, где моя ошибка?

На первых трёх пиках мои скверные письмена, на последнем, четвёртом, рабочий вариант, но с mysql.
296 1141835
>>41834

>оно не перестаёт переходить


оно не переходит
фикс
297 1141846
>>41834
А говорили, что нельзя вернуться в 2007. Откуда ты это принес, фриланс?
298 1141859
>>41452

>Есть даже функция Map в функциональном программировании и она как раз обозначает отображение одного списка на другой



Педагог и педофил - тоже одно и тоже?
Сравнить функцию высшего порядка с ООП термином это сильно блять.
299 1141872
>>40414
Хорошо. Добавлю комменты и выложу.
300 1141873
>>40499
Я уже решил задачу, лол.
Но продемонстрировать код все ещё хочу.
301 1141962
>>35053 (OP)
Аноноимусы, что можете сказать о книге "php быстрый старт" ? стоит ее прочесть, чтобы быстро освоить основы языка и приступать к практике, которая есть в шапке? парочку яп я знаю, но вебом не занимался никогда
Кстати, что можете сказать про "php в подлиннике" ? Везде ее нахваливают, но объем ее меня очень отталкивает, так как печальный опыт чтения книг по яп на 1000+ страниц есть
302 1141963
>>41962
В шапке и так все с "это называется переменная, а вот это - строка".
Никаких предварительных ласок не нужно.
303 1141976
>>41963
Да, учебник из шапки я просматривал, поэтому и спрашиваю о альтернативах, в виде настоящих книг, хотелось бы поближе познакомится с ооп в пхп, связку с sql и так далее.
304 1141981
>>41976
Чувак, я тебя не понимаю.
Если тебе просто не нравится оформление ОП-а, то можешь взять http://php720.com/ , например.

В общем, учебник ОП-а самодостаточен для первого этапа. "Настоящие" книги мне не нравятся из-за долгого вступления и всяких расшаркиваний, которые НАХУЙ не нужны нубасу, который впервые учится кодить на чем-то кроме ХТМЛ.
305 1141983
>>41962
Тебе нужна книга ОПа и справочник Скляра и Трахтенберга. Больше почти нет годных книг, смирись@покайся.
306 1141999
>>41846
А в чём проблема?
307 1142020
Где посмотреть php-код двача?
308 1142023
>>42020
На серваке у Абу. Это бэкенд и простой юзер не имеет к нему доступ.
309 1142192
>>41962
книги про пхп учат говнокоду. потрать несколько месяцев на изучение, чтобы потом прийти на собеседование и понять, что надо переучиваться.
310 1142199
>>41710

>а о себе рассказывать не буду


тебя и не просили
311 1142203
>>41811
такой вот ларавел. зато быстро!
312 1142208
>>41083
Лол, а я переживал, что хуево вкатываюсь, ибо вкатился в саппорт по PHP в 27, а сейчас макакой подрабатываю за 40 (ДС2).
313 1142298
>>41999
я другой анон, но

1. процедурный код
2. mysql_query
3. пхп и html в одном файле, закрывающие теги ?>
4. глобальные переменные

ну и просто неуловимое ощущение, что попал во времена пхп4
314 1142302
>>42298
А еще отсутствие какой-либо нормальной архитектуры.
315 1142306
>>41716
спасибо!

>>42208
главное сразу учить то, что потребуется потом на нормальных работах - ооп, тестирование, фреймворки, бд, линукс и пр. чтобы через два года не оказаться с навыками, подходящими только для дизайн-студии какой-нибудь. все, что у ОПа есть в пасте, грубо говоря, надо выучить (кроме фронта и верстки, лол)
316 1142313
>>42298

> пхп и html в одном файле, закрывающие теги ?>


И что в этом такого?
317 1142393
>>42313
то, что читай PSR. конкретно смешение логики и представления нарушает современные стандарты: https://www.php-fig.org/psr/psr-1/#23-side-effects
318 1142397
>>42313
с другой стороны ты не объявляешь функции, классы или константы в этом файле, так что формально ИМЕННО ЭТО не является нарушением именно этого пункта пср. но смешивать логику с представлением - плохая практика.
Безымянный.jpg82 Кб, 593x722
319 1142399
>>42393
Покажешь, как согласно современным стандартам должен выглядеть этот код ?
320 1142404
>>42399
я тебе так скажу, по этим самым стандартам нужно использовать например твиг с набором дополнительных расширений к нему (которые ты напишешь сам), которые будут заниматься всякой логикой типа получения путей для картинок и т.д. в твиге (или другом шаблонизаторе) можно легко выводить списки, таблички по три ячейки в столбце и т.д.

а в этом коде прям чувствуется, что подпихивали-подпихивали костылей по одному и в итоге все достаточно запутано.
321 1142417
Вопрос по слиму и прочим фреймворкам. Почему, чтобы отобразить шаблон используют return, а не echo?
разметка.png17 Кб, 968x236
322 1142420
Привет, бартики. Помогите разобраться с тем, как написать свой язык разметки по типу Wakaba mark. Буду очень благодарен.
323 1142437
>>42420
Ну а может все-таки https://secure.php.net/manual/en/book.bbcode.php ?
324 1142440
>>35053 (OP)
В node.js можно прослушивать определенный порт и обрабатывать поступающие на него запросы. Как такое делается в php?
325 1142442
>>41834
.php
.PHP
На юникс-сервере это будут разные файлы. лучше используй lowercase всегда.
326 1142445
>>42437
Я даун. Сори за тупой вопрос. Очень благодарен, братишка.
327 1142461
>>42440
Apache сам это делает. Он же балансирует нагрузку и прибивает скрипты, когда они зациклились или отожрали слишком много памяти.
328 1142467
Как реализованы в магазинах разнообразные сортировки по цене/имени/характеристикам/производителю и т.п.?
Километровые if?
329 1142474
>>42461
Ну а если я захочу обрабатывать запросы php кодом без проксирующего сервера? Будут ли запросы в таком случае нормально обрабатываться?
330 1142479
>>42467
Найн. Я реализовал через таблицы с атрибутами товаров и атрибутами категорий.

Есть категория, у неё есть десяток атрибутов. Эти атрибуты могут быть у товаров.

Далее на странице мы выводим все атрибуты в форме (с чекбоксами) и там уже просто ищем те товары, которые им соответствуют.

Ну у меня немного сложнее, т.к. присутствуют атрибуты разных типов (единичный чекбокс, множественный чекбокс, диапазон и т.д.)
331 1142486
>>42442
Всё равно не перенаправляет.
332 1142490
Господа, нормально ли использовать underscores в названиях методов?

То есть писать как-то так
$obj->method_name();

Я знаю, что в стандарте (PSR-1) указано, что использовать нужно camelCase, но с нижними подчеркиваниями выглядит аккуратнее имхо.
333 1142492
>>42479
Ммм.
А можно на пальцах?
Допустим, создал я формочку, где есть чекбокс сортировки по цене или алфавиту.
Запросы в БД будут вида
order by name asc
order by name desc
или
order by price asc
order by price desc

Или ты предлагаешь сразу выгружать всю категорию? Но сортировать по условиям все равно придется - но уже массивы, в которые выгружена таблица.
334 1142503
>>42399

Могу предложить урок по шаблонам, как раз про это: https://github.com/codedokode/pasta/blob/master/php/templates.md
335 1142504
>>42474

Сокеты в PHP доступны, так что ты можешь открыть сокет и принимать коннекты. Но в 1 поток. Чтобы сделать асинхронность, как в node, нужны неблокирующие сокеты и библиотека вроде ReactPHP. Но скажу честно, что с ней не все работает асинхронно: тот же PDO синхронный и блокирующий.
336 1142505
>>42492
Сортировка - это одно. Я говорил именно про выборку товаров.

Хорошо. Попробую рассказать подробно.

Смотри, у тебя есть категория "Мобильные телефоны". В админке у тебя есть возможность добавить атрибуты, которые присущи мобильным телефонам. Ну, пускай, например, это будет цвет, операционная система и ёмкость батареи.

Хорошо, админ это всё добавил. В этот момент в таблице attributes появилось три записи. Каждое из них содержит, как минимум свой айдишник, айди категории и название значения.

Теперь у нас есть товары. У каждого товара должны быть эти атрибуты (но это необязательно). Какие именно значения должны быть?
Допустим у нашего мобильного телефона значения такие: черный, iOS, 3200.

После того, как админ всё это добавил, у нас в таблице values появились три записи. Каждая из них содержит в себе как минимум четыре значения: айдишник свой, айди атрибута, айди товара и имя.

Разумеется, между таблицами лучше сделать связи.

Теперь поиск.

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

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

Теперь мы чекбоксами отмечаем необходимые значения и клацаем "отфильтровать".

У меня сделано через ajax, но в простейшем случае это можно сделать обычной формой. В сгенерированном URLe (мы отправили форму методом GET) содержаться айдишники значений.

Теперь дело за малым - найти те товары, у которых есть подобные значения атрибутов. И всё. Как реализовать последний шаг - думай сам. Я делаю так:

1. Подсчитываем количество значений в запросе (то есть количество чекбоксов, которые юзер отметил).

2. Далее делаем выборку товаров по данным чекбоксам и отсеиваем те, количество которых не совпадает с количеством чекбоксов.

Но это мой способ, никто не говорит, что всё так и нужно делать. Я пришел к такому решению, оно меня устраивает - работает быстро и надежно.
336 1142505
>>42492
Сортировка - это одно. Я говорил именно про выборку товаров.

Хорошо. Попробую рассказать подробно.

Смотри, у тебя есть категория "Мобильные телефоны". В админке у тебя есть возможность добавить атрибуты, которые присущи мобильным телефонам. Ну, пускай, например, это будет цвет, операционная система и ёмкость батареи.

Хорошо, админ это всё добавил. В этот момент в таблице attributes появилось три записи. Каждое из них содержит, как минимум свой айдишник, айди категории и название значения.

Теперь у нас есть товары. У каждого товара должны быть эти атрибуты (но это необязательно). Какие именно значения должны быть?
Допустим у нашего мобильного телефона значения такие: черный, iOS, 3200.

После того, как админ всё это добавил, у нас в таблице values появились три записи. Каждая из них содержит в себе как минимум четыре значения: айдишник свой, айди атрибута, айди товара и имя.

Разумеется, между таблицами лучше сделать связи.

Теперь поиск.

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

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

Теперь мы чекбоксами отмечаем необходимые значения и клацаем "отфильтровать".

У меня сделано через ajax, но в простейшем случае это можно сделать обычной формой. В сгенерированном URLe (мы отправили форму методом GET) содержаться айдишники значений.

Теперь дело за малым - найти те товары, у которых есть подобные значения атрибутов. И всё. Как реализовать последний шаг - думай сам. Я делаю так:

1. Подсчитываем количество значений в запросе (то есть количество чекбоксов, которые юзер отметил).

2. Далее делаем выборку товаров по данным чекбоксам и отсеиваем те, количество которых не совпадает с количеством чекбоксов.

Но это мой способ, никто не говорит, что всё так и нужно делать. Я пришел к такому решению, оно меня устраивает - работает быстро и надежно.
337 1142519
>>42490
Нет, не стоит писать как тебе вздумается, лучше использовать единый стандарт, для питона руководствоваться PEP, для PHP - PSR2

В любой нормальной конторе тебя будут просить писать так, как принято в коммьюнити.
338 1142529
>>42519
Спасибо. Найс, мне опять переписывать весь проект. Какой же я тупой, пиздец.
339 1142547
>>42490
>>42529

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

И не спеши огорчаться. Это ведь возможность получить новые навыки - навыки рефакторинга. В некоторых IDE есть функции рефакторинга, в том числе переименование методов (в идеале, при этом переименовываются все упоминания этого метода). С поддержкой IDE это все делается намного быстрее. Я думаю, это точно есть в PhpStorm (платный) и вроде как есть в Netbeans (бесплатный).

Если вдруг IDE не поддерживает такое, освоишь поиск/замену в файлах.

Зачем переписывать? Отрефакторь.
1514603297169.gif78 Кб, 900x278
340 1142549
Ковыряюсь с загрузкой файлов.
В PHP есть такая странная фича - если добавить в форму поле <input type="hidden" name="PHP_MAX_SIZE" value="кол-во байт">, то пхп сам проверит, умещается ли файл в эту цифру, иначе ошибка загрузки, как я понимаю. Конечно, это ни разу не безопасно, ведь число передать можно любое.
Есть хоть какие-то профиты от этой дырявой фичи? Например, может, пхп не будет грузить целый гиг, а сразу после 10мб - если лимит таков - выдаст ошибку?
341 1142553
Сап давч. Пытаюсь сделать схему бд для хранения инфы о загруженных файлах. В идеале это всё использовать через доктрин орм просто чтобы потрогать. Создал я в общем сущность файл с полями название и вес файла. Унаследовал её сущностью картинка, которая имеет так же поля ширина и высота например. И тут я понял что я нихера не понимаю как это реализовать в mysql. По идее мне нужно две таблицы, таблица картинка будет иметь внешний ключ таблицы файл, но файл может быть и не картинкой, тогда поля картинки будут null или что? А если добавить еще таблицы типа аудио/видео, там же вообще дичь будет твориться. Мне эти связи в бд даются крайне трудно.
342 1142555
>>42529
Не нужно переписывать. Есть php-cs-fixer, который сам всё поправит, использовать через консольную команду php-cs-fixer fix path/to/project

Некоторые люди идут дальше - делают precommit hook - скрипт который срабатывает при попытке создать коммит - этот скрипт в автоматическом режиме фиксит кодстайл. Во многих библиотеках на гитхабе такое тоже используется, ещё там можно настроить бота (Style CI), который автоматически будет слать пулл-реквесты в репозиторий с кодстайл фиксами.

>>42549
Лучше просто на стороне PHP провалидировать файл и только после аплоадить. Пример как это можно делать в Symfony: https://symfony.com/doc/current/reference/constraints/File.html#options
Ты же можешь просто if'ом проверить.

>>42417
Загляни в исходники, это же микрофреймворк. Slim использует абстракцию для работы с HTTP: https://www.php-fig.org/psr/psr-7/

С объектами работать проще, чем с суперглобальными переменными, так как в коде становится видно зависимости, что облегчает юнит-тестирование и подмену таких зависимостей. И еcho ведь не всегда нужен, если я хочу просто отредиректить пользователя на другую страницу, то я выставлю HTTP заголовок 301 без тела HTTP ответа.
343 1142558
Как вкатиться в backend?
344 1142559
Сап пехепач, в последнее время испытываю сложности с проектированием архитектуры приложения. Простейшее мвс приложение могу построить с роутингом и мини орм, но код выглядит как то убого, не знаю как описать даже. Нету в нем завершенности, удобности. У меня небольшой опыт, хотелось бы понять как быть дальше. Читал банды четерех, может я тупой, но я вообще нихера не раскурил, куда мне себе все эти патерны вставлять. Тоесть я понимаю как работает синглтон, но когда его лучше использовать? Так же и с интерфейсами, фабриками. Я напилил кучу интерфейсов, сижу и путаюсь в них, мне кажется смысл был в другом же? Что бы все понятно было. Когда пишешь объектно, код становится каким то неуклюжим, трудно изменяемым, хотя пытаешься применять di, ioc, solid dry kiss. Но в итоге ты углубляешься в код ради кода, а не ради решения задачи. О великий гуру пхп треда, помоги как мне быть.
1346787830097.jpg34 Кб, 800x603
sage 345 1142591
>>42298
>>42393

> глобальные переменные


И че?

> php и html


И ЧЕ?

Блядь, вот я охуеваю. КТО СКАЗАЛ ЧТО ГЛОБАЛЬНЫЕ ПЛОХО? Кто-то пёрнул и ты тоже перди, мол, эта плохо, хотя всё на них и работает, блядь. Область видимости притащили, используй. Но кто-то со времён 2007го года тащит эту хуйню и оно идёт и едет.

Потом эти пидарасы, с шаблонизацией мозга. ЛОГИКА И ПРЕДСТАВЛЕНИЕ НЕ ДОЛЖНЫ СМЕШИВАТЬСЯ - на каждый чих твиги прикручивают, всякие тупорылые смарти и прочую хуйню. А шаблонизатор тоже предоставляет ЛОГИКУ и простые условия и прочую хуйню. Ну и нахуй мне логика в логике? Нахуй мне ещё пердолить какие-то тупорылые, блядь шаблонизаторы, когда в Yii всё работает адекватно и никто туда лезть не должен, сука. SaaS дохуя?

Из за таких пидарасов вкатываение становится проблемой. Припрутся, пёрнут, что всё плоха и всё. На пике кусочки кода, которым похуй на шаблонизацию. НЕТ, БЛЯДЬ. ДАВАЙ ПРО НЕЁ ПОПИЗДИМ. Уходи из треда и не возвращайся. Ты тут не поможешь ни чем, если будешь в таком же ключе отвечать людям и предлагать твиг вкорячивать.
346 1142605
>>42504
Легких потоков тоже нет, только процессы операционной системы?
347 1142626
>>42306

>ооп


Это отдельная дисциплина?

>тестирование


Есть.

>фреймворки


С этим вот беда, лол.

>бд


Знаком.

>линукс


Достаточно хорошо знаю.

Спасибо за советы!
348 1142628
>>42420
`print "Abu pidr";`
349 1142633
>>42555
>>42547
Спасибо
350 1142655
>>42559
Бамп, меня уже не вылечить? Или анон куратор тхреда еще не пришел?
351 1142659
>>42655
Выбрось и то и другое быстрорешительно.
352 1142661
>>42655

>куратор тхреда


Сука, я проиграл на весь дом.
Представил как куратор заставляет детишек писать на PHP, даёт задание запилить магазин, а потом в новостях его показываю как он заставил 2000 детей писать на PHP. Как же я проиграл
353 1142663
>>42661

> заставляет детишек писать на PHP


Есть

>даёт задание запилить магазин


Есть, но только это файловый обменник

>а потом в новостях


Пока что нету, ждем на ньюсаче.
354 1142664
>>42661
Синий слон, все дела.

разбуди меня в 4.20 к дедлайну
355 1142665
>>42659
Что выбросить то?
356 1142682
>>42665
Скачай какой-нибудь фреймворк и смотри как он устроен. Со временем сам всё поймешь.
357 1142686
>>42682
Ты еще банду 4х скажи почитать и скажи: "а там дальше разберешься". Это вопервых, во вторых в этих фремворках напихано оверхеда дохуя. Я читал и симфони и ларавель и юи. И теперь я могу тебе сделать говносимвони, шмаравель и хуюи, своим кодом, только это мне не помогло научится объектно что ли делать, хз как объяснить.
Иногда тебе надо применить ооп, на некой бизнес логике или каком либо сервисе, но тут уже попадаешь в тупик, так как это не скопировать просто структуру приложения от крутых дядек, а надо понимать самому, как сделать удобнее.
Поэтому я хоть и смотрел другие фреймворки, но все равно после этого не особо получается собрать все мысли в кучу, и написать что то более менее читабельное и понятное.
358 1142692
Анон, как сделать на PHP запрос к API с JSON?
359 1142695
>>42692
что ТЫ хочешь СДЕЛАТЬ с JSON?
360 1142696
>>42695
Дали задание: написать запрос к API и взять необходимые данные.
Сервак отвечает в JSON.
Вот мне и нужно записать код, чтобы при его запуске скрипт опрашивал сервак и забирал с него данные.
361 1142697
>>42696
http://php.net/manual/en/function.file-get-contents.php

Я конешна ни куратор треда, но что то типа этого тебе должно помочь.
362 1142711
>>42591

>КТО СКАЗАЛ ЧТО ГЛОБАЛЬНЫЕ ПЛОХО


много кто, лол. в том числе, ОП. почитай в инторнете, если интересно

>Но кто-то со времён 2007го года тащит эту хуйню и оно идёт и едет


кто-то на дельфи пишет и оно все едет

>шаблонизатор тоже предоставляет ЛОГИКУ


не нужно воспринимать буквально. под "логикой и представлением" имеется в виду "логика МОДЕЛИ и представление".

>когда в Yii всё работает адекватно


лол, codeigniter еще вспомни

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


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

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

пиши дальше простыни кода с глобальными переменными, mysql_query и евалами, другим даже лучше. чем больше таких динозавров как ты, тем проще адекватным анонам устроиться на нормальную работу на нормальный фреймворк за приличную зп.
363 1142719
Почему header:location может не работать?
364 1142721
>>42719
header (location:) офк
365 1142733
посоны, чому fopen () создать файл не может? шоибок нету.
366 1142738
Привет анон. Только начинаю вкатываться. Хочу вкатится в админство. Уже могу в телнет и настройку свичей, управление/мониторинг l2 l3 l4 уровнями. Хочу вкатится еще глубже в админство. Так понял надо знания php, mySQL. В каком порядке стоит учить ? знания php на уровне работы с массивами. SQL на уровне создавал запросики для лаб в универе.
367 1142741
>>42711

>твиги прикручивают, всякие тупорылые смарти


лол, слышал звон не знаю где он. твиг используют все, в т.ч. его часто используют на Yii2, а смарти - это мамонт из того же 2007, откуда и ты вылез.

ты поди и файлы на сервер по фтп заливаешь
368 1142742
>>42738
нахуй админу пхп? ему скорее питон нужен
370 1142744
>>42742
Ну под бзню. Чтоб апачем как бох владеть.
371 1142805
Котятки, как можно автоматизировать синхронизация локальных файлов с теми, что на сервере валяются? Вручную делать как-то долбоебично, ибо нужно помнить какие файлы ты отредактировал и всё такое, что неудобно.
372 1142810
>>42805
И да, желательно без использования phpstorm
373 1142867
>>42810
очень жаль, потому что в шторме это делается одним кликом

а так можно коммитить в удаленный репозиторий и по сценарию сборки автоматом прогонять тесты и загружать их на сервер. но это достаточно заебно в настройке
374 1142892
>>42867
Через netBeans тоже можно такое настроить. Я покурил гугл, вроде что-то нашел.

Но а как это делают вообще все нормальные белые люди, не использующие phpStorm?

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



Так что ли?
375 1142927
По совету форумчан (>>42437) решил установить bbcode. Почитал, посмотрел. В итоге час просидел в неудавшихся попытках установить это ссаное расширения PECL. Есть только для пхп 5.6. Пытаюсь ее пропердолить, вылазит ошибка php5ts.dll. Что делать?
опен сервер, винда 7
376 1142934
>>42892

>Но а как это делают вообще все нормальные белые люди, не использующие phpStorm?


таких не существует лол

>Так что ли?


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

обычно простой деплой файлов используется для работы с дев-сервером, где у разработчика своя папка и свой хост, а сценарии сборки применяются для деплоя на продакшн или всякие стейджы.
377 1143039
>>42927
Попробуй альтернативу http://pear.php.net/package/HTML_BBCodeParser2
378 1143049
>>43039
а pear не устарел?
379 1143050
>>43039
Порыскал на гите, есть отличные решения, но больно громоздкие для нескольких требующийся мне тэгов. Если что можно и на регулярках пописать в регулярки вообще не знаю, лол
380 1143053
>>43049

>pear


Это менеджер пакетов. Тебе нужно поставить пакет для bbcode ручками или через менеджер.
381 1143057
>>43053
Не всасываю
382 1143063
>>42692
для запроса использоовать curl. Для парсинга json_decode()
383 1143066
>>42805
использовать FTP/SSH клиент. Например, CuteFTP. Но он будет перезаливать все файлы. Для выборочной заливки нужно поставить на сервер SVN и использовать svn-клиент на своем компе.
384 1143077
>>43066

>CuteFTP


>SVN


из каких берлог вы выползаете? там щас потепление что ли или что?
385 1143078
>>42559
бiмп.
386 1143083
>>42559
не надо пытаться впихнуть паттерны, потому что прочитал о них. открой код какого-нибудь компонента симфони (ОП рекомендует symfony form) и посмотри, как там сделано.

синглтон признан антипаттерном и вместо него следует использовать DI.
387 1143096
>>43083
А как вообще лучше проектировать, Например у меня есть какое то стороннее апи отдающее жсон. И разные типы запросов и ответов.
Как спроектировать сервис на пхп? с какой стороны подойти?
Выделить объекты и установить связи между ними?
388 1143099
Давайте помолимся за создателя этого треда.
389 1143105
>>42741

>ты поди и файлы на сервер по фтп заливаешь


А как их нужно заливать? просто интересно, другой анон
390 1143113
>>41873
Демонстрируй давай
391 1143114
>>42591

>вкатываение становится проблемой


Ну если ты будешь себя так вести и так писать код, то для тебя проблемой станет работа и собеседования.
И вообще, не тролируй.
392 1143118
>>43099
Я готов кидать ОПу копеечку на Патреон, но у него нет Патреона...
ОП, не думал о таком?
Мне хочется тебя отблагодарить, за твои добрые дела.
393 1143208
>>43099
Я плачу каждый день, потому что не знаю как отблагодарить его.
394 1143215
>>43096
да легко, возьми существующую библиотеку для работы с АПИ, например google php api client и посмотри как там сделано.

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

обычно нужно сделать классы, отвечающие непосредственно за коннект и работу с данными (сам Client, всякие коннекторы, менеджеры паролей и т.д.), условно Request, и классы, которые представляют сущности того АПИ, с которым ты хочешь работать, условно Entity. а дальше нахуярить еще много всяких вспомогательных. короче смотри реальный код из библиотек.

>>43105
по ssh конечно. фтп - небезопасный протокол.
395 1143220
>>43114
почему же, это типичная позиция какого-нибудь битрикс-программиста. мол все эти твиги и прочую бесовщину используют только хипстеры из кремниевой долины лол, а настоящий код он такой, страшный но работающий, с глобальными переменными и на 5.3.

представляю какой шок его ждет, если он узнает, что существуют конторы, где покрывают код тестами.
396 1143222
>>42559

С одной стороны, ты правильно делаешь, что пытаешься изучать разные готовые решения (паттерны). В веб-приложениях ничего нового изобретать не надо, все уже придумано до нас. Но с другой стороны, ты неправильно делаешь, что пытаешься обязательно использовать в коде какой-то паттерн. Это говорит о том, что ты в них не разобрался и не понял, для чего они нужны, когда их используют.

В программировании (как и в вообще в инженерных науках) для каждого решения есть обоснование. Почему мы хотим сделать так, а не иначе. Чаще даже есть не одно решение, а несколько, мы сравниваем плюсы и минусы и выбираем то, что лучше подходит. Вот например, если у тебя есть свободное время, ты можешь почитать отчет о разработке радиопередатчика для первого спутника (он длинный): http://russianspacesystems.ru/wp-content/uploads/2017/10/Otchet-o-razrabotke-bortovoy-radiostancii-pervogo-sputnika.pdf . В этом отчете формулируется задача, разбираются разные варианты ее решения, и каждый раз обосновывается, почему выбран тот или иной вариант. Например, почему были выбраны лампы, а не транзисторы. Вот в идеале у тебя в голове должен происходить такой же мыслительный процесс. Начинающему, может, это и сложно, но со временем надо к этому стремиться.

Если ты сомневаешься, то можно по умолчанию выбрать самое простое решение. Такое решение, которое требует минимум затрат времени и усилий. Не уверен, нужен ли тебе ORM? Ок, не используй. Но если потом ты заметишь, что пишешь много однотипных SQL запросов, то может быть стоит все же подумать про ORM.

Ну например, я могу для решения какой-то задачи написать просто скрипт на 200 строчек без ООП (и иногда даже без функций), а потом по мере надобности добавлять объекты, библиотеки, итд.

Есть хорошая статья по этой теме (как программисты пекли хлеб): https://habrahabr.ru/post/153225/ - обязательно прочти.

То есть должно быть так: возникает потребность в чем-то и ты применяешь какое-то решение. А не так, что просто подключаешь в проект библиотеку, потому что о ней написали на Хабре. И здесь, конечно, полезно умение замечать эту потребность, видеть, что в коде что-то не так. Ну вот например, ты замечаешь, что получается много однообразного кода и думаешь, как это исправить.

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

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


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

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



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

> Так же и с интерфейсами, фабриками.



Про интерфейсы есть урок - https://github.com/codedokode/pasta/blob/master/php/interfaces.md - там есть немного, но в общем интерфейсы мы используем, когда хотим дать возможность писать новые классы, с которыми сможет работать существующий код. Ну например, интерфейс логгера PSR-3 - мы используем в коде интерфейс, а не название конкретного логгера, и благодаря этому можем подключить любой логгер. Почитай про PSR-3 как пример использования интерфейсов, если не знаком с ним.

Фабрика - это класс, создающий объекты. Может использоваться в такой ситуации: есть какая-то библиотека, которая создает объекты. И мы хотим дать пользователю возможность влиять на создание этих объектов. Код библиотеки он править не может, потому мы выносим создание объектов в фабрику и разрешаем пользователю написать и передать библиотеке свою фабрику.

Из примеров использования фабрик я могу вспомнить разве что https://github.com/symfony/form - там есть класс FormFactory (он создает объекты форм и полей в формах - и те и другие там называются Form). Я, кстати, советовал бы тебе разбрать эту библиотеку, в том числе код, и нарисовать диаграмму классов в ней - там много интересного.

Но ты должен добавлять фабрики и интерфейсы только когда ты почуствуешь потребность в них. А не просто добавлять, чтобы были.

> Я напилил кучу интерфейсов


Зачем?

> Что бы все понятно было.


Да, так и должно быть.

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


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

> Но в итоге ты углубляешься в код ради кода, а не ради решения задачи


Хорошо, что ты это понимаешь. Попробуй тогда использовать более простые подходы, может для твоей задачи хватит 10-20 функций без ООП? Или может быть не надо так много разных классов.

> помоги как мне быть.


Так как ты не описал свою задачу и не показал куски кода, которые тебе не нравятся, то я могу только дать общие советы.
396 1143222
>>42559

С одной стороны, ты правильно делаешь, что пытаешься изучать разные готовые решения (паттерны). В веб-приложениях ничего нового изобретать не надо, все уже придумано до нас. Но с другой стороны, ты неправильно делаешь, что пытаешься обязательно использовать в коде какой-то паттерн. Это говорит о том, что ты в них не разобрался и не понял, для чего они нужны, когда их используют.

В программировании (как и в вообще в инженерных науках) для каждого решения есть обоснование. Почему мы хотим сделать так, а не иначе. Чаще даже есть не одно решение, а несколько, мы сравниваем плюсы и минусы и выбираем то, что лучше подходит. Вот например, если у тебя есть свободное время, ты можешь почитать отчет о разработке радиопередатчика для первого спутника (он длинный): http://russianspacesystems.ru/wp-content/uploads/2017/10/Otchet-o-razrabotke-bortovoy-radiostancii-pervogo-sputnika.pdf . В этом отчете формулируется задача, разбираются разные варианты ее решения, и каждый раз обосновывается, почему выбран тот или иной вариант. Например, почему были выбраны лампы, а не транзисторы. Вот в идеале у тебя в голове должен происходить такой же мыслительный процесс. Начинающему, может, это и сложно, но со временем надо к этому стремиться.

Если ты сомневаешься, то можно по умолчанию выбрать самое простое решение. Такое решение, которое требует минимум затрат времени и усилий. Не уверен, нужен ли тебе ORM? Ок, не используй. Но если потом ты заметишь, что пишешь много однотипных SQL запросов, то может быть стоит все же подумать про ORM.

Ну например, я могу для решения какой-то задачи написать просто скрипт на 200 строчек без ООП (и иногда даже без функций), а потом по мере надобности добавлять объекты, библиотеки, итд.

Есть хорошая статья по этой теме (как программисты пекли хлеб): https://habrahabr.ru/post/153225/ - обязательно прочти.

То есть должно быть так: возникает потребность в чем-то и ты применяешь какое-то решение. А не так, что просто подключаешь в проект библиотеку, потому что о ней написали на Хабре. И здесь, конечно, полезно умение замечать эту потребность, видеть, что в коде что-то не так. Ну вот например, ты замечаешь, что получается много однообразного кода и думаешь, как это исправить.

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

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


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

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



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

> Так же и с интерфейсами, фабриками.



Про интерфейсы есть урок - https://github.com/codedokode/pasta/blob/master/php/interfaces.md - там есть немного, но в общем интерфейсы мы используем, когда хотим дать возможность писать новые классы, с которыми сможет работать существующий код. Ну например, интерфейс логгера PSR-3 - мы используем в коде интерфейс, а не название конкретного логгера, и благодаря этому можем подключить любой логгер. Почитай про PSR-3 как пример использования интерфейсов, если не знаком с ним.

Фабрика - это класс, создающий объекты. Может использоваться в такой ситуации: есть какая-то библиотека, которая создает объекты. И мы хотим дать пользователю возможность влиять на создание этих объектов. Код библиотеки он править не может, потому мы выносим создание объектов в фабрику и разрешаем пользователю написать и передать библиотеке свою фабрику.

Из примеров использования фабрик я могу вспомнить разве что https://github.com/symfony/form - там есть класс FormFactory (он создает объекты форм и полей в формах - и те и другие там называются Form). Я, кстати, советовал бы тебе разбрать эту библиотеку, в том числе код, и нарисовать диаграмму классов в ней - там много интересного.

Но ты должен добавлять фабрики и интерфейсы только когда ты почуствуешь потребность в них. А не просто добавлять, чтобы были.

> Я напилил кучу интерфейсов


Зачем?

> Что бы все понятно было.


Да, так и должно быть.

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


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

> Но в итоге ты углубляешься в код ради кода, а не ради решения задачи


Хорошо, что ты это понимаешь. Попробуй тогда использовать более простые подходы, может для твоей задачи хватит 10-20 функций без ООП? Или может быть не надо так много разных классов.

> помоги как мне быть.


Так как ты не описал свою задачу и не показал куски кода, которые тебе не нравятся, то я могу только дать общие советы.
397 1143223
>>43096

Ты хочешь написать сервер API (раздавать данные всем), или клиент (получать данные из стороннего сервиса)?

Ты можешь попробовать "выделить объекты", но попытайся сначала сделать минимальный вариант, просто решающий задачу. Может для твоей задачи даже не нужны объекты, а хватит просто массивов (хотя сомневаюсь, что это удобно). Ну и наверняка для твоей задачи уже есть какие-то готовые библиотеки - для преобразования в JSON точно что-то должно быть.

>>43083

> синглтон признан антипаттерном и вместо него следует использовать DI.


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

>>43105
>>42805

Это называется "деплой". Гуглится по словам вроде "автоматизация деплоя php", если нет результатов - то же самое по-англйиски. Вот ссылка на гугл, изучай: https://www.google.ru/search?q=автоматизация+деплоя+php&btnG=Поиск&newwindow=1&dcr=0&gbv=1

Можешь потом написать итоги своих поисков для других анонов.

FTP точно использовать не надо, так как он не защищен и позволяет атакаующему просматривать и подменять информацию. Как замена FTP, есть SCP и SFTP - они работают через SSH. Правда, не так много программ, которые их поддерживают.

Ну а вообще, я обычно стараюсь автоматизировать деплой. Глупо тратить время на выделение файлов, нажатие кнопок в GUI, когда можно написать скрипт. В простой ситуации - bash-скрипт (программа на языке bash) с использованием утилиты rsync (он поддерживает передачу файлов по SSH), в сложной - плейбук для ansible. Учти, что многое из этого плохо работает или вовсе не работает под Windows.

Есть еще вариант "деплой через git" - git позволяет выгружать коммиты в удаленный репозиторий на другом сервере.

Ну если тебе лень изучать утилиты linux, ты ведь программист, что тебе мешает написать программу копирования файлов на PHP? Или поискать готовую. Или как-то настроить программу, чтобы деплой делался одной кнопкой.

Хотя конечно скриптами автоматизировать такие вещи удобнее, на мой взгляд.
397 1143223
>>43096

Ты хочешь написать сервер API (раздавать данные всем), или клиент (получать данные из стороннего сервиса)?

Ты можешь попробовать "выделить объекты", но попытайся сначала сделать минимальный вариант, просто решающий задачу. Может для твоей задачи даже не нужны объекты, а хватит просто массивов (хотя сомневаюсь, что это удобно). Ну и наверняка для твоей задачи уже есть какие-то готовые библиотеки - для преобразования в JSON точно что-то должно быть.

>>43083

> синглтон признан антипаттерном и вместо него следует использовать DI.


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

>>43105
>>42805

Это называется "деплой". Гуглится по словам вроде "автоматизация деплоя php", если нет результатов - то же самое по-англйиски. Вот ссылка на гугл, изучай: https://www.google.ru/search?q=автоматизация+деплоя+php&btnG=Поиск&newwindow=1&dcr=0&gbv=1

Можешь потом написать итоги своих поисков для других анонов.

FTP точно использовать не надо, так как он не защищен и позволяет атакаующему просматривать и подменять информацию. Как замена FTP, есть SCP и SFTP - они работают через SSH. Правда, не так много программ, которые их поддерживают.

Ну а вообще, я обычно стараюсь автоматизировать деплой. Глупо тратить время на выделение файлов, нажатие кнопок в GUI, когда можно написать скрипт. В простой ситуации - bash-скрипт (программа на языке bash) с использованием утилиты rsync (он поддерживает передачу файлов по SSH), в сложной - плейбук для ansible. Учти, что многое из этого плохо работает или вовсе не работает под Windows.

Есть еще вариант "деплой через git" - git позволяет выгружать коммиты в удаленный репозиторий на другом сервере.

Ну если тебе лень изучать утилиты linux, ты ведь программист, что тебе мешает написать программу копирования файлов на PHP? Или поискать готовую. Или как-то настроить программу, чтобы деплой делался одной кнопкой.

Хотя конечно скриптами автоматизировать такие вещи удобнее, на мой взгляд.
398 1143224
>>43118

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

>>43063

Это не самый удачный вариант. curl требует указания разных опций, обработку ошибок и тд. Проще по моему взять библиотеку-HTTP клиент Guzzle.

>>42927

Во-первых, есть же документация. Ты ее внимательно изучил? Идем сюда

- http://php.net/manual/ru/bbcode.installation.php

отсюда идем по ссылке:

- http://php.net/manual/ru/install.pecl.php

И изучаем все, что написано. Обычно это работает так:

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

Если ты используешь винду, то надо либо искать готовую dll-ку для твоей версии PHP на сайте pecl, либо собирать самому из исходников (это требует установить компилятор вроде Windows SDK или Visual Studio, качать исходники PHP, ставить их в нужную папку, возиться с командной строкой - в общем, будет больно. Описан процесс тут http://php.net/manual/ru/install.pecl.windows.php но без подробностей, а далее подробности надо искать тут https://wiki.php.net/internals/windows/stepbystepbuild_sdk_2#building_pecl_extensions ).

Ты не написал, какой версии у тебя PHP. Тут вот https://pecl.php.net/package/bbcode есть ссылка DLL, и если перейти по ней https://pecl.php.net/package/bbcode/1.0.3b1/Windows то какие-то добрые люди уже собрали расширение для PHP5.3, 5.4, 5.5 и 5.6. Для PHP7 они конечно не подойдут.

Ну и судя по истории релизов, оканчивающейся в 2010 году, с PHP7 это расширение вряд ли совместимо.

Гугление по "bbcode php7" выдает проект - https://github.com/esminis/php_pecl_bbcode - но там нет сборок под винду, то есть там дан только исходный код и надо его самому собирать. В принципе, наверно, это было бы неплохим опытом для тебя, попробовать собрать расширение под виндой, но рассмотрим еще другие варианты.

В документации написано, что есть аналог расширения в виде библиотеки на PHP - http://pear.php.net/package/HTML_BBCodeParser . Он ставится через PEAR - это менеджер библиотек, который умеет их скачивать и устанавливать, но сначала придется научиться им пользоваться, например, найти статью про него или изучить документацию. Но это точно проще, чем компилировать.

Также, есть еще другие разметки, кроме BBCode. Берешь список тут https://en.wikipedia.org/wiki/Lightweight_markup_language изучаешь каждую и проверяешь, есть ли для данной разметки php-библиотека. Например, поиском в packagist.org (репозиторий библиотек для композера).
398 1143224
>>43118

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

>>43063

Это не самый удачный вариант. curl требует указания разных опций, обработку ошибок и тд. Проще по моему взять библиотеку-HTTP клиент Guzzle.

>>42927

Во-первых, есть же документация. Ты ее внимательно изучил? Идем сюда

- http://php.net/manual/ru/bbcode.installation.php

отсюда идем по ссылке:

- http://php.net/manual/ru/install.pecl.php

И изучаем все, что написано. Обычно это работает так:

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

Если ты используешь винду, то надо либо искать готовую dll-ку для твоей версии PHP на сайте pecl, либо собирать самому из исходников (это требует установить компилятор вроде Windows SDK или Visual Studio, качать исходники PHP, ставить их в нужную папку, возиться с командной строкой - в общем, будет больно. Описан процесс тут http://php.net/manual/ru/install.pecl.windows.php но без подробностей, а далее подробности надо искать тут https://wiki.php.net/internals/windows/stepbystepbuild_sdk_2#building_pecl_extensions ).

Ты не написал, какой версии у тебя PHP. Тут вот https://pecl.php.net/package/bbcode есть ссылка DLL, и если перейти по ней https://pecl.php.net/package/bbcode/1.0.3b1/Windows то какие-то добрые люди уже собрали расширение для PHP5.3, 5.4, 5.5 и 5.6. Для PHP7 они конечно не подойдут.

Ну и судя по истории релизов, оканчивающейся в 2010 году, с PHP7 это расширение вряд ли совместимо.

Гугление по "bbcode php7" выдает проект - https://github.com/esminis/php_pecl_bbcode - но там нет сборок под винду, то есть там дан только исходный код и надо его самому собирать. В принципе, наверно, это было бы неплохим опытом для тебя, попробовать собрать расширение под виндой, но рассмотрим еще другие варианты.

В документации написано, что есть аналог расширения в виде библиотеки на PHP - http://pear.php.net/package/HTML_BBCodeParser . Он ставится через PEAR - это менеджер библиотек, который умеет их скачивать и устанавливать, но сначала придется научиться им пользоваться, например, найти статью про него или изучить документацию. Но это точно проще, чем компилировать.

Также, есть еще другие разметки, кроме BBCode. Берешь список тут https://en.wikipedia.org/wiki/Lightweight_markup_language изучаешь каждую и проверяешь, есть ли для данной разметки php-библиотека. Например, поиском в packagist.org (репозиторий библиотек для композера).
399 1143225
>>43050

Библиотека на регулярках создает риск XSS - злоумышленник сможет вставлять произвольный HTML или JS код в страницу.

>>42738

Изучи linux, bash, основные утилиты. По PHP - от админа требуется только умение его установить и может чуть подправить php.ini (почитав мануал), по MySQL - установить и настроить, и на сайте MySQL есть 2 раздела специально для администраторов:

- https://dev.mysql.com/doc/refman/5.7/en/installing.html
- https://dev.mysql.com/doc/refman/5.7/en/server-administration.html

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

>>42733

Может у тебя отключен их вывод через опцию display_errors в php.ini? Или включено их игнорирование через error_reporting? Проверь настройки (с помощью phpinfo()) и изучи логи, может там есть ошибка.

>>42719

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

>>42686

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

А еще, если вдруг ты не очень уверен в ООП, то у меня еще есть пара задач - про Гостиницу и Агенство - не хочешь хотя бы глянуть? https://phpclub.tech/pr/chain/1108694/

> во вторых в этих фреймворках напихано оверхеда дохуя.


А ты не думал, что это может быть сделано по какой-то причине? Вряд ли у них есть цель просто так увеличивать объем кода.
399 1143225
>>43050

Библиотека на регулярках создает риск XSS - злоумышленник сможет вставлять произвольный HTML или JS код в страницу.

>>42738

Изучи linux, bash, основные утилиты. По PHP - от админа требуется только умение его установить и может чуть подправить php.ini (почитав мануал), по MySQL - установить и настроить, и на сайте MySQL есть 2 раздела специально для администраторов:

- https://dev.mysql.com/doc/refman/5.7/en/installing.html
- https://dev.mysql.com/doc/refman/5.7/en/server-administration.html

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

>>42733

Может у тебя отключен их вывод через опцию display_errors в php.ini? Или включено их игнорирование через error_reporting? Проверь настройки (с помощью phpinfo()) и изучи логи, может там есть ошибка.

>>42719

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

>>42686

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

А еще, если вдруг ты не очень уверен в ООП, то у меня еще есть пара задач - про Гостиницу и Агенство - не хочешь хотя бы глянуть? https://phpclub.tech/pr/chain/1108694/

> во вторых в этих фреймворках напихано оверхеда дохуя.


А ты не думал, что это может быть сделано по какой-то причине? Вряд ли у них есть цель просто так увеличивать объем кода.
400 1143227
>>42605

Что такое "легкие потоки"? LWP? Если тебе хочется использовать треды, то наверно можно найти какую-нибудь библиотеку под линукс и взять потокобезопасную версию PHP. Но подозреваю, там будут подводные камни, так как я не слышал, чтобы кто-то это использовал.

>>42591

> КТО СКАЗАЛ ЧТО ГЛОБАЛЬНЫЕ ПЛОХО?


Вот ты бы разобрался сначала. Конечно, глобальные переменные плохо, если у тебя скрипт больше 200 строчек. Потому что их можно изменять из любой точки кода и понять, что в них находится в тот или иной момент времени, не изучая весь код, сложно. Более подробно про них ты можешь прочесть кусочек в пасте про DI: https://github.com/codedokode/pasta/blob/master/arch/di.md#Чем-плохи-глобальные-переменные

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

> Область видимости притащили, используй


Так у глобальных переменных глобальная область видимости - они доступны везде (внутри функций импортируются через global) - что ты хотел сказать-то?

> ЛОГИКА И ПРЕДСТАВЛЕНИЕ НЕ ДОЛЖНЫ СМЕШИВАТЬСЯ


Конечно, не должны. Тяжело же читать код, когда идет 5 строк HTML кода, потом SQL запрос на 10 строк, потом разбор результатов этого запроса, потом еще 10 строк HTML и так далее. Удобнее в одном файле получать данные, а в другом выводить их на страницу. Особенно когда у тебя сложные страницы, содержащие много разных блоков и сложная логика получения данных. Почитай урок про шаблоны https://github.com/codedokode/pasta/blob/master/php/templates.md

> твиги прикручивают


Чем твиг лучше встроенного в PHP шаблона, подробно и доходчиво объясняется на главной странице сайта твига: https://twig.symfony.com/ - пробовал почитать?

> А шаблонизатор тоже предоставляет ЛОГИКУ


Логику представления, а не получения данных.

> вкатываение становится проблемой.


Проблема скорее всего в тебе и твоем восприятии. Заходи чаще в наш тред, проходи задачи из ОП-поста и может быть, ты все же сможешь разобраться, зачем нужна та или иная библиотека. У нас тебе всегда этого готовы объяснить.
400 1143227
>>42605

Что такое "легкие потоки"? LWP? Если тебе хочется использовать треды, то наверно можно найти какую-нибудь библиотеку под линукс и взять потокобезопасную версию PHP. Но подозреваю, там будут подводные камни, так как я не слышал, чтобы кто-то это использовал.

>>42591

> КТО СКАЗАЛ ЧТО ГЛОБАЛЬНЫЕ ПЛОХО?


Вот ты бы разобрался сначала. Конечно, глобальные переменные плохо, если у тебя скрипт больше 200 строчек. Потому что их можно изменять из любой точки кода и понять, что в них находится в тот или иной момент времени, не изучая весь код, сложно. Более подробно про них ты можешь прочесть кусочек в пасте про DI: https://github.com/codedokode/pasta/blob/master/arch/di.md#Чем-плохи-глобальные-переменные

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

> Область видимости притащили, используй


Так у глобальных переменных глобальная область видимости - они доступны везде (внутри функций импортируются через global) - что ты хотел сказать-то?

> ЛОГИКА И ПРЕДСТАВЛЕНИЕ НЕ ДОЛЖНЫ СМЕШИВАТЬСЯ


Конечно, не должны. Тяжело же читать код, когда идет 5 строк HTML кода, потом SQL запрос на 10 строк, потом разбор результатов этого запроса, потом еще 10 строк HTML и так далее. Удобнее в одном файле получать данные, а в другом выводить их на страницу. Особенно когда у тебя сложные страницы, содержащие много разных блоков и сложная логика получения данных. Почитай урок про шаблоны https://github.com/codedokode/pasta/blob/master/php/templates.md

> твиги прикручивают


Чем твиг лучше встроенного в PHP шаблона, подробно и доходчиво объясняется на главной странице сайта твига: https://twig.symfony.com/ - пробовал почитать?

> А шаблонизатор тоже предоставляет ЛОГИКУ


Логику представления, а не получения данных.

> вкатываение становится проблемой.


Проблема скорее всего в тебе и твоем восприятии. Заходи чаще в наш тред, проходи задачи из ОП-поста и может быть, ты все же сможешь разобраться, зачем нужна та или иная библиотека. У нас тебе всегда этого готовы объяснить.
401 1143228
>>42558

"вкатиться" это значит "устроиться на работу"? В шапке же написано, ищешь вакансии на сайте вакансий, отправляешь отклик, проходишь собеседование и тд. Или тебя что-то конкретное интересует?

Если вопрос "что изучать", то опять же, надо изучить почти всю шапку - серверный язык программирования, SQL, итд.

>>42553

> И тут я понял что я нихера не понимаю как это реализовать в mysql.


Есть 3 паттерна наследования: Single Table Inheritance, Concrete Table Inheritance, Class table inheritance - погугли их для начала и потом задай вопрос, если непонятно.

Учти, что не все паттерны могут поддерживаться в Доктрине, потому глянь еще ее документацию.

>>42549

Не стоит на нее полагаться, но добавить инпут можно. Что касается защиты от загрузки больших файлов, во-первых, есть опции в php.ini вроде post_max_size ( http://php.net/manual/ru/ini.core.php ), во-вторых, опции в конфиге веб-сервера, например в nginx https://nginx.ru/ru/docs/http/ngx_http_core_module.html#client_max_body_size

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

Тут объяснение https://phpclub.ru/talk/threads/Зачем-нужно-указывать-в-форме-max_file_size.76276/
402 1143229
>>42467

Если построение SQL запроса, то использовать можно query biulder. Также, удобно сделать объект для представления фильтра.

Если товаров много, может понадобиться подключать демон поиска вроде sphinx, если SQL база будет тупить.

>>42417

В документации чуть-чуть упомянуто: https://www.slimframework.com/docs/v3/objects/router.html#route-callbacks

В Слиме используется подход, когда "контроллер" получает на вход объекты Запроса и пустой Ответ, и должен заполнить этот Ответ данными (кодом статуса, телом страницы, заголовками, и всем, что HTTP позволяет возвращать в ответе). Есть еще немного другой подход - в Симфони контроллер получает на вход HTTP-Запрос и должен создать и вернуть HTTP-Ответ.

Зачем? Ну, тут есть несколько причин:

- логичность. Теперь у нас контроллер не создает какие-то побочные эффекты (что-то выводит, создает заголовки, куки), а возвращает на выходе результат свой работы - HTTP-Ответ. Логично же, получаем Запрос, обрабатываем и возвращает Ответ
- взаимодействие с middleware. В Слиме есть middleware - обертки, которые могут модифицировать Запрос до его получения контроллером и модифицировать Ответ после того, как он создан, но до того, как он отдан в браузер пользователя. Очевидно, что для этого контроллер должен именно возвращать Ответ. Вывод через echo можно конечно перехватить (и он перехватывается), а вот выставленные через функцию header() заголовки перехватить нельзя и middleware их не получит и не сможет с ними ничего сделать.
- тестирование. Мы можем в тесте создать Запрос, вызвать контроллер, получить Ответ и проверить его правильность. Опять же, в случае использования echo/header напрямую, это невозможно.
- многоразововость. Мы можем в ходе работы скрипта вызвать контроллер(ы) несколько раз и получить несколько Ответов, и что-то с ними делать, как-то их использовать. Можно например сделать несколько контроллеров, каждый из которых отвечает за свою часть страницы.

Аноны, а вы не хотите это перевести на англ и законтрибутить в документацию Слима? А то мы пошлем человека читать документацию, а объяснения там нет.

>>41976

В ОП посте упомянуты книги Зандстры и Шлосснейла(?). Единственный недостаток - староватые, но зато учат в правильном направлении. Ну и php the right way.

>>42591

Ты вбросил в тред код - получил ожидаемую критику. Такие правила этого треда. Но, конечно, важно писать о недостатках корректно. Наша цель ведь не доказать, кто умнее, а обучить.
402 1143229
>>42467

Если построение SQL запроса, то использовать можно query biulder. Также, удобно сделать объект для представления фильтра.

Если товаров много, может понадобиться подключать демон поиска вроде sphinx, если SQL база будет тупить.

>>42417

В документации чуть-чуть упомянуто: https://www.slimframework.com/docs/v3/objects/router.html#route-callbacks

В Слиме используется подход, когда "контроллер" получает на вход объекты Запроса и пустой Ответ, и должен заполнить этот Ответ данными (кодом статуса, телом страницы, заголовками, и всем, что HTTP позволяет возвращать в ответе). Есть еще немного другой подход - в Симфони контроллер получает на вход HTTP-Запрос и должен создать и вернуть HTTP-Ответ.

Зачем? Ну, тут есть несколько причин:

- логичность. Теперь у нас контроллер не создает какие-то побочные эффекты (что-то выводит, создает заголовки, куки), а возвращает на выходе результат свой работы - HTTP-Ответ. Логично же, получаем Запрос, обрабатываем и возвращает Ответ
- взаимодействие с middleware. В Слиме есть middleware - обертки, которые могут модифицировать Запрос до его получения контроллером и модифицировать Ответ после того, как он создан, но до того, как он отдан в браузер пользователя. Очевидно, что для этого контроллер должен именно возвращать Ответ. Вывод через echo можно конечно перехватить (и он перехватывается), а вот выставленные через функцию header() заголовки перехватить нельзя и middleware их не получит и не сможет с ними ничего сделать.
- тестирование. Мы можем в тесте создать Запрос, вызвать контроллер, получить Ответ и проверить его правильность. Опять же, в случае использования echo/header напрямую, это невозможно.
- многоразововость. Мы можем в ходе работы скрипта вызвать контроллер(ы) несколько раз и получить несколько Ответов, и что-то с ними делать, как-то их использовать. Можно например сделать несколько контроллеров, каждый из которых отвечает за свою часть страницы.

Аноны, а вы не хотите это перевести на англ и законтрибутить в документацию Слима? А то мы пошлем человека читать документацию, а объяснения там нет.

>>41976

В ОП посте упомянуты книги Зандстры и Шлосснейла(?). Единственный недостаток - староватые, но зато учат в правильном направлении. Ну и php the right way.

>>42591

Ты вбросил в тред код - получил ожидаемую критику. Такие правила этого треда. Но, конечно, важно писать о недостатках корректно. Наша цель ведь не доказать, кто умнее, а обучить.
403 1143230
>>41834

> Очевидно же, что проблема в spellSmallNumber. Но где?


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

> Как в PDO заменить mysql_real_escape_string так, чтобы оно работало?


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

По другим картинкам - я бы советовал шаблоны выносить в отдельный файл. И прочитать мой урок про шаблоны с гитхаба.

По работе с формами - не надо использовать сессии для ошибок, есть алгоритм гораздо лучше: https://github.com/codedokode/pasta/blob/master/forms.md

В коде есть и просто ошибки, например, бессмысленная строка

$dateTime;

Далее, quote() в первом примере испоьзован неверно.

strlen тоже использован неверно, почитай урок https://github.com/codedokode/pasta/blob/master/php/strings-utf8.md

По поводу архитектуры - я бы советовал прочесть урок про MVC ( https://github.com/codedokode/pasta/blob/master/arch/mvc.md ), заметь что он не требует ООП и ты можешь получить его, просто вынеся часть кода (например, получение данных из БД) в отдельные функции. Это, например, облегчит повторное использование кода (сейчас у тебя код получения данных вплавлен в шаблон и его нельзя вызвать из другого места) и тестирование.

В четвертом примере у тебя SQL инъекция: https://github.com/codedokode/pasta/blob/master/security/sql-injection.md

Код у тебя правда плохой, видимо ты учился по какому-то устаревшему учебнику.

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

>>41811

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

Может они так пытаются упростить код, избавившись от DI? Так там внутри вроде как есть DI конейнер, просто эти статические "фасады" скрывают его наличие.
403 1143230
>>41834

> Очевидно же, что проблема в spellSmallNumber. Но где?


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

> Как в PDO заменить mysql_real_escape_string так, чтобы оно работало?


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

По другим картинкам - я бы советовал шаблоны выносить в отдельный файл. И прочитать мой урок про шаблоны с гитхаба.

По работе с формами - не надо использовать сессии для ошибок, есть алгоритм гораздо лучше: https://github.com/codedokode/pasta/blob/master/forms.md

В коде есть и просто ошибки, например, бессмысленная строка

$dateTime;

Далее, quote() в первом примере испоьзован неверно.

strlen тоже использован неверно, почитай урок https://github.com/codedokode/pasta/blob/master/php/strings-utf8.md

По поводу архитектуры - я бы советовал прочесть урок про MVC ( https://github.com/codedokode/pasta/blob/master/arch/mvc.md ), заметь что он не требует ООП и ты можешь получить его, просто вынеся часть кода (например, получение данных из БД) в отдельные функции. Это, например, облегчит повторное использование кода (сейчас у тебя код получения данных вплавлен в шаблон и его нельзя вызвать из другого места) и тестирование.

В четвертом примере у тебя SQL инъекция: https://github.com/codedokode/pasta/blob/master/security/sql-injection.md

Код у тебя правда плохой, видимо ты учился по какому-то устаревшему учебнику.

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

>>41811

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

Может они так пытаются упростить код, избавившись от DI? Так там внутри вроде как есть DI конейнер, просто эти статические "фасады" скрывают его наличие.
404 1143231
>>41532

Какие именно тесты? Юнит-тест например можно просто написать руками. Ну допустим, протестируем функцию mb_strlen:

$len = mb_strlen("Привет");
if ($len != 6) {
throw new TestFailedException("Expected 6, got $len instead");
}

Дальше ты можешь сделать какие-то вспомогательные функции. А потом ты обнаружишь что написал слабый и кривой аналог phpunit.

>>41528

Есть хороший учебник на примере Питона http://aliev.me/runestone/

Самый подробный учебник - это многотомник Кнута (ты скорее умрешь, чем его осилишь).

Ключевые слова для поиска - "алгоритмы и структуры данных".

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

>>41492

Как я написал выше, либо юнион, либо денормализация с добавлением таблицы, хранящей ссылки на 3 последних поста для каждого треда.

>>41330

> Мануал читал, в английский могу, но я не въехал, как сделать так, чтобы он выбирал случайное число и при этом выводил из массива его значение.


Тут есть 2 момента, на которые ты видимо не обратил внимание:

- array_rand возвращает не значения элементов, а их ключи. Тебе надо самому получить значение из массива по ключу (подсказка: для этого есть квадратные скобки: $value = $array[$key]).
- если попросить 1 ключ, array_rand вернет его. А если 2 или больше - то вернет массив ключей. (это плохой подход, возвращать результат в разных форматах, не делай так). Потому в мануале там использованы квадратные скобки.

> то тут первая и вторая строки (где значения из 1, 2 и 3 массива) получаются абсолютно идентичными.


А это потому что у тебя код в стиле:

- взять случайное слово и записать его в переменную $rand1
- вывести в первой строке $rand1
- вывести во второй строке $rand1

Очевидно, что строки будут одинаковые. Тебе нужны разные переменные для первой и второй строк. Либо же использовать цикл из 2 шагов (на каждом шаге генерируем и выводим одну строку).
404 1143231
>>41532

Какие именно тесты? Юнит-тест например можно просто написать руками. Ну допустим, протестируем функцию mb_strlen:

$len = mb_strlen("Привет");
if ($len != 6) {
throw new TestFailedException("Expected 6, got $len instead");
}

Дальше ты можешь сделать какие-то вспомогательные функции. А потом ты обнаружишь что написал слабый и кривой аналог phpunit.

>>41528

Есть хороший учебник на примере Питона http://aliev.me/runestone/

Самый подробный учебник - это многотомник Кнута (ты скорее умрешь, чем его осилишь).

Ключевые слова для поиска - "алгоритмы и структуры данных".

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

>>41492

Как я написал выше, либо юнион, либо денормализация с добавлением таблицы, хранящей ссылки на 3 последних поста для каждого треда.

>>41330

> Мануал читал, в английский могу, но я не въехал, как сделать так, чтобы он выбирал случайное число и при этом выводил из массива его значение.


Тут есть 2 момента, на которые ты видимо не обратил внимание:

- array_rand возвращает не значения элементов, а их ключи. Тебе надо самому получить значение из массива по ключу (подсказка: для этого есть квадратные скобки: $value = $array[$key]).
- если попросить 1 ключ, array_rand вернет его. А если 2 или больше - то вернет массив ключей. (это плохой подход, возвращать результат в разных форматах, не делай так). Потому в мануале там использованы квадратные скобки.

> то тут первая и вторая строки (где значения из 1, 2 и 3 массива) получаются абсолютно идентичными.


А это потому что у тебя код в стиле:

- взять случайное слово и записать его в переменную $rand1
- вывести в первой строке $rand1
- вывести во второй строке $rand1

Очевидно, что строки будут одинаковые. Тебе нужны разные переменные для первой и второй строк. Либо же использовать цикл из 2 шагов (на каждом шаге генерируем и выводим одну строку).
405 1143237
Аноны, сам Господь спустился с небес и отвечает нам!

Спасибо большое, отпишусь. Я делал на PHP клонирование части логики с одного сервера на другой, когда выстраивал систему обновления сайта. Там по одной кнопочке запаковывался архив с .php файлами, отправлялся просто по https, далее там уже распаковывался и всё такое.
Разумеется, все с использованием хеша от (данные + секретный ключ), так как с этим нужно осторожнее быть.
Но я отказался от этой системы, т.к. боюсь, она не слишком надежная.

>>42805 анон
406 1143238
407 1143239
>>43223
>>43237

Извините за флуд. Не тот пост отметил.
408 1143242
Не стукайте, я тут задачу с кредитным айфоном принес. Правильно ли я решил? https://ideone.com/wjQilA
4906c3f625.png15 Кб, 785x125
409 1143243
>>43242
и еще пара вопросов
1. подскажите обязательно ли заключать переменные находящиеся в echo внутрь скобок {}, пробовал без них все работает. Зачем они нужны?
2. Что выделено на пике является дурным тоном в написании кода? html так вставлять нельзя, как я понял.
sage 410 1143247
>>42743
>>42711
ЯСНА ВСЁ. Не передёргивай, говорит, а сам передёргивает. Смарти ему из 2007го... а условий, операторы и прочее в твиг не завезли, да? Ладно, ты уточнил на счёт отделение "логики". Но ведь её и отделяют. Модели и пр. Какая, нахуй, разница - видишь ли хтымыло вместе с пшп, или видишь свой ебучий твиг?

> пиши дальше простыни кода с глобальными переменными, mysql_query и евалами


Ниче ты ПЕРЕДЁРГИВАЕШЬ

>>43114
>>43220
Я насмотрелся уже на хипстеров, которые работая над одним говносайтом, накручивают на него твиги и ебашат его через ГИТ, просто потомушто модно. А если туда надо прикрутить пару процедурок, которые он ниасилил в ходе понимания seo, то ОБЯЗАТИЛЬНА ДАВАЙ ЧЕРЕЗ ГИТ, МНЕ ВАЖНА, НИКТО НИРАБОТАИТ С МАИМ САЙТАМ, НО Я ПАСТАЯННА ГИТПУШУ И ГИТАПДЕЙТЮ И ТЫ ТАК ДЕЛАЙ, НА ХАБРЕ ТАК СКОЗАЛИ.

Про читаемость они мне будут тереть. Научите тут лучше людей классы писать, вызывать всё это, а свои советы про твиги уносите. Принесут догматы про глобалы, твиги, ТЕСТЫ... в тред начинающих, гиты свои прилепят, со словами ТАК НАДА, и рады, ёпт.
411 1143248
>>43243
это с простыми именами переменных всё нормально

Если будешь выводишь массивы или объекты (не уверен на счет них), то уже не будет работать так просто.
https://ideone.com/YKEYEP

Ты можешь делать так, как тебе больше нравится, просто знай что можно делать, а что нельзя.
sage 412 1143249
>>43227
А вот тебе спасибо, пишешь лучше.
413 1143255
>>41364
>>41452
>>41859
Думаю превращение экземпляра класса PHP в JSONAPI объект нельзя назвать просто сериализацией, т.к. мы не только сериализуем класс, когда получаем JSON объект, но предварительно трансформируем класс в объект JSONAPI, например resourceObject, который в свою очередь имеет определенную структуру с обязательными свойствами. И обратная трансформация в большинстве случаев невозможна, т.к. resourceObject не содержит методов класса.

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


Мапер / мапирование норм слово для этого случая.
414 1143258
>>43224
Понял, брат. Здоровья тебе.
415 1143280
Плохо ли хранить JSON в SQL и если да, почему?
Я тут пришел джуниором в реальный проект с хайлоадом, и тут дохера чего в базе лежит джсоном. Например, если брать прикрепление файлов к посту. По методичке тебе нужна таблица files, где каждая строка хранит id поста. У нас же в таком случае просто в таблице posts будет поле files, а в нем json с массивом файлов. Это норм?
416 1143291
>>43280
Тоесть они хранят в базе, формат передачи данных для JS?

>У нас же в таком случае просто в таблице posts будет поле files, а в нем json с массивом файлов.


Это даже не говнокод, это уже клиника.
417 1143295
>>43291
JSON - это форматы передачи данных между приложениями. Он основан на JS, но может быть использован где угодно.
418 1143296
>>43280
Если не будет поиска по имени файлов или еще каким-то их параметрам, не нужно будет mysql с ними работать, вывести и все,
тогда норм.

Иначе избыточно получается.
419 1143298
>>43295
Я знаю что такое JSON.
Только фишка в том, что он предназначен для формирования из БД. ПРи хранении его в самой бд ты теряешь всю суть JSON, надо получить немного другие данные - хрен, надо изменить выборку - хрен, надо провести другой запрос отличный от задачи - хрен. Надо улучшить бд - хрен, надо решить новую задачу и добавить полей к базе - заново перелопачивать каждое поле.
420 1143300
>>43296
А потом все стоят и кумекают почему это хайлоап забивает 99% процессора, когда там всего-то неиндексированные имена файлов. Поэтому. Я вот удивляюсь кто в команду берёт людей на архитектуру приложений без знаний даже начальных по БД. И причём смысл то непонятен. Ну вот убрал он ID, а взамен что получил? Ничего же. Где профит то?
421 1143339
>>43247

>условий, операторы и прочее в твиг не завезли, да?


все завезли

>видишь ли хтымыло вместе с пшп, или видишь свой ебучий твиг?


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

и опять же я не предлагаю вводить новые ("новые" лол) технологии только ради того чтобы они были.

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

>Научите тут лучше людей классы писать


одно другому не мешает. изучение технологий - это такая же часть обучения, как изучение ООП

>работая над одним говносайтом


тут сидят не только те, для которых работа программистом - это работа с говносайтами

>в тред начинающих


и не только начинающие
422 1143345

>накручивают на него твиги и ебашат его через ГИТ, просто потомушто модно



это реально же смешно, это как бабка из того видоса "нам инторнет ваш нахуй не нужон!"
423 1143354
билядь опять промахнулся
>>43247
>>43345

>Научите тут лучше людей классы писать


я какбэ на такие вопросы тоже отвечаю
424 1143439
>>43280

>Плохо ли хранить JSON в SQL и если да, почему?


Если нет выборки по содержимому JSON, то хорошо, если есть такая выборка - то плохо. Потому что индексация.
425 1143441
>>43439
А если нет выборки, зачем вобще JSON в БД хранить? Можно запилить папку где всё это складировать и получить эдакую документоориентированную СУБД простейшую.
426 1143454
>>43248
Спасибо
427 1143559
>>43280
это сложный вопрос. возможно в вашем случае это экономит ресурсы. если, например, вы точно знаете, что никогда не нужно будет переформатировать этот жсон, добавлять туда что-то и т.д. тут лучше спросить у начальника, наверняка он знает причины.

субд то какая?

>У нас же в таком случае просто в таблице posts будет поле files, а в нем json с массивом файлов. Это норм?


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

>>43441
это тебя на такую мысль сподвиг анон любитель глобальных переменных?

зачем его хранить в бд - а зачем данные типа "текст" хранить в бд? странный вопрос. если они у тебя в базе, ты можешь:
1. подрубить к ним сфинкс в случае необходимости
2. перекатиться на другую субд
3. раскатать данные по разным шардам
4. обращаться к ним в рамках одного запроса к базе, без костылей. если ты используешь ОРМ, то вообще без вариантов
5. ограничивать права (это можно сделать и ограничением прав на папку, но там есть лазейки)
6. делать бэкапы теми же средствами, которыми ты бэкапишь бд

это первое что в голову пришло. а какие плюсы у твоего решения?
429 1143565
>>43559
>>43280

>возможно, это денормализация (второй вариант - просто всем похуй, что вряд ли в хайлоаде)



кстати третий вариант: всем раньше было похуй, а потом это стал хайлоад. обычно бывает как раз так
430 1143566
>>43559

>это денормализация


Тогда создаётся плоская таблица и в ней столбики.
431 1143569
>>43559
Ну опять же всё перечисленное можно сделать и без БД.

>6. делать бэкапы теми же средствами, которыми ты бэкапишь бд


Делать бэкапы вообще любыми средствами.
Ну хз я вообще не вижу преимужеств хранений JSON в БД. Какое-то извращение по моему.
432 1143571
>>43565
Обычно это бывает когда кто-то слишком "Хорошо" оптимизирует БД. И после этого простое приложение превращается в хайлоад.
433 1143581
>>43569
>>43559

Блин, я вообще сложно себе представляю именно запрос по которому нужно получить JSON именно из БД. Я привык к логике когда запос обрабатывается в бэке и потом бэк формирует JSON. А тут походу они получают миллиард JSON, или мудрят очень навороченные запросы чтобы получить что-то определённое. Опять же всё это даёт довольно большую нагрузку на сервер, на СУБД, на саму обработку запроса. Но при этом на формирование JSON сервер не тратит ресурсов. Или они просто отдают с десяток мегабайт JSON клиенту, а тот сам всё обрабатывает на своей стороне.
Вот хоть убей не вижу профитов такой схемы.
А в >>43559 ну хорошо, вот только опять же просто в полях хранить данные хранить проще же, и обслуживать проще, и редактировать. Я уже представляю как неверный запрос редактирования случайно редактирует пару сотен лишних ячеек. Короче какая-то странная архитектура если это не документо ориентированная БД.
434 1143592
>>43581

Вообще, такое иногда бывает нужно. Например, в файлообменнике мы собираем информацию о файле, которая бывает разная в зависимости от типа файла (длительность видео, битрейт, кодек, параметры кодека и тд). Ее удобно хранить как JSON, альтернатива - использовать EAV. Поля под нее делать неудобно, так как свойств может быть много, они сами по себе могут содержать массивы и тд.
435 1143596
>>43280

Я думаю, дело тут не в хайлоаде, а просто в лени. Из недостатков - поиск по имени файла сделать почти невозможно (в postgresql впрочем можно сделать индекс по отдельному полю JSON документа). Какие-то запросы (вроде найти посты с большим числом файлов) делать неудобно.
436 1143597
>>43592
А как потом собирать эту информацию? Ну вот например мне нужны все файлы MKV весом больше 5 метров и меньше 250. Я вижу тут только запрос через LIKE. И тут же я понимаю что это ведь довольно сильно даст нагрузки по СУБД. Или вот. Надо все JPG разрешением больше 4к, пережать. Как в таком случае редактировать уже занесённые данные?
437 1143599
>>43597

Вообще, в Postgres и в новой MySQL есть функции для разбора JSON, а postgres даже позволяет делать индексы по произвольным выражениям, в том числе по полю в JSON.
438 1143601
>>43569

>Ну опять же всё перечисленное можно сделать и без БД


только с костылями

>я вообще не вижу преимужеств хранений JSON в БД


если ты имеешь в виду "в сравнении с хранением их в файлах", то я тебе назвал шесть. а если про саму идею хранения данных сразу в json, то я согласен.

>>43581

>просто в полях хранить данные хранить проще же



я и не защищаю такую хуйню, просто пытаюсь восстановить логику событий
439 1143605
>>43441

Тут есть недостатки:

- отсутствие транзакций и блокировок, есть например риск что 2 процесса будут писать в один и тот же файл , или кто-то будет читать не до конца записанный файл
- отсутствие внешних ключей и проверок целостности
- база может быть на отдельном сервере, в случае с файлами тебе придется как-то это самому решать
- в базе есть индексы для ускорения поиска
- база позволяет получить какие-то данные через SQL. В случае с самодельной БД ты это не можешь сделать.

То есть я вообще плюсов не вижу. В чем они? Если тебе хочется хранить данные в файле, есть встраиваемая СУБД sqlite, которая именно это делает.

Пока просто ощущение, что анон думает, что написать свою БД будет быстрее, чем разобраться в уже написанной.
440 1143607
ОП, а как ты автоматизируешь деплой проекта?

допустим, у тебя есть локальный дев-сервер, приватный "главный" репозиторий на битбакете, куда ты пушишь изменения. какие средства используешь?
441 1143609
>>43607

Выше же было про деплой >>43223

Самый простой вариант - сделать bash скрипт и в нем написать команду обновления файлов из удаленного репозитория. Заходишь по ssh на сервер и выполняешь этот скрипт.
442 1143617
>>43242
бамп
443 1143636
>>43609

>


>Выше же было про деплой >>43223


я читал, поэтому и стало интересно, что именно ты используешь. я конечно имею в виду уже существующие решения. искал, нашел вот что:
https://deployer.org/docs/getting-started
как раз вариант простого скрипта, о котором ты говоришь. он занимается вопросами типа установки пакетов композера, нпм и т.д., блокировки проекта на момент обновления, но не решает (насколько я понял) с АВТОМАТИЧЕСКИМ обновлением, т.е. ты запушил - он спуллил.
https://www.phing.info/
тут честно говоря черт ногу сломит, но я так понимаю он умеет все

знаю еще есть варианты с teamcity и еще travis, но тимсити жрет ресурсы сервера, т.к. он там сидит в бэкграунде, а если ты снимаешь впс за 5 баксов, то это проблема, а травис платный для не опенсорс проектов.

>>Заходишь по ssh на сервер и выполняешь этот скрипт


вот этот процесс и хотелось бы автоматизировать (не заходить и не запускать каждый раз)
444 1143644
>>43636
Пихаешь в крон, ну сириосли, что за вопросы.

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

П.С Если влом курить баш (что зря), напиши ПХП скрипт.
445 1143662
>>43636

Ты можешь сделать репозиторий на том же сервере и настроить хуки, чтобы при пуше в него запускался деплой. Также можно установить какой-нибудь Jenkins и попробовать там настроить запуск деплоя при коммите.
446 1143663
>>43644
я чот сомневаюсь, что это типичный флоу - использовать крон вместо того, чтобы просто ловить вебхук, который шлет гит-сервер.

я перефразирую вопрос (хотя думал, что он достаточно понятно сформулирован): какими КОНКРЕТНО решениями пользуются аноны и почему?
447 1143668
>>43663
Эм...
https://gist.github.com/oodavid/1809044

Офф дока гита сойдет не?
448 1143669
По wordpress есть ветка или здесь спрашивать можно?
449 1143671
>>43663
бля, сорян, обосрался, то не офф дока.
Пойду выпилюсь
450 1143673
>>43662
>>43668
спасибо

>Офф дока гита сойдет не?


подойдет
451 1143724
>>43225

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



Да там примитив. Год назад работало, сейчас откопал и решил скопировать схему авторизации - а нихрена.
Код вида

extract($_POST);
if(isset($login) && isset($password)) {
if($login == 'условие' && $password == 'условие') {
header("Location:адрес.страницы");
setcookie("имя_кука", "true", time() + 3600247, "/", null, false, false);
}
else {
setcookie("имя_кука", "false");
header("Location:адрес_другой.страницы");
}
}
452 1143784
Как сделать так что бы команда break завершала цикл после достижения 0
453 1143795
>>43784
0 - это creditbalance?
if (creditbalance == 0)
break;
img21.jpg1,3 Мб, 1920x1200
454 1143875
ньюфаг в треде. Сразу пара вопросов про контору "Вектор"

1. Почему количество коффе,которое задается в условии для каждой профессии не является свойством? (так написано в подсказках)

2. Зачем нужно свойство "профессия" (так написано в подсказках)?

я только началл ООП и сильно плаваю не стукайте
455 1143907
Не совсем понимаю как в задаче про калькулятор, сделать так, чтобы выполнилось действие, которое находиться в переменной $op.
Только ли через if/else это можно сделать?
456 1143947
какой-то пиздос. этот гопник совместил паттерн пул объектов и синглетон и получился какой-то вырвиглазовый ужас:

<?php
/
Общий интерфейс пула одиночек
/
abstract class FactoryAbstract
{

/

@var array
/
protected static $instances = array();

/
Возвращает экземпляр класса, из которого вызван

@return static
/
public static function getInstance()
{
$className = static::getClassName();
if (!(self::$instances[$className] instanceof $className)) {
self::$instances[$className] = new $className();
}
return self::$instances[$className];
}

/

Удаляет экземпляр класса, из которого вызван

@return void
/
public static function removeInstance()
{
$className = static::getClassName();
if (array_key_exists($className, self::$instances)) {
unset(self::$instances[$className]);
}
}

/
Возвращает имя экземпляра класса

@return string
/
final protected static function getClassName()
{
return get_called_class();
}

/

Конструктор закрыт
/
protected function __construct()
{
}

/
Клонирование запрещено
/
final protected function __clone()
{
}

/

Сериализация запрещена
/
final protected function __sleep()
{
}

/
Десериализация запрещена
/
final protected function __wakeup()
{
}
}

/

Интерфейс пула одиночек
/
abstract class Factory extends FactoryAbstract
{

/
Возвращает экземпляр класса, из которого вызван

@return static
/
final public static function getInstance()
{
return parent::getInstance();
}

/

Удаляет экземпляр класса, из которого вызван

@return void
/
final public static function removeInstance()
{
parent::removeInstance();
}
}

/
=====================================
USING OF MULTITON
=====================================
/

/
Первый одиночка
/
class FirstProduct extends Factory
{
public $a = [];
}

/

Второй одиночка
*/
class SecondProduct extends FirstProduct
{
}

// Заполняем свойства одиночек
FirstProduct::getInstance()->a[] = 1;
SecondProduct::getInstance()->a[] = 2;
FirstProduct::getInstance()->a[] = 3;
SecondProduct::getInstance()->a[] = 4;

print_r(FirstProduct::getInstance()->a);
// array(1, 3)
print_r(SecondProduct::getInstance()->a);
// array(2, 4)
456 1143947
какой-то пиздос. этот гопник совместил паттерн пул объектов и синглетон и получился какой-то вырвиглазовый ужас:

<?php
/
Общий интерфейс пула одиночек
/
abstract class FactoryAbstract
{

/

@var array
/
protected static $instances = array();

/
Возвращает экземпляр класса, из которого вызван

@return static
/
public static function getInstance()
{
$className = static::getClassName();
if (!(self::$instances[$className] instanceof $className)) {
self::$instances[$className] = new $className();
}
return self::$instances[$className];
}

/

Удаляет экземпляр класса, из которого вызван

@return void
/
public static function removeInstance()
{
$className = static::getClassName();
if (array_key_exists($className, self::$instances)) {
unset(self::$instances[$className]);
}
}

/
Возвращает имя экземпляра класса

@return string
/
final protected static function getClassName()
{
return get_called_class();
}

/

Конструктор закрыт
/
protected function __construct()
{
}

/
Клонирование запрещено
/
final protected function __clone()
{
}

/

Сериализация запрещена
/
final protected function __sleep()
{
}

/
Десериализация запрещена
/
final protected function __wakeup()
{
}
}

/

Интерфейс пула одиночек
/
abstract class Factory extends FactoryAbstract
{

/
Возвращает экземпляр класса, из которого вызван

@return static
/
final public static function getInstance()
{
return parent::getInstance();
}

/

Удаляет экземпляр класса, из которого вызван

@return void
/
final public static function removeInstance()
{
parent::removeInstance();
}
}

/
=====================================
USING OF MULTITON
=====================================
/

/
Первый одиночка
/
class FirstProduct extends Factory
{
public $a = [];
}

/

Второй одиночка
*/
class SecondProduct extends FirstProduct
{
}

// Заполняем свойства одиночек
FirstProduct::getInstance()->a[] = 1;
SecondProduct::getInstance()->a[] = 2;
FirstProduct::getInstance()->a[] = 3;
SecondProduct::getInstance()->a[] = 4;

print_r(FirstProduct::getInstance()->a);
// array(1, 3)
print_r(SecondProduct::getInstance()->a);
// array(2, 4)
457 1144020
>>43228

>Есть 3 паттерна наследования: Single Table Inheritance, Concrete Table Inheritance, Class table inheritance - погугли их для начала и потом задай вопрос, если непонятно.


В общем почитал я про них, как я понял единого верного варианта нет. Я могу просто прикинуть что расширяющих файл сущностей у меня будет точно не много (изображение, аудио, видео), и использовать одну общую таблицу. Хотя более логичным мне кажется использовать паттерн одна сущность - одна таблица без явных связей с другими таблицами(Concrete Table Inheritance), ведь объект полностью имеет поля своего предка, и раз в бд нельзя провернуть наследование, то может оно и не нужно? Хотя говорю я это без опыта работы с любыми орм и паттернами бд, на практике хз как выйдет.

И у меня еще вопрос по поводу хранения файлов. Я правильно понимаю что в бд я записываю путь к файлу, который лежит на диске, а потом при отправке пишу нужные заголовки и вставляю туда же путь к файлуу слима вроде обёртка есть для переменной _FILES,
но я в подробности не вникал
, и он оп и отправился?
458 1144022
Сап.
Друзья, вопрос...
Есть верстка сайта школы стилистов. На одной из страниц выводятся все курсы с кнопкой "Узнать подробнее", при нажатии на которую, открывается страница с подробной информацией об этом курсе.

Нужно сделать такую админ панель, где будет страница с полями "Название курса", "Дата", "Изображение курса" и т.п. Человек заполняет все нужные поля и нажимает на кнопку добавить. И на страничке курсов появляется этот курс. Можно как-то по-другому это реализовать, но главное чтобы сократить работу с кодом к минимуму.
Первый опыт с сайтом, не знаю куда двигаться.

Конечно, я могу наклепать таблицы, написать PHP код, сверстать быстренько админ панель. Но я боюсь это делать, потому что опыта то нет.. Будут проблемы с безопасностью, как-то криво будет работать..

Сейчас взялся за ModX, как я понимаю, с помощью него я смогу все это реализовать. Но возможно есть более лучшее решение этой ситуации для новичка?

Спасибо, очень жду ответа, потому что время поджимает...
459 1144074
Учите симфони, битрикс это пиздец.
460 1144089
Как реализовать роутинг на мапах или деревьях? Во всех статьях что находил только на регулярках.
461 1144090
>>44074
Работу не найти по симфоне. На битрикс дофига вакансий. А если с английским разговорным плохо, то вообще не найти симфони.
462 1144091
>>44089
лол, подставляешь в качестве ключа, название роута, а в качестве значения, либо функцию которая открывает тебе твой контроллер, либо другой массив с ключами других роутов.
463 1144098
>>44090
Коллега устроился на 15к на первый месяц наработал стаж - год и ушел из этой конторы в другую на 50к. Вышки у него нет.
464 1144099
>>44098
Такое только до 2010 прокатывало. Сейчас такого простого вката нету, только битрикс, край вп.
SaturdayEveningPuss-Lightning,ButchandTopsy.png372 Кб, 640x480
465 1144119
Сап обучающий. Хочу сделать сайт среднего функционала в качестве хобби. Сайт этот никуда не пойдет, буду делать фор фан. Хочу использовать php движок, раньше были DLE и Joomla! в связи с этим интересуюсь появилось ли чегонибудь интересного в этой сфере, конкретно движки. Гуглить пробовал, но интересует Ваше мнение.
466 1144122
>>44091
Если по твоему это так просто, то почему статей нет, почему все пишут на регулярках? А на деревьях знаешь как сделать?
467 1144126
>>44098
Это в каких-таких Мухосрансках нет симфони?

Симфони ща в любой дырке затычка:
Ларавель - юзает библиотеки Симфони
Друпал 8 - юзает компоненты Симфони

Тем более Симфони, это автоматически юзание композера.. Со знанием Композера заехать в тот же YII2 вообще на изи.

Даже в моей ебучей провинции 3-4 ваканчии в пару месяцев появляется. Какой нахой Битрикс.
Битрикс программист вообще не программист а собиратель говна и палок, чтобы клеить костыли.
Нм одна блять здравая контора не возьмет Битрикс как основу для проекта выше обычного.
Интеграция с Адинэс из коробки (единственный плюс Битрикса) не является сколь либо сложно задачей для имея на руках библиотеку уровня Симфони/ЮаЙаЙ
468 1144131
В этом задании
https://phpclub.tech/pr/chain/1108694/
Тут просто надо методы прописать и параметры объектов? Или надо еще указать как взаимодействуют объекты между собой? Надо ли подключить базу и как то настроить все?
469 1144144
>>44126
Какая разница кто что юзает, причем тут композиры?

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

В битрикс вкатываешься стажером и все. Хотя постепенно битрикс тоже переходит такую модель, как брать только опытных с 1-3 года опыта. Становится труднее вкатится, но все еще можно.

>Битрикс программист вообще не программист а собиратель говна и палок, чтобы клеить костыли.


Зависит от тебя, если ты собираешь говно и палки, то это не проблема битрикса, там много чего приходится дописывать, никто же не заставляет говнокодить, но ты же не можешь не говнокодить без симфониларавель, да?

>Нм одна блять здравая контора не возьмет Битрикс как основу для проекта выше обычного.


Кекаю с наркомана. Берут как миленькие. Тебя что в интернет не пускают?

Ты в какой провинции живешь? Квебек? В провинция ойти вообще нету. Одни 1с и битриксоиды. А если и появляется то надо чтоб в мухосрани ты откуда то получил опыт в 3 - 5 лет чтобы взяли.

Насмешил меня, спасибо.
470 1144154
>>44144

>Какая разница кто что юзает, причем тут композиры?


>Вопрос в другом, каких контор больше, битрикс клепальщиков или симфони ковыряльщиков и куда вкатиться проще.


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

>В битрикс вкатываешься стажером и все. Хотя постепенно битрикс тоже переходит такую модель, как брать только опытных с 1-3 года опыта. Становится труднее вкатится, но все еще можно.


В крупных компаниях есть Trainee, есть фриланцы и т.д. было бы желание

>Зависит от тебя, если ты собираешь говно и палки, то это не проблема битрикса, там много чего приходится дописывать, никто же не заставляет говнокодить, но ты же не можешь не говнокодить без симфониларавель, да?


Предпочитаю не забивать гвозди утюгом. А вы?

>Ты в какой провинции живешь? Квебек? В провинция ойти вообще нету. Одни 1с и битриксоиды. А если и появляется то надо чтоб в мухосрани ты откуда то получил опыт в 3 - 5 лет чтобы взяли.



Хохлостанская южная мухосрань. У нас тут около 15 компаний в городе. Есть такие же битрикс-клепальщики, есть малые стартапы за доширак и опыт, если филиалы крупных компаний типа ДатаАрта. Короче на любой вкус.

Плюс опять же никто не отменял удаленку.

На серьезных щщах реально втирать что Битрикс тру - ну это пиздец. Есть задачи, для которых он хорош (тот же 1С), и дядя доволен что сайт быстро заработал и за десять тыщь - но в целом это тупиковая ветка если есть желание уйти куда в хай лоад или биг дату со временем.
471 1144163
>>44154

>Хохлостанская


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

>мухосрань


>15 компаний


Ну ну, мухосрань, конечно.

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

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

>Предпочитаю не забивать гвозди утюгом. А вы?


К чему это сказано? Тебе наверное непонятен смысл этой фразы. Битрикс очень даже по назначению применяют, как ты ниже сам заметил. А то что тебе придется писать, какой либо сервис для интеграции с каким либо апи или бизнес логику клиента, так оно тебе и на симфони придется писать.

>На серьезных щщах реально втирать что Битрикс тру - ну это пиздец.


>Есть задачи, для которых он хорош (тот же 1С), и дядя доволен что сайт быстро заработал и за десять тыщь


Ты либо трусы одень, либо крестик сними.

Смысл бесполезного хейта битрикса? Тебе говорят как есть, причем в другой стране, ты говоришь да как такто, у нас же все так. Никто не спорит, что есть у него свои недостатки. Но нету выбора, по описаным выше причинам.
472 1144180
>>44074
Добавлю, что если и вкатываетесь, начиная с битрикса, то лучше, когда вы будете работать над проектом в команде, а не в одиночку.
473 1144193
>>44090
работу на битриксе не найти. в макдаке дофига вакансий.

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

когда я последний раз смотрел работу на хх, там было 300 вакансий со словом "симфони" и из них 50 по удаленке. это меньше, чем на битриксе, но и специалистов меньше.

>>44144

>Зависит от тебя, если ты собираешь говно и палки, то это не проблема битрикса


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

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

https://habrahabr.ru/post/282333/ вот есть статья, объясняющая, почему говнокод в битриксе - это проблема битрикса.

>В провинция ойти вообще нету. Одни 1с и битриксоиды.


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

>>44163

>Но нету выбора, по описаным выше причинам.


по причинам "незнания разговорного английского" лол?

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

>>44154

>это тупиковая ветка если есть желание уйти куда в хай лоад или биг дату со временем


я работал в конторе, которая начинала с битрикса и потом продукт стал хайлоадом. это боль, конечно.
473 1144193
>>44090
работу на битриксе не найти. в макдаке дофига вакансий.

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

когда я последний раз смотрел работу на хх, там было 300 вакансий со словом "симфони" и из них 50 по удаленке. это меньше, чем на битриксе, но и специалистов меньше.

>>44144

>Зависит от тебя, если ты собираешь говно и палки, то это не проблема битрикса


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

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

https://habrahabr.ru/post/282333/ вот есть статья, объясняющая, почему говнокод в битриксе - это проблема битрикса.

>В провинция ойти вообще нету. Одни 1с и битриксоиды.


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

>>44163

>Но нету выбора, по описаным выше причинам.


по причинам "незнания разговорного английского" лол?

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

>>44154

>это тупиковая ветка если есть желание уйти куда в хай лоад или биг дату со временем


я работал в конторе, которая начинала с битрикса и потом продукт стал хайлоадом. это боль, конечно.
474 1144196
да, щас перечитал статью про битрикс и вспомнил код моей предыдущей конторы, где каждый файл и каждый метод начинался с
global $DB, $USER;

бррр
475 1144197
>>44163

>Смысл бесполезного хейта битрикса?


смысл защищать битрикс? если перестанешь его защищать и станешь ненавидеть как все, то со временем перекатишься на нормальный фреймворк. необязательно симфони, хоть на yii. на yii дохера работы в провинциях же.
476 1144202
>>44119
на друпал обрати внимание.
477 1144208
>>44022
вообще, это достаточно объемная задача, если ты раньше такого не делал. человек, который этим уже занимался и владеет инструментами, сделает такую задачу за рабочий день спокойно. а если ты не делал, это может занять от дня до нескольких недель.

у тебя три варианта:
1. написать все с нуля на голом пхп. это не варик для продакшна, так делают только в учебных целях
2. взять фреймворк, тот же Симфони и там уже есть необходимые решения - doctrine, security, easyadminbundle. но нужна какая-то база, чтобы те же сущности ОРМ правильно выстроить.
3. взять CMS: drupal, wodrpress или любой другой. думаю, для тебя это самый быстрый путь, но там тоже придется покопаться.

вот еще есть http://cmf.symfony.com/ но я не могу его рекомендовать, т.к. сам не пользовался. по презентации http://cmf.symfony.com/slides/why_symfony_cmf.html понял, что это что-то среднее между друпалом и симфони. может другие аноны подскажут по нему
478 1144222
>>44074
Мне недавно прилетел заказ на 500 рублей (мой первый заказ лол), допилить форму продажи, допилить загрузку фоток, и сделать им превьюшки. В общем до этого ковырялся я в пхп пару месяцев и буквально на базовом уровне знал html и css, ну думаю ща тут все раскидаю на изи. Открываю я этот битрикс, нихуя не понимаю, какая-то статистика скорости сайта, предлагают прям там пройти какие-то тесты блять, десять тыщь папок, шаблоны страниц в одной папке, заголовки и футеры в другой, стили в третей, оче сложная навигация, потом оказалось что у чувака сайт сверстан на таблицах, я об этом только читал на самом деле, а сейчас сам столкнулся, ну я не растерялся и ебанул таблицу в таблицу(так нужно было). Потом я еще пол дня ебался с джаваскриптом, так как до этого его не трогал вообще, но в итоге всё сделал, все довольны, лол. Пхп так и не трогал. Короче ковыряться в этом говне не вызвало у меня никаких положительных эмоций. Буду дальше пинать фреймворки и созидать.
479 1144255
>>44197
Дело не в защите, плохому програмисту, всегда другие программисты мешают. Это актуально и для фреймворков.

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


Вуду магия какая то.
480 1144256
>>44222

>нихуя не понимаю


А если бы прилетел ларавели, ну или на друпале или вукомерце, ты бы сразу познал дзен?
481 1144258
>>44131

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

В случае Агенства - достаточно просто написать названия классов, полей и методов в них. Весь код писать не надо, проверяются только навыки проектирования.
482 1144271
>>44255

>Дело не в защите, плохому програмисту, всегда другие программисты мешают. Это актуально и для фреймворков.


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

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

это как таксист будет говорить "мне похуй на чем бомбить, на камри или на классике - это всего лишь инструменты".
483 1144272
>>44256
то не взял бы такой заказ, лол
484 1144279
>>44271

>не понял твою мысль


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

Про специализацию, это само собой. Я сейчас про вкатывальщиков и начинающих, у которых в мухосрани просто нет выбора. Да и в дсах, можно прождать вакансию для вкатывающегося от года и больше.
485 1144286
>>44279
Дело не только в коде, битрикс может вести себя непредсказуемо и это бесит. Второе: из коробки в битриcке есть много всего, но используется из этого далеко не все. Вот нахуя мне столько полей в инфоблоке? Это как пример. Я не работал с современным фреймворком, но мне кажется, что используя фреймворк ты используешь только те компоненты, которые тебе действительно нужны.
486 1144291
>>44286
Как может код вести себя непредсказуемо? Или в фреймворках, какой то пхп, что там все предсказуемо?
В фреймворках тоже всего много, например различия ларавель или слим. Мне тоже много всего ларавельного не надо. Это не основание говорить, что это плохой фреймворк.
Мне кажется ты можешь использовать те поля, которые действительно тебе нужны?
487 1144310
>>44291
Помню, как не мог понять, почему 404 при переходе на страницу новости. Дело было в том, что нужно было в настройке компонента убрать галочку и поставить ее снова. Два клика мышью у одного и того же чекбокса. Ебля с кэшированием. Разворот локальной версии - access denied, ок, поменял в базе имя хоста на локальный.
488 1144313
>>44291

>Мне кажется ты можешь использовать те поля, которые действительно тебе нужны?



А потом заказчик спрашивает, почему все так тормозит
489 1144320
>>44279
с битриксом наверное можно написать хороший код, но это сложно по трем причинам:
1. битрикс не способствует быстрому профессиональному росту
2. битрикс поощрает плохие практики
3. (самое главное) в конторах, где используют битрикс, обычно на хороший код кладут хер. думаю, ты с этим сам согласишься

>Так и плохой спец взяв фреймворк, все равно будет лепить код как может


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

>у которых в мухосрани просто нет выбора


вменяемые курсы, фриланс, релокацию ты за вариант не считаешь. тогда да

>Да и в дсах, можно прождать вакансию для вкатывающегося от года и больше


ну нет конечно. в дс1 можно сегодня устроиться, а завтра выйти на 30к. я даже могу подсказать места, лол
490 1144321
>>44313
Отвечаешь ему честно, причем тут ты то? Алсо, при отсутствии каких либо особых хотелок, кэш вполне вытягивает. Так что попробуй еще.
491 1144324
>>44286

>используя фреймворк ты используешь только те компоненты, которые тебе действительно нужны


если он компонентный, то да

>>44291

>Мне тоже много всего ларавельного не надо


в симфони 4 ты ставишь symfony/skeleton и там по дефолту только самый минимум компонентов. нет ни профайлера, ни твига, ничего. все ставишь по желанию
492 1144325
>>44310
Ну не понимание, как работает система, с которой ты работаешь, конечно же затрудняет работу.
Да и отсутствие настроенного деплоя, так же мешает.
Тут уж надо самом с этим что то делать.
Битрикс хоть и предлагает свою систему развертывания, никто ей не пользуется, так как быстрее самому сделать.
493 1144328
>>44324

>в симфони 4


А заказчик хочит ларавель, поэтому что эта модна.
То есть теперь мне надо начать ненавидеть ларавель, чтобы перейти на "нормальный фреймворк"?
494 1144330
>>44328
ну нет, не надо его ненавидеть. ларавел тоже пиздатый, просто я его плохо знаю, чтобы что-то в нем советовать
495 1144340
>>44320
Все сказанное про битрикс верно, если ты попал в плохую контору, где нету хороших спецов. Актуально так же для любого другого фреймворка языка. Я как то давно легаси на кодигнайтере поддерживал. Контроллер или модель на 5-7к строк, вполне имело место быть.
Отличие от битрикса было лишь в том, что битрикс со своими компонентами на 5к строк, а тут контроллеры на столько же.

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

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

>вменяемые курсы


Например? В мухосрани потом приди и скажи, что курсы прошел. Над тобой посмеются дружно всем офисом.

>фриланс


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

>релокацию


Кому вкатывальщик без опыта нужен?
Да и с опытом, переехать в другой город, помогают не так уж и много компаний. Если ты средний спец, вряд ли стоит ожидать. Был бы опытным и топовым спецом, давно бы уже пробовал за границу уехать.
sage 496 1144349
Нихуя себе у вас тут холивар простынями, аж с нулевой видно.
497 1144376
Есть тут люди которые работали с woocommerce через rest api? Могут ли клиенты у которых нет доступа в админку для генерации ключей (consumer_key, consumer_secret) логиниться/смотреть списки товаров/покупать?
Ключи ведь привязаны к конкретным юзерам но в документации я не нашел ничего о том, как сгенерировать ключ юзера через API. Такое впечатление, что их API это чисто для юзеров с доступом в админку
498 1144393
>>44340

>если ты попал в плохую контору, где нету хороших спецов


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

>отдавай предпочтения конторе, которая строит бизнес вокруг своего сайта


это 100%

>Например? В мухосрани потом приди и скажи, что курсы прошел


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

>С нуля во фриланс, это самоубийство


ну мб

>Кому вкатывальщик без опыта нужен?


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

Короче надо поправить форму обратной связи на лендосе и захотелось это сделать на локальном серве. Какая сейчас прога есть для этого или онлайн песочница чтобы по быстрому скормить этому всем html-css-js-php файлы и оно фурычило? Может какой-то аналог codepen jsfidle?

Алсо на компе стоит Денвер но я его год где-то не трогал, лол. Может что-то попроще есть для такой просто задачи?
501 1144441
>>43875
Ты по какому мануалу делаешь? В подсказках предлагают сделать профессии классами
502 1144449
А задачу на файлообменник можно на mysql сделать, или все же postgres лучше будет?
503 1144452
>>44449

Можно на любой СУБД. Я бы советовал брать ту, с которой раньше не работал - чтобы расширить кругозор. Если ни с одной не работал, то можно взять postgres.
504 1144465
Пацаны что скажете на счёт codecourse.com ?
Гайды выглядят очень годно и подписка вроде не дорогая. Не понимаю правда что мешает мне за месяц скачать все курсы.
https://www.codecourse.com/lessons/build-your-own-realtime-php-server/2223
505 1144469
Сука как же у меня горит от вордпресса.....
506 1144470
>>44469
А что с тобой случилось?
507 1144471
>>44470
Человеку сделал "фронтендер" на WPBakery Page Builder сайт для крипто-валют без оптимизации, на половину кривой. а я его второй день правлю и ахуеваю.

В конце спрошу сколько он "фронтендеру" отдал чтобы еще раз ахуеть.
508 1144475
>>43597

>А как потом собирать эту информацию?


Если требуется только показывать её юзеру, то и не надо ничего собирать. А жсон в этом случае используется для удобства обработки жаваскриптом, например. Если когда-нибудь потребуется выборка, тогда и изменят схему БД и распихают жсон по табличкам, это не проблема.
509 1144484
>>44471
А причем тут вп? Это же какой то бакерибулдер, и фронтендер сделали. Считай ты ему полсайта сделал.
Безымянный.jpg120 Кб, 1538x596
510 1144568
Почему не отправляется(или не принимается?) post запрос?
С action="register.php" пробовал, так же бесполезно.
511 1144569
>>43242
бамп
512 1144575
>>44568

А что ты делаешь? Я просто виду на скриншоте точку останова (или что значит красный кружок) и пытаюсь понять, что ты делал.
Безымянный.png56 Кб, 1221x215
513 1144580
>>44575
Да то я случайно тыкнул.
Я пытаюсь отправить пост запрос на эту же страницу.
В хроме просто ничего не происходит, в фаерфоксе после отправки (значит, пост запрос все таки отправляет?) вот такая вот херня
Безымянный.jpg198 Кб, 1641x896
514 1144583
>>44580
upd
Если что-то покажет.
515 1144589
>>44583
ну у тебя где этот register.php лежит?
у тебя форма должна слать запрос этому файлу именно.

если у тебя обработчик лежит в /htdocs/shop/register.php

то и в форме напиши action="/htdocs/shop/register.php"
516 1144590
>>44580

Ну вот так и надо было писать:

- открываю такую-то страницу с таким-то URL
- ввожу в форму то-то и то-то
- жму такую-то кнопку
- вижу ошибку 404 и такой-то URL

А ты можешь сравнить URL в адресной строке, когда ты просто открываешь форму в браузере и она видна, и URL при отправке формы?

Я помню, что несколько месяцев назад анон писал про такую же проблему. и мне кажется, что дело может быть в шторме. У тебя наверно установлен PHP, ты не мог бы попробовать запустить встроенный в него сервер и открыть в браузере страницу через него? Это описано тут и потребует немного возни с командной строкой: https://github.com/codedokode/pasta/blob/master/soft/web-server.md#Встроенный-в-php-сервер

Пока моя версия - у встроенного в Шторм веб-сервера какие-то проблемы с обработкой POST запросов.

Тут пишут что $_POST приходит пустым. https://intellij-support.jetbrains.com/hc/en-us/community/posts/115000097930-Can-not-use-POST-method-in-PhpStorm

Тут пишут ( https://stackoverflow.com/questions/34785913/phpstorm-10-0-3-error-502-bad-gateway-due-to-javavm/34787827#34787827 ), что можно проверить логи phpstorm ( PHPstorm/Help/Show Log in Explorer ) - попробуй глянуть, что там?
Безымянный.jpg290 Кб, 1721x1453
517 1144592
>>44589
Хоть так, хоть эдак не работает.
518 1144594
Вопрос по папке var/cache в Symfony4. По правам к ней, точнее.

Я корректно понимаю принцип работы на проде? Мы запускаем cache:clear (создается папка prod от имени нашего пользователя, права 755) и далее не позволяем системе создавать свои скомпилированные файлы в эту папку (она этого все равно сделать не сможет, т.к. пользователь у нее www-data), а создаем их сами, прогревая кеш? Тогда они создаются от имени нашего пользователя и все заебись.

То есть вопрос в том, что правильно ли я понимаю, что без прогрева не надо вообще на проде ничего менять?
Безымянный.jpg202 Кб, 1655x742
519 1144595
>>44590

>Ну вот так и надо было писать:


Сорри, туплю :-(

>ты можешь сравнить URL в адресной строке, когда ты просто открываешь форму в браузере и она видна, и URL при отправке формы?


Пикрелейтед оно?

>попробуй глянуть, что там?


2018-02-23 00:12:31,898 [30225280] INFO - ide.actions.ShowFilePathAction -
Exit code 1

>Это описано тут и потребует немного возни с командной строкой


Сейчас попробую
520 1144597
Вдогонку еще вопрос по правам в Симфони4.

вот тут http://symfony.com/doc/current/setup/file_permissions.html написано:

>If you decide to store log files on disk, you will need to make sure your logs directory (e.g. var/log/) is writable by your web server user and terminal user. One way this can be done is by using chmod -R 777 var/log/. Just be aware that your logs are readable by any user on your production system.



То есть один способ такой (топорный), а какие есть еще?
Я пока придумал только дать на папку права допустим 770, в кач-ве владельца поставить нашего terminal user и включить пользователя www-data в группу terminal user. Или создать им какую-то общую группу и поставить ее в кач-ве группы для этой папки.

Может есть какие-то еще более изящные варианты?
521 1144598
>>44590

>ока моя версия - у встроенного в Шторм веб-сервера какие-то проблемы с обработкой POST запросов


Да, ты прав.
Вышел из шторма, запустил через хампп - и все заработало.
Столько времени и нервов убил, печаль :-/

Спасибо большое.
522 1144599
>>44594

Не уверен. По задумке да, на проде кеш генерируется из cli при деплое. Но я гарантировать, что симфони не захочет что-то записать в кеш, не могу. Ну например, там есть кеш для результата разбора DQL запросов (в доктрине) - по умолчанию вроде используется apcu, но кто знает, какие у тебя могут быть настройки. И какие там еще могут быть кеши.

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

>>44595

Если URL одинаковый (а это вроде так), то проблема в встроенном в шторм сервере, он не работает с POST запрросами. Нужно освоить встроенный в PHP сервер (проще всего), либо Апач, либо nginx + php-fpm.
523 1144600
>>44597

Простой вариант - запускать веб-сервер от того же юзера, что и используется в cli. Но тут минус: что, если разработчиков больше одного? Да и не хочется серверу давать доступ к своим файлам.

Можно тогда попробовать взять всех разработчиков + создать пользователя-веб-сервера и объединить их в группу. Сделать ее основной для пользователя-веб-сервера (чтобы создаваемые им файлы получали ее). Сделать chown на эту группу для всех файлов. Дать полный доступ к файлам участникам группы.

Подвох: если у кого-то из разработчиков эта группа не основная, то у создаваемых им файлов будет другая группа и веб-сервер и другие разработчики не получат к ней доступ.

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

Подвох: по умолчанию umask = 022 и надо его поменять на 002 иначе создаваемые файлы и папки будут иметь права rx для группы, а не rwx.

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

То есть, если подытожить:

- либо использовать всем одного пользователя
- либо сделать группу
- либо сделать группу и использовать ACL для гибкой настройки.

> Я пока придумал только дать на папку права допустим 770, в кач-ве владельца поставить нашего terminal user и включить пользователя www-data в группу terminal user.



Надо еще выставить корректный umask (почитай что это) иначе сервер будет создавать файлы и папки с правами rx без w для группы. То же касается и твоего пользователя.
изображение.png38 Кб, 1072x332
524 1144610
>>44592
ты сам то можешь вызывать этот файл через адресную строку?

Не когда ты с формы на него шлешь. А как тут >>44568
левом куске скрина? Что-то у тебя не так с доступом, либо с путями.

Вот пикрил ты как получил? Что при этом в адресной сроке:?
525 1144612
>>44610

Погугли по теме phpstorm builtin server POST - много информации про плохую поддержку встроенным в PhpStorm сервером метода POST. Скорее всего дело в этом.
526 1144614
Авторизация и регистрация редиректом по страницам еще допускается, или уже не модна и надо мучаться переделывая на ajax+ jquery(которые я не знаю по сути)?
>>44610
Дело было в шторме, через апач все корректно работает.
527 1144647
>>44475
Ты вопрос то читал вообще?
528 1144648
>>44475

>и не надо ничего собирать


Ага, симс легит. Просто отдал юзеру пару миллиардов JSON записей. Это ты имел ввиду?
529 1144653
>>44648
Предварительно всё это завернув в массив. Который завернул в JSON. И закешировал запрос. А потом сохранил его в БД. Не проиндексировав. Или вообще создал новую БД под каждый запрос. Каеф.
530 1144655
Уже скоро 100 тред.
Я тут с 1 треда и до сих пор не смог сделать задачу про айфон в кредит.
ОП мне стоит вообще продолжать пытаться в программирование?
531 1144693
>>44655
Толстота. Не понимаю чего там сложного.
533 1144716
>>44701
ну ты спрашивай что непонятно
534 1144720
>>44716
какой альтернативный язык программирования посоветуешь? PHP пока сложноват для меня. Планирую начать с чего-то более фундаментального.
535 1144724
536 1144727
>>44720
Что-то более фундаментальное - это машина Тьюринга, алгоритмы Маркова, Си, Scheme.
537 1144728
>>44720
CS50 пройди для начала. Там даже для таких даунов как я было всё понятно.
538 1144730
>>44724
реально? он де устарел давно. нам его в универе давали на 1 курсе 5 лет назад. он уже тогда был древним
539 1144733
>>44730
Он может не подходить для некоторых сфер, но устарела в языке C++ только часть.

>нам его в универе давали


Вам его в универе давали в виде Си с классами версии 98 года.
540 1144738
>>44730

>нам его в универе давали на 1 курсе 5 лет назад.


Это показатель какой-то? Или что? Ну вон пиши на расте тогда. Ему около года всего. Правда область применения мизерная и вакансий 15 на весь мир.
541 1144740
>>44600
спасибо!

>Подвох: по умолчанию umask = 022


в принципе тут и кроется решение моей проблемы.
542 1144742
>>44720

>PHP сложноват


>начать с чего-то более фундаментального



смотри, обычно фундаментальный = более сложный
543 1144746
>>44742
Сложный в использовании но простой в понимании. Мне важно понимать то, что я использую.
т. другой анон
544 1144747
>>44733

>в виде Си с классами версии 98 года


Который является фактически лучшей версией плюсов
545 1144748
>>44720
Всегда python как первый язык. С ним ты сможешь пощупать 90% программирования кроме серьёзной графики разве что
546 1144758
>>44746
питон. но он не проще
547 1144759
>>44747
По версии анонима с джвача? Самой короткой - разумеется, лучшей - нет.
548 1144762
>>44759
Еще лучше если мы говорим о просто Си. Но 98 на мой взгляд - необходимое зло. Везде где юзаюся фичи 11 + стандартов разумнее использовать другой язык
549 1144806
>>44475

С переносом данных из JSON в таблицы скорее всего будут сложности, так как никто к тому моменту не будет помнить схему JSON данных (какие в них есть поля и для чего) и придется все это мучительно выяснять анализом кода.

>>44724

До C++ надо выучить Си.

>>44720

В каком смысле фундаментального? Если тебе интересны низкоуровневые детали, то надо почитать как устроен процессор и учить ассемблер (только не учи древний 16-битный досовский - учи хотя бы 32-, а лучше 64-битный). Скорее всего, на ассемблере тебе писать ничего не придется, но ты будешь понимать, как программа выполняется на процессоре.

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

Но это не проще PHP. Это будет сложнее. И потребует время. И зарабатывать этим ты вряд ли сможешь.

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

>>44727

Машина Тьюринга - это модель для математических доказательств и в изучении программирования не поможет.

>>44730

Его используют там, где нужна высокая производительность, а также в десктопных программах с окошечками. Хром, Openoffice на нем написаны например.
550 1145073
Может ктото написать для примера консольную программу на пхп.

Просьба ввести имя, потом возраст. После чего на экран выведется "Привет аноннейм, тебе 12 лет".
1111.PNG4 Кб, 293x137
551 1145079
>>45073
Разобрался вроде. Но может кто пояснить, что происходит если я ввожу не латиницу? Почему оно второй раз не просит ввода второй раз(возраст)? А после имени сразу вываливает последний echo с пустыми значениями в переменных $name и $age
552 1145082
>>45079

Что происходит при вводе "нелатинницы" зависит от используемых ОС, настроек ОС и кодировки скрипта.

В линуксе и маке по умолчанию консоль передает программе и отображает на экране данные в кодировке utf-8. Если скрипт написан в utf-8, то он будет работать с любыми символами любых алфавитов. Если не в utf-8 - то надписи из скрипта будут выводиться криво. Подробнее

- https://github.com/codedokode/pasta/blob/master/php/strings-utf8.md
- совсем подробно, объясняя с нуля https://github.com/codedokode/pasta/blob/master/cs/strings.md

Если ты используешь винду, то придется страдать. Виндовая консоль в русской версии использует по умолчанию 8-битную кодировку cp1251, и значит ты должен либо писать скрипт в cp1251 (плохо, плюс не все функции ее будут поддерживать), либо кириллица не будет отображаться.

Винда + cygwin кстати иногда умеет отображать utf-8 в консоли.
553 1145083
>>45079

Еще один вариант, если ты под виндой, то можно писать программу в utf-8, но конвертировать все вводимые и выводимые данные в/из cp1251.

Причем обрати внимание, что cp1251 используется в консоли только в русской версии винды. Если твою программу запустить на другой версии винды, то кирилица не будет отображаться.
554 1145084
>>45079

А, я ошибся. В винде в консоли по умолчанию может еще быть cp866. Не знаю, от чего это зависит, есть консольная команда chcp для ее переключения. На utf-8 переключить нельзя.

Проверить кодировку можно, набрав например такую команду

php -r "echo chr(253); echo '\n';"

Она выводит символ с кодом 253. Затем взять в википедии таблицы кодировок cp866 и cp1251 и посмотреть в них символ с таким же кодом 253 и сделать вывод о кодировке.
изображение.png14 Кб, 634x286
555 1145087
Почему такой вот венегрет? Кирилцу даже не попытался впихнуть, но почему каждая переменная содержит перенос строки? Из-за того что я ентером при вводе еще и перенос строки складываю туда? Как просто вбивать туда по простому инфу?

Вспоминается в паскале было
read();
readln();

которые позволяли считывать пользовательский ввод, есть в пхп что-то аналогичное?
556 1145088
>>45087

fgest возвращает строку с символом перевода строки (от нажатия enter).

Удалить его можно с помощью rtrim(), смотри мануал.

fgest(STDIN) это и есть что-то вроде read.
557 1145168
>>45082
Сygwin и использую. Кстати, попробовал запустить на убунте - действительно с русским проблем нет. Но вопрос не в этом, я понимаю что с utf8 могут быть проблемы, вопрос в том, почему введя первый раз имя на русском оно не просит у меня ввести возраст, а сразу выводит последний echo? Т.е. пропускает заполнение переменной $age
PHP 8 558 1145170
Может кто в курсе или знает где почитать.
Че там в 8й версии планируют запилить? Когда планируют выпустить?
559 1145188
>>45168
Может дело в trim? Второй же >>45087
работет у тебя. Попробуй тримать переменную.
560 1145220
>>45188
Мы два разных анона:
Я: >>45079
Хз кто: >>45087

С латиницей работает. Если ввожу кириллицу, то ввод возраста не спрашивает: win 10 + open server + conemu + cygwin. На убунте все норм
561 1145242
Заметил, что изредка на базе данных MyISAM не срабатывают транзакции ладом.
Делаю запросы:
BEGIN
INSERT в 1 таблицу
получаю ->insert_id
INSERT в 2 таблицу SET last_base_id=$insert_id
COMMIT

Где-то раз в 100 тысяч таких срабатываний скриптов получается такое (при одновременной запущенных нескольких скриптов):
У меня в 1 и 2 таблице AUTO_INCREMENT стоит и должно записываться:
1 таблица:
id=999
id=1000
2 таблица:
id=999, last_base_id=999
id=1000, last_base_id=1000

Но вместо этого изредка получается во второй таблице:
id=999, last_base_id=1000
id=1000, last_base_id=999

Без транзакции в ->insert_id вообще какие-то левые данные.
562 1145271
>>45242

MyISAM не поддерживает транзакции и BEGIN/COMMIT ничего не делают. И еще много чего не поддерживают. Погугли сравнение MyISAM с InnoDB.
563 1145316
>>45170
https://wiki.php.net/rfc тут сморти планы, они не по 8 версии конечно. не кто не знает, сколько будет минорных у седьмой.
564 1145329
>>45271
перевел таблицы на InnoDB и охуел с тормозов из-за транзакций. Использую транзакции чтоб вместо по-очередной вставки данных вставился сразу блок - какие-то ключи и картинка в другой таблице. Потом выбираю это все объединяя таблицы.
Тормозить стали почему-то и другие скрипты, где транзакциями и не пахнет и должны выполняться моментально.
В общем, надо как-то настраивать, но лень разбираться.
Эх, не быть мне программистом. Просто вернусь на старый тип таблиц и не буду использовать ->insert_id.
download.png34 Кб, 969x367
565 1145379
Так, молодые шутливые. Вот сделаю я БД такого вида, как мне получить оттуда:

1) список владельцев с полями, по id животного

2) список животных с полями, по id владельца

3) информацию по владельцу(ам), по некоторой известной инфе о животном (клеймо, микрочип)
566 1145388
>>45379
Лол, спасибо за идею с третьей таблицей связывающей. Это придаст моему проекту более понятный вид. Можно хоть тормознутые транзакции откинуть
Тоже жду ответов. Главное чтоб быстро выбирало крупные данные и без лишних полей.
567 1145426
Сейчас делаю задачку на файлообменник и думаю над валидатором для файлов. Нужно ли проверять размер приходящего файла/файлов и их количество? Это же все задается в php.ini. Что вообще можно проверить?
568 1145428
>>45426
Что бы входящий файл не был troyan_ot_vasyana.php например, и что бы злоумышленник потом пройдя по ссылке
tvoy.sait/upload/images/troyan_ot_vasyana.php не получил полный доступ к твоему сайту.
download.png151 Кб, 1449x882
569 1145436
Чот я наабракадабрил тут.
570 1145457
Есть ли какие то бест практис так сказать при написании sdk и библиотек для работы со сторонними API? Попробовал искать но Гугл выдает результаты по ключевым словам api/sdk игнорируя остальное. Писал уже больше 10 разных либ для работы с апи но хотел бы почитать еще на эту тему
571 1145475
>>44208
благодарю за ответ. я остановился на CMF ModX, думаю все получится.

в будущем конечно буду учить фреймворки.. это мне сейчас просто заказ подкинули спонтанно, ну и я взялся блин, без опыта :)
572 1145497
Сап. Как курлом отправить картинку постом? С директивой @ не отправляется картинка. Изучаю тут, пытаюсь тред создать, в ответ всегда получаю необходимость прикрепить файл.
573 1145606
https://ideone.com/Q9fEgl

Часть функции из задачи на банк.
Сия функция должна принимать на вход три числа и переводить их в текст, но почему она глючит с цифрами типа, начинающимися на 0, типа 056 или 038. Указывает неправильные числа, например, вместо "пятьдесят шесть" пишет "сорок шесть"
Я по калькулятору проверял, всё должно быть верно.
Решил, что проблема в отсутствии сотен, решил сделать так https://ideone.com/6U4CQx
где если нет сотен, то он сразу брал номер, не отбрасывая первую цифру, но такой номер он не видит в массиве и выдавал ошибки.

Однако в конечном варианте задачи ещё не до конца готовым https://ideone.com/hDcpnO
такой ошибки нет.
574 1145616
>>43230
Почему при отсутствии сотен он начинает глючить >>45606 ?
Там же сотни будут равны нулю, а значит и любые действия нулю? Или там пустота, NULL?
575 1145618
>>43230

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


С курса на udemy брал.
576 1145619
>>45606
Вот ещё более конечный, но не готовый вариант.
https://ideone.com/aMgtBb
С женским родом слова 1 тысяча я ничего лучше не придумал.
image.png241 Кб, 550x530
577 1145621
Что-то задача с переводом цифр в слова невероятно сложная на фоне остальных.
578 1145631
>>45428
Я тут погуглил, наверное самое эффективное решение это выдавать ссылки на файл в публичной папке, а в этой папке отключить обработку скриптов. Я изначально хотел сделать папку не публичной, на практике это будет не слишком хорошо работать даже с каким-то йоба заголовком x-sendfile или еще хуже считыванием прямо пхпхой в озу.

У меня есть один вопрос к анонам. Каким образом в реальном мире производятся фоновые задачи? По наводке из статьи опа прочитал про gearman, мало что понял, есть еще какой-то крон. Вот как например ютуб конвертирует видео? Я загружаю видео на сайт, где-то внутри логика запускает эту фоновую задачу конвертации(представим что это консольная команда ffmpeg), она каким-то образом еще отдает ответ логике о прогрессе. Может создается какая-то временная запись в бд о файле и статус типа обрабатывается, завершил обратку этц. В общем сложна.

И еще есть один подводный камень с джепегом и внедренным внутрь пхп. Если я буду в превьюхе указывать сорс на оригинальную картинку, то будет ли выполняться пхп код? Я тестил на рандомном файлообменнике, там везде, даже в микро превьюшках 15x15 сохраняется пхп код, то есть чуваки не чистят метаданные, и у них ничего не ломается. Ргост кстати отказывается грузить такую картинку вообще, лол.
579 1145660
>>45621
а ты думал тебе сразу через неделю предложат работу 100к в месяц и 3 гладковыбритые бляди на выбор?
дальше все экспоненциально сложнее
580 1145668
>>45660

>дальше все экспоненциально сложнее


че ты запугиваешь человека.
581 1145723
>>35053 (OP)
Привет, анон.
Где-нибудь написано за куки? Нужны ли они? Я думал в куки передаются данные откуда перешел человек и всё такое, а в мануалах везде передают одну и ту же хуйню в виде простой строки
582 1145734
Это правда что чем дальше в будущее тем меньше и меньше вещей будут делаться на бекенде, и всё кроме бизнес логики возьмёт на себя жс
583 1145789
https://ideone.com/sB2wGU

Я сделал уже почти

Почему при цифре 02020200 он выводит: "На вашем счету пятьсот тридцать две тысячи шестьсот восемь рублей
(532608)"?
Откуда это взялось, как?

Если добавить amount8, то он вообще его пропускает.
Почему он так реагирует на цифры с нулём в начале?
584 1145790
>>44806

>Машина Тьюринга - это модель для математических доказательств и в изучении программирования не поможет.


Описание машины Тьюринга - это самый элементарный язык. Тебе не поможет, зато мне помог.
585 1145793
Ну, то есть, можно найти ещё более элементарный, разумеется.
586 1145797
>>45789

>Почему он так реагирует на цифры с нулём в начале?


Это у меня проблемы или компилятор глючит?
https://ideone.com/QljIj0
Я везде, где только можно добавил условие if != 0, поэтому он просто должен подобные пропускать.

Или он числа с 0 в начале воспринимает, как десятые части? https://ideone.com/Lh0Ch5
587 1145869
>>45723

Немного про куки есть в уроке по HTTP: https://github.com/codedokode/pasta/blob/master/network/http.md#Куки (возможно, придется еще прочесть информацию выше).

Кука это просто текстовая строка, которую сервер может сохранить в браузере и получать вместе с следующими запросами на этот сервер в виде заголовков.
588 1145889
>>45734
Но ведь в жс и в бэкенде может
589 1145890
>>45790
Учите алгоритмы, господа, теорию программирования. Тогда язык станет просто инструментом, где важно просто знать синтаксис и какие-нибудь специфические особенности.
590 1145903
>>45869
Не, это я знаю. Я имею ввиду можно ли примеры как например с помощью куки запоминаются пароли, действия на сайте, подгрузка видосов, картинок, сохранение действий. Как это всё делается
591 1145942
а в пхп есть поддержка http2?
592 1145952
>>45942
http2 это же просто протокол, какое отношение он имеет к php?
593 1146040
>>45889
Но я очевидно не об этом
594 1146079
Мне нужно создавать объекты разных классов в рантайме, я такой думаю, ну есть же какие-то йоба паттерны, натыкаюсь на фактори паттерны, читаю, большого смысла в своем случае не вижу. В одном источнике аргументация простой фабрики - если поменять название класса, то не придеться менять название во всех местах программы, только в самой фабрике. Ну охуеть.

Короче подумал что мой вариант это простая фабрика, которой передается тип/название класса, и она с помощью кейсов создает и возвращает что нужно. Потом у какого-то индуса почитал что так делать нельзя и это нарушает какой-то там йоба принцип, можно только расширять сущности, изменять их не стоит. Мол в будущем я захочу новых типов, полезу дополнять кейс и ВСЁ СЛОМАЕТСЯ. Альтернативой он предложил ФакториМетод, где каждый кейс это отдельный класс. Но мою проблему это не решает, теперь мне придется пилить кейсы сразу в каком-то контроллере, и вызывать нужные классы. Или я тупой и ничего не понял, или это всё говно из жопы. жопа горит
595 1146081
>>46079
Ваще эти паторны хуита какая то узкоспецилазированная, тебе нужно сделать йобу, а они тебя сука ограничивают, шо нихуя не получается. Походу вообще хуй надо на них забить.
596 1146123
Кто-нибудь в тредике решал недавно кошек-мышек? Мне эта задача уже года два не дается наверное. Периодически сажусь за её решение и постоянно стопарюсь на том, что не могу принять какое-то решение на каком-то этапе. Наприрмер о том, где нужно хранить координаты животного. Либо в мире, либо в самом животном например.
Начинаю себе голову какой-то фигней забивать о том, что вот если бы у нас был очень большой мир с очень большим количеством объектов, то например будут такие проблемы:

Допустим животные хранят в себе своё положение в мире. Стало быть нельзя просто взять и спросить у мира кто рядом с нами? (а было бы удобно просто спросить кто стоит в радиусе 4х клеток от x,y через простой вложенный цикл например), и придется для этого все объекты опрашивать, на предмет их координат, что бы понять о том, где они и не находится ли кто-то из них рядом с нашей текущей мшкой/кошкой.

Кароче у меня прям бомбит от своей тупости и не понимания того что делать тут. Как просто и по полочкам съехать в это примитивное казалось бы ООП с самыми что ни на есть кошечками и собачками :(
597 1146129
>>35053 (OP)
Этоn тред еще живой?

Есть вот такой говнокод: https://pastebin.com/UwKriche
Посоветуйте, как мне лучше его переписать, чтобы он выглядел более менее разборчивым? Может как-то разобрать всё в разные функции? Как это делать, и как понять, когда нужно переносить код в функцию, а когда оставить как есть? Особо сильно не вижу смысла создавать дохуя функций однострочников, так ведь только больше места уходит. Если не прав, переубедите меня.
Где вообще читать об этом?
Еще мне порой очень сильно не хватает фантазии на то, чтобы придумать название переменной. Это уже проблемы из-за того, что пишу говнокод?

Вообще, желал бы перейти на функциональный и процедурный код. Отговорите меня, или наоборот, убедите использовать всего сразу, но по чуть-чуть и только в подходящих местах. Где?

В этом проекте использую Slim и Doctrine.
598 1146159
быдланы, подскажите, если переменная не передана в запросе, нужно ее по дефолту установить. В перле было что-то вроде
$huita_name |=$default_value
В общем мне нужно, что если $huit_name - определена, то нихуя не делать, а если не определена взять значение default_value. Спс, аноны.
599 1146177
>>46159
$huita ?? $default
600 1146178
>>46177
либо воспользоваться функцией isst();
601 1146179
>>46178
*isset();
602 1146192
>>46177
>>46178
>>46179
Зочем ты ему помогаешь? Он просит помощи, но делает это без уважения, да и всрато составленный вопрос максимум. Куда у него что приходит, в функцию, в пост, в базу? Фу блядь
603 1146193
>>46192
я только хуиту написал
604 1146197
А вот это >>46129 тоже написао без уважения и с врасто составленными вопросами? Я тут нюфаг, но если ответа не получу, то можете сразу так и сообщить, тратить время не особо хочется.
605 1146206
>>35053 (OP)
Посоветуйте, пожалуйста, хороший видеокурс для начинающего, который можно было бы стянуть с торрентов. На английском или русском - без разницы. В PHP я полный ноль, но имеются некоторые знания в сфере HTML/CSS/JS.
606 1146207
>>46197
Я твоего вопроса тоже не понял. Что у тебя там не так то? Ожидал увидеть тупую стену текста, но увидел класс для незнакомого фреймворка. Или знакомого?
бесконечные $this->ci как бе намекают на codeigniter, но в общем хз что у тебя за мешанина там.

Ты в коде как используешь его?
$test= new ImageUpdate($ci);
$test->command();
как-то так и на этом всё?

Ты можешь пояснить что в итоге твои 2 метода конкретно делают?
И зачем ты хочешь их оптимизировать? Если это до тебя писали и просто работает - проще ведь не лезть.

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

Можешь попробовать например разбить на 2 функции это дело.

Первая будет искать какой-то там твой $diff и складывать его в
$this->diff в самом объекте.

А в другой метод запихнуть то, что у тебя внитри форича дергается. Что это этому методу передавать этот самый $diff уже, или даже лучше каждый отдельный элемент.

а комманд например переписать уже так:
{
$this->diff = $this->addImages();
foreach ($this->diff as $image) {
$image->doSomethingWithImage();
}
...
//аналогично для самбнейлов

}

Можешь еще сделать так, что бы у тебя не всё подряд printf'алось, а только ошибки. Поле под это дело добавить, которое будешь в конструктор передавать или прямо в коде править когда надо дампить или не дампить, или вообще что бы оно из конфига сайта на этапе конструктора класса подсасывалось

Могу полный бред писать, сам полунубас, не воспринимай меня как гуру но с аналогичным говнокодом на другом фреймворке работал, прост сижу маюсь не могу вот задачи начать решать оповские, где нужно разобраться в том, как с 0 нахуярить микрофреймворк и на нем писать студентов и прочее уже :(
606 1146207
>>46197
Я твоего вопроса тоже не понял. Что у тебя там не так то? Ожидал увидеть тупую стену текста, но увидел класс для незнакомого фреймворка. Или знакомого?
бесконечные $this->ci как бе намекают на codeigniter, но в общем хз что у тебя за мешанина там.

Ты в коде как используешь его?
$test= new ImageUpdate($ci);
$test->command();
как-то так и на этом всё?

Ты можешь пояснить что в итоге твои 2 метода конкретно делают?
И зачем ты хочешь их оптимизировать? Если это до тебя писали и просто работает - проще ведь не лезть.

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

Можешь попробовать например разбить на 2 функции это дело.

Первая будет искать какой-то там твой $diff и складывать его в
$this->diff в самом объекте.

А в другой метод запихнуть то, что у тебя внитри форича дергается. Что это этому методу передавать этот самый $diff уже, или даже лучше каждый отдельный элемент.

а комманд например переписать уже так:
{
$this->diff = $this->addImages();
foreach ($this->diff as $image) {
$image->doSomethingWithImage();
}
...
//аналогично для самбнейлов

}

Можешь еще сделать так, что бы у тебя не всё подряд printf'алось, а только ошибки. Поле под это дело добавить, которое будешь в конструктор передавать или прямо в коде править когда надо дампить или не дампить, или вообще что бы оно из конфига сайта на этапе конструктора класса подсасывалось

Могу полный бред писать, сам полунубас, не воспринимай меня как гуру но с аналогичным говнокодом на другом фреймворке работал, прост сижу маюсь не могу вот задачи начать решать оповские, где нужно разобраться в том, как с 0 нахуярить микрофреймворк и на нем писать студентов и прочее уже :(
607 1146208
>>46206
https://www.youtube.com/watch?v=Vw0SU_3FoWA

на торрентах ищи это как специалист php
изображение.png41 Кб, 715x707
608 1146213
>>46207

>Можешь попробовать например разбить на 2 функции это дело.


пикрил
609 1146225
>>46207
Фреймворк использую Slim, точнее микрофреймворк.
Конкретно этот код мой.
$this->ci это Container Interface, который подхватывается при совпадении правила route и выполнении функции в Slim. В этой функции находятся много связанного с самим фреймворком.

>Если дали таск оптимизировать чужой код, что бы учился и разбирался, то хз.


Нет, это я исключительно со своим вожусь, страдаю перфекционизмом. Всё никак не могу остановится на одном варианте, постоянно не устраивает.

>Ты можешь пояснить что в итоге твои 2 метода конкретно делают?


Вообще, забыл, что всё это действительно выглядит очень странно, без объяснения. Этот класс у меня запускается из командной строки, сделано так чтобы вызывалось из крона.
Рекурсивно ищет изображения в директорих, берёт местанахождение, sha512 файоа и заполняет эту информацию в базу данных, с помощью Doctrine, попутно генерирует для всех этих изображений превьюшки в заданных размерах через imagemagick.

Вот еще есть вот такой вариант https://pastebin.com/ceAYHjZ3 , но я не знаю, лучше ли он, чем то, что было до этого. Пытался в функциональное программирование. Как видно, выжимал из функций array_* максимум, что они могут. Почему мне кажется, что это крайне плохая затея, программировать так в классах, и тем более в PHP. От того и захотелось переписать всё это на процедурный код. Сейчас пытаюсь вернуться к здравому смыслу и обратился ИТТ.
610 1146290
>>46208
У него вроде за 2017 уже давно есть или хз за какой но поновее 2015. Самые годные уроки
611 1146291
поцоны. Поясните по хардкору, что такое cgi? Постоянно слышу это слово
613 1146312
Со Сваггера приходит число, которое я передаю либе. Либа просит чтобы число было только float. Делаю (float)$number и floatval($number), но при gettype($number) я получаю каким-то хуем double вместо float. Что за хуйня?
614 1146317
>>46312
Четыре скалярных типа:

boolean
integer
float (число с плавающей точкой, также известное как double)
string
615 1146321
>>46317
Пофиксил пока только форком либы, где в валидаторе поменял float на double.
616 1146337
>>46321
Я тут недавно немного боли с int integer в php7 принял. Конечно, мне нужно лучше знать язык, но хотелось бы какой-нибудь последовательности.
617 1146463
>>46307
Вот чочешь ты например написать для PHP функцию для своего сайта. Например сгенерировать новую 3d модель голой бабы. А в PHP такой функции нет. Вот тут на помощь приходить CGI, пишешь на другом языке это вот всё и потом к PHP подключаешь это всё. Вот это называется CGI.
618 1146482
>>46291

Гуглил?

https://ru.wikipedia.org/wiki/CGI
http://lectureswww.readthedocs.io/5.web.server/cgi.html

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

Если тебе не знакомы понятия "веб-сервер" или "HTTP запрос", прочти введение тут https://github.com/codedokode/pasta/blob/master/network/http.md

В unix/linux часто используется принцип разделения ответственности, когда каждая программа отвечает за свою часть работы. В соответствие с этим принципом, веб-сервер (nginx, apache итд) занимается только взаимодействием с клиентом по протоколу HTTP и отдачей статических файлов. Он не умеет при поступлении запроса загружать и выполнять программы на каких-то языках программирования. А это часто необходимо - когда мы хотим, чтобы страницы генерировались бы на "лету", динамически.

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

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

CGI, если ты почитаешь, очень простой и не требует каких-то специальных библиотек. Можно использовать хоть скрипт на bash из 5 строчек, а также, разумеется, программу на любом другом языке программирования. Это его плюс. Ну например, можно сделать bash скрипт, выводящий количество свободного места на дисках, и настроить сервер так, чтобы при заходе на определенную страницу показывалась бы эта информация.

Вот пример такого скрипта (работает только под Мак и Линукс), допустим с именем /var/www/disks.sh:

#!/bin/bash
echo "Content-Type: text\plain; charset=utf-8"
echo
df # выводит информацию о дисках

В линуксе bash-скрипты являются исполняемыми программами и их можно запускать напрямую.

Вот пример части конфига, который указывает Апачу (он поддерживает CGI) запускать этот скрипт при обращении по URL http://127.0.0.1/disks :

LoadModule cgid_module modules/mod_cgid.so
ScriptAlias /disks /var/www/disks.sh

Как видим, добавив всего несколько строчек, мы можем смотреть результат выполнения команды df через браузер. Этот пример показывает, насколько прост CGI.

Мануал

- http://httpd.apache.org/docs/current/howto/cgi.html
- https://httpd.apache.org/docs/trunk/mod/mod_alias.html#scriptalias

PHP поддерживает взаимодействие с сервером в соответствие с спецификацией CGI.

Минус в том, что запускать внешнюю программу на каждый запрос довольно неэффективно, так как основное время может уходить на запуск/завершение программы, а не на выполнение полезной работы. Потому для нагруженных серверов придуманы новые интефейсы вроде FastCGI где программа запускается один раз и может обработать много запросов от веб-сервера не завершаясь. PHP поддерживает FastCGI с помощью php-fpm.

Ну и другое, не такое удчаное решение - это mod_php, PHP может работать внутрни процесса apache, взаимодействуя с ним через внутренние API Апача.

Веб-сервер nginx не поддерживает CGI, а только FastCGI. Для запуска CGI программ из-под него нужно использовать вспомогательную программу вроде https://www.nginx.com/resources/wiki/start/topics/examples/fcgiwrap/ которая будет принимать FastCGI запросы и запускать внешние программы через CGI.
618 1146482
>>46291

Гуглил?

https://ru.wikipedia.org/wiki/CGI
http://lectureswww.readthedocs.io/5.web.server/cgi.html

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

Если тебе не знакомы понятия "веб-сервер" или "HTTP запрос", прочти введение тут https://github.com/codedokode/pasta/blob/master/network/http.md

В unix/linux часто используется принцип разделения ответственности, когда каждая программа отвечает за свою часть работы. В соответствие с этим принципом, веб-сервер (nginx, apache итд) занимается только взаимодействием с клиентом по протоколу HTTP и отдачей статических файлов. Он не умеет при поступлении запроса загружать и выполнять программы на каких-то языках программирования. А это часто необходимо - когда мы хотим, чтобы страницы генерировались бы на "лету", динамически.

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

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

CGI, если ты почитаешь, очень простой и не требует каких-то специальных библиотек. Можно использовать хоть скрипт на bash из 5 строчек, а также, разумеется, программу на любом другом языке программирования. Это его плюс. Ну например, можно сделать bash скрипт, выводящий количество свободного места на дисках, и настроить сервер так, чтобы при заходе на определенную страницу показывалась бы эта информация.

Вот пример такого скрипта (работает только под Мак и Линукс), допустим с именем /var/www/disks.sh:

#!/bin/bash
echo "Content-Type: text\plain; charset=utf-8"
echo
df # выводит информацию о дисках

В линуксе bash-скрипты являются исполняемыми программами и их можно запускать напрямую.

Вот пример части конфига, который указывает Апачу (он поддерживает CGI) запускать этот скрипт при обращении по URL http://127.0.0.1/disks :

LoadModule cgid_module modules/mod_cgid.so
ScriptAlias /disks /var/www/disks.sh

Как видим, добавив всего несколько строчек, мы можем смотреть результат выполнения команды df через браузер. Этот пример показывает, насколько прост CGI.

Мануал

- http://httpd.apache.org/docs/current/howto/cgi.html
- https://httpd.apache.org/docs/trunk/mod/mod_alias.html#scriptalias

PHP поддерживает взаимодействие с сервером в соответствие с спецификацией CGI.

Минус в том, что запускать внешнюю программу на каждый запрос довольно неэффективно, так как основное время может уходить на запуск/завершение программы, а не на выполнение полезной работы. Потому для нагруженных серверов придуманы новые интефейсы вроде FastCGI где программа запускается один раз и может обработать много запросов от веб-сервера не завершаясь. PHP поддерживает FastCGI с помощью php-fpm.

Ну и другое, не такое удчаное решение - это mod_php, PHP может работать внутрни процесса apache, взаимодействуя с ним через внутренние API Апача.

Веб-сервер nginx не поддерживает CGI, а только FastCGI. Для запуска CGI программ из-под него нужно использовать вспомогательную программу вроде https://www.nginx.com/resources/wiki/start/topics/examples/fcgiwrap/ которая будет принимать FastCGI запросы и запускать внешние программы через CGI.
619 1146484
>>46463

Нет. CGI это протокол взаимодействия между веб-сервером и внешней программой-обработчиком, а не между PHP и внешней программой.
620 1146506
>>46484
Но таки из PHP ты таки можешь получить инфу от CGI?
621 1146513
>>46506

Что значит "получить инфу от CGI"? CGI это правила взаимодействия двух программ, от самого CGI получить ничего нельзя, можно только с использованием правил CGI вызвать другую программу и получить что-то от нее.
14788938129490.jpg31 Кб, 317x372
622 1146549
623 1146552
>>46482
короче обычный роутер для вебсайта - cgi
624 1146553
>>46552
Нет, тебе же всё расписали. Это вообще не роутер не разу.
625 1146557
>>46081
Великовозрастное быдло?
Тоже поймал себя на мысле, что все современные новшества - это хуита без содержания.
Сидишь, пытаешься понять, читаешь доку - где же потаенный смысл? В итоге оказывается, что ты ожидал от какойто хуйни больше, чем она есть на самом деле. Зато пафоса нагоняют яебу, термины придумывают и пр. Причем специально преподносят инфу об этом в таком сложном виде, чтобы создать иллюзию, что они знают что-то мега сложное
626 1146558
>>46553
Мне расписали так, что это на выходе - роутер.
хттп адрес вызывает программу, которая генерирует мне страницу, что не так?
627 1146561
>>46558

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


Всё не так. Перечитывай.
628 1146563
>>46558
Ты действительно описал роутер. Но ты вообще даже близко не понял смысл CGI.
629 1146564
>>46561
Перечитал

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

630 1146572
>>46563
Везде так написано. CGI - это запрос, который возвращает результат работы программы
631 1146573
>>46564
Роутер - запросы роутит
Ты пишешь ему hui\pizda\igor а он тебе по заросу страницу скидывает
А CGI тебе делеает внутренние расчёты на компе, внешней прогой. Тоесть тут тоже запрос идёт, но это не роут блядь запрос. Это запрос к программе, который тоже через роутер можно сделать. Как вообще эти вещи перепутать можно, я не понимаю?
632 1146578
>>46573
Роутер также. Делаю запрос, внешняя программа на пхп делает внутренние расчеты и отдает результат
633 1146583
>>46578
Ты траллируешь меня чтоли? Нахуй иди даун.
634 1146588
>>46583
Я не виноват, что тебя трисет, гуманитарий. Хочешь общаться и не рваться - научись излагать мысли исчерпывающе.
http://www.php.su/learnphp/cgi/?interface

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

635 1146593
>>46588
Нахуй ты вообще в треде вопросы задеёшь дебил? Если тебе 5 раз сказали нет, это не роутер, а у тебя всё равно один роутер блядь на уме. Ну и иди нахуй тошда со своим роутером, еблана кусок. Не еби людям мозг. Всё равно ты необучаемый и тупой как полено. Выучил одно слово и теперь считаешь что это всё роутер. Тебе написали что нет, всё равно пытаешься что-то там доказать, зачем только непонятно.
636 1146600
>>46588
В треде все тебя одманывают анон. Это всё на самом деле роутер. И весь PHP - это роутер. И JS это роутер. Даже CSS это роутер. Ты раскусил заговор против тебя. Не оборачивайся.
R3q5hwKU1ak.jpg92 Кб, 1080x1044
637 1146603
>>46593
Если это не роутер, тогда зачем ты и другие источники, поясняя за cgi, дают определение роутера?
639 1146609
>>46604

>РОУТЕР НИТАК СДЕЛАН, ЯТАКСКАЗАЛ!!!11


Тяжело программирование дается, гуманитарий?
640 1146611
Почоны, возьмут ли меня с таким стэком технологий на работу?
1. Роутер (PHP)
2. Роутер (HTML5)
3. Роутер (TP-LINK TL-WR841N)
?
641 1146617
>>46611
Тише. Понимаю, хотел умное спиздануть и обосрался принародно, мой совет - не бегай роняя кал, тихонько ретируйся потом подучишь, может столкнешься на практике и второй раз может получиться не обосраться
642 1146622
Почему не стоит парсить HTML с помощью регекс?
643 1146629
Поцаны, поясните, почему на вике написано про cgi

>CGI является одним из наиболее распространённых средств создания динамических сайтов.


это же совсем разные вещи, верно?
644 1146643
>>46290

>У него вроде за 2017 уже давно есть


У него есть, а на торрентах нет.
645 1146645
>>46622
Потому что ты изобретаешь колесо. Есть тысячи библиотек для работы с DOM'ом, используя которые шанс ошибиться намного меньше, чем при попытке написать регексп.
>>46629
Ну смотри. Веб-сервер возвращает статичный контент. Нужна динамика? Дергай скрипт. Как дёрнуть скрипт? Через cgi. Вот и всё. Хотя в той же джаве не или го нет такого разделения на веб-сервер/прикладной код, но мы же тут за пехапе общаемся.
647 1146681
Сорян за глупый вопрос
Стоит ли для вкатывания в php начинать проходит курс от И.О.Борисова?
Каков он как преподаватель или преподаёт ли он нужную информацию для изучения?
648 1146698
Ну что же такое-то, я вроде пытался все подробно расписать в посте >>46482 но все равно есть непонимание. Вы точно читали урок про HTTP? Понимаете, как работает веб-сервер?

Повторю еще раз. Когда ты переходишь по какой-то ссылке или вводишь адрес в браузер, браузер как HTTP-клиент связывается в HTTP-сервером и отправляет ему HTTP-запрос. По умолчанию сервер просто в ответ на запрос отдает файл с диска. Это может быть HTML-страница, картинка или что-то еще. Но такой подход позволяет отдавать только статические, то есть неизменные страницы. А часто требуется генерировать страницы динамически с помощью программы на каком-то языке.

Сам веб-сервер не умеет выполнять программы, потому были придуманы интерфейсы/протоколы (правила взаимодействия) веб-сервера с внешними программами - CGI и позже FastCGI. В конфиге веб-сервера мы настраиваем, какую программу и в каком случае надо вызывать.

CGI очень простой и понятный, но медленный - на каждый запрос программа запускается заново. На реальных сайтах используют FastCGI - в этом случае мы запускаем отдельно веб-сервер, отдельно FastCGI процесс, и затем веб-сервер начинает передавать этому процессу запросы, которые тот обрабатывает по очереди, не перезапускаясь. В случае языка PHP, программа php-fpm принимает от веб-сервера FastCGI запросы на выполнение PHP скриптов, выполняет их и возвращает серверу результат выполнения скрипта. То есть веб-сервер "просит" php-fpm выполнить PHP-скрипт, тот выполняет его и передает веб-серверу результат выполнения (что вывел скрипт с помощью echo, какие заголовки выставил с помощью header).

Эти протоколы (как CGI, так и fastCGI) позволяют веб-серверу взаимодействовать с программами на любом языке программирования. Веб-сервер не привязан к какому-то одному языку. Веб-серверу не надо "знать", как выполнить ту или иную программу. Также, они добавляют надежности - если во внешней программе (в интерпретаторе PHP например) произойдет ошибка, и она аварийно завершится, процесс веб-сервера это не заденет и он продолжит работать.

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

Насчет роутера - "роутером" обычно называют часть приложения, которая занимается разбором запроса. То есть это функция, которая получает на вход URL и на выходе дает например название контроллера, который надо выполнить. CGI это не функция, а протокол (набор правил) и уже поэтому нельзя говорить, что "CGI это роутер". Тем более, CGI не занимается вообще разбором URL. Это набор правил, который говорит о том, как веб-севрер передает внешней программе информацию о запросе (через переменные окружения и поток stdin) и как программа возвращает заголовки и тело HTTP-ответа. Почитайте спецификацию CGI, например https://tools.ietf.org/html/rfc3875 (увы, на русском адекватного перевода не нашел) и найдите там что-то похожее на роутер.

>>46629

> CGI является одним из наиболее распространённых средств создания динамических сайтов.



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

>>46645

> Хотя в той же джаве не или го нет такого разделения на веб-сервер/прикладной код



Они просто общаются с веб-сервером по HTTP вместо CGI/FastCGI. В сравнении с CGI это усложняет приложение (ты вряд ли напишешь полноценный HTTP сервер на bash, а с CGI можно работать хоть из bash скрипта), приводит к дублированию функционала (разбором HTTP мог бы заниматься только веб-сервер). Есть конечно и плюсы - они могут работать как-то ограниченно даже без веб-сервера.
648 1146698
Ну что же такое-то, я вроде пытался все подробно расписать в посте >>46482 но все равно есть непонимание. Вы точно читали урок про HTTP? Понимаете, как работает веб-сервер?

Повторю еще раз. Когда ты переходишь по какой-то ссылке или вводишь адрес в браузер, браузер как HTTP-клиент связывается в HTTP-сервером и отправляет ему HTTP-запрос. По умолчанию сервер просто в ответ на запрос отдает файл с диска. Это может быть HTML-страница, картинка или что-то еще. Но такой подход позволяет отдавать только статические, то есть неизменные страницы. А часто требуется генерировать страницы динамически с помощью программы на каком-то языке.

Сам веб-сервер не умеет выполнять программы, потому были придуманы интерфейсы/протоколы (правила взаимодействия) веб-сервера с внешними программами - CGI и позже FastCGI. В конфиге веб-сервера мы настраиваем, какую программу и в каком случае надо вызывать.

CGI очень простой и понятный, но медленный - на каждый запрос программа запускается заново. На реальных сайтах используют FastCGI - в этом случае мы запускаем отдельно веб-сервер, отдельно FastCGI процесс, и затем веб-сервер начинает передавать этому процессу запросы, которые тот обрабатывает по очереди, не перезапускаясь. В случае языка PHP, программа php-fpm принимает от веб-сервера FastCGI запросы на выполнение PHP скриптов, выполняет их и возвращает серверу результат выполнения скрипта. То есть веб-сервер "просит" php-fpm выполнить PHP-скрипт, тот выполняет его и передает веб-серверу результат выполнения (что вывел скрипт с помощью echo, какие заголовки выставил с помощью header).

Эти протоколы (как CGI, так и fastCGI) позволяют веб-серверу взаимодействовать с программами на любом языке программирования. Веб-сервер не привязан к какому-то одному языку. Веб-серверу не надо "знать", как выполнить ту или иную программу. Также, они добавляют надежности - если во внешней программе (в интерпретаторе PHP например) произойдет ошибка, и она аварийно завершится, процесс веб-сервера это не заденет и он продолжит работать.

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

Насчет роутера - "роутером" обычно называют часть приложения, которая занимается разбором запроса. То есть это функция, которая получает на вход URL и на выходе дает например название контроллера, который надо выполнить. CGI это не функция, а протокол (набор правил) и уже поэтому нельзя говорить, что "CGI это роутер". Тем более, CGI не занимается вообще разбором URL. Это набор правил, который говорит о том, как веб-севрер передает внешней программе информацию о запросе (через переменные окружения и поток stdin) и как программа возвращает заголовки и тело HTTP-ответа. Почитайте спецификацию CGI, например https://tools.ietf.org/html/rfc3875 (увы, на русском адекватного перевода не нашел) и найдите там что-то похожее на роутер.

>>46629

> CGI является одним из наиболее распространённых средств создания динамических сайтов.



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

>>46645

> Хотя в той же джаве не или го нет такого разделения на веб-сервер/прикладной код



Они просто общаются с веб-сервером по HTTP вместо CGI/FastCGI. В сравнении с CGI это усложняет приложение (ты вряд ли напишешь полноценный HTTP сервер на bash, а с CGI можно работать хоть из bash скрипта), приводит к дублированию функционала (разбором HTTP мог бы заниматься только веб-сервер). Есть конечно и плюсы - они могут работать как-то ограниченно даже без веб-сервера.
649 1146699
>>46622

Неудобно.

>>46593

Не надо так писать. Иди самоутверждайся в каком-то другом треде или просто пройди мимо.

>>46603

Это надо спрашивать у этих источников, а не у нас.

>>46588

В той статье (по ощущениям, она старая или это перевод очень старой статьи) в самом начале ведь написано:

> Термин CGI ... обозначает набор соглашений...



Тут же черным по синему написано: CGI - это набор соглашений. А роутер это часть программы, функция или класс.

>>Подобным образом можно передавать и html-документы,


А роутер-то тут при чем? Роутер не занимается передачей HTML-документов, а лишь разбором URL.

По статье - неточность:

> Фактически, до недавнего времени все Web-программирование представляло собой программирование CGI-приложений


"до недавнего времени" - где-то до 2000 года, так как спецификация FastCGI появилась в 1996.

>>46572

CGI - это не "запрос", а набор правил о том, как веб-сервер взаимодействует с внешней программой, как передает ей данные и что она возвращает ему.

>>46583

Если не можешь спокойно объяснить, то лучше не объяснять вообще.

>>46558

> хттп адрес вызывает программу,


Не так. Веб-сервер при поступлении HTTP-запроса страницы с определенным URL может вызвать внешнюю программу с использованием соглашения CGI, если в его настройках так указано.

"хттп адрес" (URL видимо) это просто строка, и она ничего не может вызвать.
649 1146699
>>46622

Неудобно.

>>46593

Не надо так писать. Иди самоутверждайся в каком-то другом треде или просто пройди мимо.

>>46603

Это надо спрашивать у этих источников, а не у нас.

>>46588

В той статье (по ощущениям, она старая или это перевод очень старой статьи) в самом начале ведь написано:

> Термин CGI ... обозначает набор соглашений...



Тут же черным по синему написано: CGI - это набор соглашений. А роутер это часть программы, функция или класс.

>>Подобным образом можно передавать и html-документы,


А роутер-то тут при чем? Роутер не занимается передачей HTML-документов, а лишь разбором URL.

По статье - неточность:

> Фактически, до недавнего времени все Web-программирование представляло собой программирование CGI-приложений


"до недавнего времени" - где-то до 2000 года, так как спецификация FastCGI появилась в 1996.

>>46572

CGI - это не "запрос", а набор правил о том, как веб-сервер взаимодействует с внешней программой, как передает ей данные и что она возвращает ему.

>>46583

Если не можешь спокойно объяснить, то лучше не объяснять вообще.

>>46558

> хттп адрес вызывает программу,


Не так. Веб-сервер при поступлении HTTP-запроса страницы с определенным URL может вызвать внешнюю программу с использованием соглашения CGI, если в его настройках так указано.

"хттп адрес" (URL видимо) это просто строка, и она ничего не может вызвать.
650 1146700
>>46557

Вы просто не так понимаете. Вы прочли "фабрика может использоваться для создания объектов" и думаете, что "в 2018" все объекты принято создавать через фабрики. Нет, где это написано? Не надо использовать паттерны просто, чтобы они были.

Паттерны (могу ошибаться) начал собирать Фаулер. Он работал с самым разным кодом, и выделил какие-то типичные решения, которые часто встречались. Дал им названия, определения, описал их в книге. Иногда одну задачу можно было решить несколькими способами (например, наследование таблиц). Если у вас нет книги, то краткое описание паттернов есть на его сайте: https://martinfowler.com/eaaCatalog/ Там, кстати, нет Фабрики или Синглтона (которые вы изучаете, так как они вам кажутся самыми простыми). Зато есть Контроллер Страницы (тот самый, из MVC), паттерны наследования таблиц, паттерны взаимодействия с БД. Почитайте, полистайте. У меня как-то язык не повернется сказать, что описанное там "нигде не нужно" - я это видел много раз, а если вы будете разбирать Симфони, там половина этих паттернов встретится.

И кстати, книга вышла в 2003. Довольно давно.

>>46312

В PHP double и float это синонимы. В других языках, вроде Си, это 2 разных способа хранения чисел с плавающей точкой (в Си double занимает 8 байт, а float 4 байта, но первый хранит больше знаков после запятой и представляет более широкий диапазон значений).
651 1146701
>>46129

> class ImageUpdate


Название класса - это существительное, хотя бы ImageUpdater, "обновлятель картинок" (есть впрочем мнение, что вредно называть классы с суффиксом -er).

> class ImageUpdate extends Container


Здесь ошибка, непонимание наследования. Вот я даже в своем учебнике пытался описать ( http://phpbooktest.ga/l1/pasta.html )

> Наследование позволяет создать новый класс не с нуля, а расширив уже существующий.


> Нельзя наследовать что угодно от чего угодно. Наследование должно применяться только для однотипных сущностей. Например, класс Банк можно унаследовать от класса Организация (так как банк - это вид организации), а вот унаследовать класс Работник от Организации нельзя. Также, нельзя унаследовать Организацию от Банка, так как Организация - это более широкое понятие.



"А наследуется от B" - это значит "А является B". Это значит, объект класса B можно использовать в коде вместо A (принцип замещения Лисков).

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

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

Кстати, это типичная ошибка, я такое во многих CMS видел, люди просто не понимают ООП.

Хотя, я могу ошибиться, так как из куска кода неясно, что такое Container. Тем более что некий ci у тебя еще и передается в конструктор.

Дальше, в конструктор ты передаешь DI Container - но DI делается не так. Прочитай мой урок про DI, лень тут пересказывать все: https://github.com/codedokode/pasta/blob/master/arch/di.md . В конструктор передаются сами зависимости, а не контейнер.

> $images = $this->repo->findAll();


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

> $files = Files::find($this->imageRoot, $this->ignore, $this->imageExts);


Название класса Files неудачное. Что, его объект представляет набор файлов? Нет, это просто Utility class со статическими методами и логично было назвать его FileUtil или FileHelper.

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

> foreach ($images as $image) array_push($list, $image->getImage());


Надо писать в 3 строки со скобками. Глянь PSR-1 и PSR-2, они есть и в переводе. Или пропусти код через phpformatter.com.

> $image->getImage()


Метод называется getImage но возвращает, судя по всему, не картинку, а путь к ней. Ну так и сделай соответствующее название.

> if ($dup = $this->repo->findOneBy(['sha512' => $sha512Hash])) {


Если ты загрузил все файлы в память выгоднее сделать "индекс" в виде массива и искать по ключу в нем - это в разы быстрее, чем слать запрос в БД.

> $this->ci->em->persist($image);


> $this->ci->em->flush();


Вообще, не выгодно делать flush после каждого файла, выгоднее собрать побольше сущностей и разом их записать в БД.

> $this->ci->em->clear();


А это вообще не логично. Ты понимаешь, что делает эта команда?

> exec(sprintf("convert -thumbnail


Это довольно невыгодно, запускать внешнюю программу на каждую картинку. Выгоднее использовать расширение imagick или gd.

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

> ob_flush();


Зачем они там в каждой строке?

> foreach (["medium" => "1000x1000", "small" => "250x250"]


> as $name => $size)


Слишком длинный и нечитаемый заголовок цикла. не надо так.

> $key = array_search($thumb, $files);


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

По коду, код плохо оформлен, не по PSR, оставлены какие-то закомментированные куски, тяжело читать. Также, функции написаны одниой длинной стеной кода, надо выносить отдельные действия. Например, в методе addImages (который правильнее назвать findNewImages или findUnregisteredImages), можно вынести отдельно метод createImageEntity.

В методе createThumbs генерацию одной превьюшки надо вынести отдельно.

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

> есть вот такой вариант https://pastebin.com/ceAYHjZ3


Куча методов с плохо составленными названиями, без тайп-хинтов. Если ты хочешь попробовать функциональное программирование, изучай Хаскелл, так как это конечно не оно.

> isset($args[0]) && $args[0] === "thumbs" ?


> $this->thumbs() : $this->thumbs($this->images());


Не надо так делать. Тут нужен if, а ты зачем-то его обфусцируешь, от этого никакой пользы и труднее читать код.

> return array_map(array($this, "putImages"),


> array_filter(


> $this->filterDups(


> array_map(array($this, "prepareSha512"), $diff)


> ),


> array($this, "filterNull")


Эту лестницу невозможно читать.

> Вообще, желал бы перейти на функциональный


Тогда изучи сначала функциональное программирование на примере Хаскелл. На PHP корявость синтаксиса только отпугнет тебя.

> Как это делать, и как понять, когда нужно переносить код в функцию, а когда оставить как есть


Когда полeчается тяжело читаемая стена кода, когда в ней явно можно выделить отдельные действия.

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


Цель - читаемость, простота поддержки, а не экономия строчек.

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


Надо учиться объяснять, зачем нужна эта переменаая и что она хранит.
651 1146701
>>46129

> class ImageUpdate


Название класса - это существительное, хотя бы ImageUpdater, "обновлятель картинок" (есть впрочем мнение, что вредно называть классы с суффиксом -er).

> class ImageUpdate extends Container


Здесь ошибка, непонимание наследования. Вот я даже в своем учебнике пытался описать ( http://phpbooktest.ga/l1/pasta.html )

> Наследование позволяет создать новый класс не с нуля, а расширив уже существующий.


> Нельзя наследовать что угодно от чего угодно. Наследование должно применяться только для однотипных сущностей. Например, класс Банк можно унаследовать от класса Организация (так как банк - это вид организации), а вот унаследовать класс Работник от Организации нельзя. Также, нельзя унаследовать Организацию от Банка, так как Организация - это более широкое понятие.



"А наследуется от B" - это значит "А является B". Это значит, объект класса B можно использовать в коде вместо A (принцип замещения Лисков).

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

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

Кстати, это типичная ошибка, я такое во многих CMS видел, люди просто не понимают ООП.

Хотя, я могу ошибиться, так как из куска кода неясно, что такое Container. Тем более что некий ci у тебя еще и передается в конструктор.

Дальше, в конструктор ты передаешь DI Container - но DI делается не так. Прочитай мой урок про DI, лень тут пересказывать все: https://github.com/codedokode/pasta/blob/master/arch/di.md . В конструктор передаются сами зависимости, а не контейнер.

> $images = $this->repo->findAll();


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

> $files = Files::find($this->imageRoot, $this->ignore, $this->imageExts);


Название класса Files неудачное. Что, его объект представляет набор файлов? Нет, это просто Utility class со статическими методами и логично было назвать его FileUtil или FileHelper.

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

> foreach ($images as $image) array_push($list, $image->getImage());


Надо писать в 3 строки со скобками. Глянь PSR-1 и PSR-2, они есть и в переводе. Или пропусти код через phpformatter.com.

> $image->getImage()


Метод называется getImage но возвращает, судя по всему, не картинку, а путь к ней. Ну так и сделай соответствующее название.

> if ($dup = $this->repo->findOneBy(['sha512' => $sha512Hash])) {


Если ты загрузил все файлы в память выгоднее сделать "индекс" в виде массива и искать по ключу в нем - это в разы быстрее, чем слать запрос в БД.

> $this->ci->em->persist($image);


> $this->ci->em->flush();


Вообще, не выгодно делать flush после каждого файла, выгоднее собрать побольше сущностей и разом их записать в БД.

> $this->ci->em->clear();


А это вообще не логично. Ты понимаешь, что делает эта команда?

> exec(sprintf("convert -thumbnail


Это довольно невыгодно, запускать внешнюю программу на каждую картинку. Выгоднее использовать расширение imagick или gd.

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

> ob_flush();


Зачем они там в каждой строке?

> foreach (["medium" => "1000x1000", "small" => "250x250"]


> as $name => $size)


Слишком длинный и нечитаемый заголовок цикла. не надо так.

> $key = array_search($thumb, $files);


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

По коду, код плохо оформлен, не по PSR, оставлены какие-то закомментированные куски, тяжело читать. Также, функции написаны одниой длинной стеной кода, надо выносить отдельные действия. Например, в методе addImages (который правильнее назвать findNewImages или findUnregisteredImages), можно вынести отдельно метод createImageEntity.

В методе createThumbs генерацию одной превьюшки надо вынести отдельно.

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

> есть вот такой вариант https://pastebin.com/ceAYHjZ3


Куча методов с плохо составленными названиями, без тайп-хинтов. Если ты хочешь попробовать функциональное программирование, изучай Хаскелл, так как это конечно не оно.

> isset($args[0]) && $args[0] === "thumbs" ?


> $this->thumbs() : $this->thumbs($this->images());


Не надо так делать. Тут нужен if, а ты зачем-то его обфусцируешь, от этого никакой пользы и труднее читать код.

> return array_map(array($this, "putImages"),


> array_filter(


> $this->filterDups(


> array_map(array($this, "prepareSha512"), $diff)


> ),


> array($this, "filterNull")


Эту лестницу невозможно читать.

> Вообще, желал бы перейти на функциональный


Тогда изучи сначала функциональное программирование на примере Хаскелл. На PHP корявость синтаксиса только отпугнет тебя.

> Как это делать, и как понять, когда нужно переносить код в функцию, а когда оставить как есть


Когда полeчается тяжело читаемая стена кода, когда в ней явно можно выделить отдельные действия.

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


Цель - читаемость, простота поддержки, а не экономия строчек.

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


Надо учиться объяснять, зачем нужна эта переменаая и что она хранит.
652 1146702
>>46159

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

В чистом PHP: $x = array_key_exists('x', $_GET) ? strval($_GET['x']) : '';
В новом PHP дял ленивых $x = strval($_GET['x'] ?? '');
В Symfony: $x = $request->query->get('x');

>>46123

Есть поиск в архиве: https://phpclub.tech/search/?q=кошки+мышки если не лень разбирать столько постов.

> Мне эта задача уже года два не дается наверное


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

Почитай статью про выпечку хлеба, она обязательна для всех, кто недавно изучал ООП или паттерны: https://habrahabr.ru/post/153225/

> Наприрмер о том, где нужно хранить координаты животного. Либо в мире, либо в самом животном например.


Надо взвесить плюсы и минусы.

> Допустим животные хранят в себе своё положение в мире. Стало быть нельзя просто взять и спросить у мира кто рядом с нами?


Ну допустим, координаты хранятся в "мире" в виде массива Coordnate[] (объект Coordinate содержит поля x и y). В чем отличие? В одном случае - массив животных, в другом - массив координат.

Я скажу, в чем. Отличие в том, что когда координаты в мире, их нельзя изменить без его ведома. Если у тебя есть, например, индекс для быстрого поиска на карте, то его надо обновлять при изменении координат. Когда они в мире - это просто. А когда в животных - то мир должен как-то узнавать об их изменении:

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

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

Чтобы быстро спросить "кто рядом" при большом числе объектов, разумеется, массив не годится - там время поиска O(N). Для этого используют индексы - структуры для оптимизации поиска. Есть много разных видов индексов с плюсами и минусами:

- https://ru.wikipedia.org/wiki/Задача_поиска_ближайшего_соседа
- https://en.wikipedia.org/wiki/Nearest_neighbor_search

Например, kD- и BSP-деревья позволяют быстро искать точки в определенном радиусе, но к недостатку можно отнести то, что при перемещении любой точки надо их перестраивать - а у тебя перемещения происходят постоянно. Они лучше годятся для неподвижных объектов (поиск точек на карте, например). R-tree ( https://en.wikipedia.org/wiki/R-tree ) врде лучше заточены под изменение, но очень сложные.

Есть еще другие подходы. Например, разделение пространства на "сектора", причем id сектора вычисляется из координат. Затем мы делаем индекс (просто массив), который хранит для каждого сектора все объекты в нем. Когда нам надо искать ближайшие точки к данной, мы берем ее сектор и, если надо, соседние, берем объекты из них и уже их отсеиваем по расстоянию. При перемещении объекта в другой сектор индекс надо обновить, при перемещении внутри сектора - не надо.

Сюда можно отнести алгортмы:

- https://en.wikipedia.org/wiki/Grid_(spatial_index)
- https://en.wikipedia.org/wiki/Z-order_curve
- https://en.wikipedia.org/wiki/HHCode
- https://en.wikipedia.org/wiki/Quadtree
- другие структуры данных отсюда https://en.wikipedia.org/wiki/Spatial_database#Spatial_index

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

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

> Как просто и по полочкам съехать в это примитивное казалось бы ООП с самыми что ни на есть кошечками и собачками :(


Напиши список классов, полей и методов (без кода) и обсудим.
652 1146702
>>46159

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

В чистом PHP: $x = array_key_exists('x', $_GET) ? strval($_GET['x']) : '';
В новом PHP дял ленивых $x = strval($_GET['x'] ?? '');
В Symfony: $x = $request->query->get('x');

>>46123

Есть поиск в архиве: https://phpclub.tech/search/?q=кошки+мышки если не лень разбирать столько постов.

> Мне эта задача уже года два не дается наверное


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

Почитай статью про выпечку хлеба, она обязательна для всех, кто недавно изучал ООП или паттерны: https://habrahabr.ru/post/153225/

> Наприрмер о том, где нужно хранить координаты животного. Либо в мире, либо в самом животном например.


Надо взвесить плюсы и минусы.

> Допустим животные хранят в себе своё положение в мире. Стало быть нельзя просто взять и спросить у мира кто рядом с нами?


Ну допустим, координаты хранятся в "мире" в виде массива Coordnate[] (объект Coordinate содержит поля x и y). В чем отличие? В одном случае - массив животных, в другом - массив координат.

Я скажу, в чем. Отличие в том, что когда координаты в мире, их нельзя изменить без его ведома. Если у тебя есть, например, индекс для быстрого поиска на карте, то его надо обновлять при изменении координат. Когда они в мире - это просто. А когда в животных - то мир должен как-то узнавать об их изменении:

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

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

Чтобы быстро спросить "кто рядом" при большом числе объектов, разумеется, массив не годится - там время поиска O(N). Для этого используют индексы - структуры для оптимизации поиска. Есть много разных видов индексов с плюсами и минусами:

- https://ru.wikipedia.org/wiki/Задача_поиска_ближайшего_соседа
- https://en.wikipedia.org/wiki/Nearest_neighbor_search

Например, kD- и BSP-деревья позволяют быстро искать точки в определенном радиусе, но к недостатку можно отнести то, что при перемещении любой точки надо их перестраивать - а у тебя перемещения происходят постоянно. Они лучше годятся для неподвижных объектов (поиск точек на карте, например). R-tree ( https://en.wikipedia.org/wiki/R-tree ) врде лучше заточены под изменение, но очень сложные.

Есть еще другие подходы. Например, разделение пространства на "сектора", причем id сектора вычисляется из координат. Затем мы делаем индекс (просто массив), который хранит для каждого сектора все объекты в нем. Когда нам надо искать ближайшие точки к данной, мы берем ее сектор и, если надо, соседние, берем объекты из них и уже их отсеиваем по расстоянию. При перемещении объекта в другой сектор индекс надо обновить, при перемещении внутри сектора - не надо.

Сюда можно отнести алгортмы:

- https://en.wikipedia.org/wiki/Grid_(spatial_index)
- https://en.wikipedia.org/wiki/Z-order_curve
- https://en.wikipedia.org/wiki/HHCode
- https://en.wikipedia.org/wiki/Quadtree
- другие структуры данных отсюда https://en.wikipedia.org/wiki/Spatial_database#Spatial_index

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

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

> Как просто и по полочкам съехать в это примитивное казалось бы ООП с самыми что ни на есть кошечками и собачками :(


Напиши список классов, полей и методов (без кода) и обсудим.
653 1146703
>>46079

if/else и new не подойдет?

Прочти статью https://habrahabr.ru/post/153225/

>>45734

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

>>45942

В смысле, отправка HTTP/2 запросов? Или их прием? Обычно за второе веб-сервер, а не PHP, отвечает. А первое вроде есть в расширении curl.

>>45903

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

Ну например: надо сделать авторизацию на сайте, и такие функции:

- регистрация: функция получает на вход логин, пароль и "запоминает" их где-то
- проверка данных: функция получает на вход логин, пароль, и проверяет, правльные ли они
- вход на сайт: функция получает на вход логин, пароль, если они верные, то выставляет некую куку
- проверка залогиненности: функция проверяет по кукам, залогинен ли текущий пользователь, если да, то возвращает его логин, если нет - null
- выход: вызов функции "разлогинивает" пользователя, удаляя авторизационную куку

Попробуй описать алгоритм этих функций словами или кодом.

Пароли не запоминаются, а хешируются, есть урок: https://github.com/codedokode/pasta/blob/master/security/password-hashing.md

> действия на сайте


Создается таблица в БД. При каждом действии пользователя в нее добавляется запись. Можно писать действия в лог-файл. Можно использовать Google Analytics, где это уже сделано.

> подгрузка видосов,


Тут куки не причем. Сформулируй конкретную задачу.

> сохранение действий.


Это по моему то же, что и выше. Делается табличка или файл.
653 1146703
>>46079

if/else и new не подойдет?

Прочти статью https://habrahabr.ru/post/153225/

>>45734

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

>>45942

В смысле, отправка HTTP/2 запросов? Или их прием? Обычно за второе веб-сервер, а не PHP, отвечает. А первое вроде есть в расширении curl.

>>45903

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

Ну например: надо сделать авторизацию на сайте, и такие функции:

- регистрация: функция получает на вход логин, пароль и "запоминает" их где-то
- проверка данных: функция получает на вход логин, пароль, и проверяет, правльные ли они
- вход на сайт: функция получает на вход логин, пароль, если они верные, то выставляет некую куку
- проверка залогиненности: функция проверяет по кукам, залогинен ли текущий пользователь, если да, то возвращает его логин, если нет - null
- выход: вызов функции "разлогинивает" пользователя, удаляя авторизационную куку

Попробуй описать алгоритм этих функций словами или кодом.

Пароли не запоминаются, а хешируются, есть урок: https://github.com/codedokode/pasta/blob/master/security/password-hashing.md

> действия на сайте


Создается таблица в БД. При каждом действии пользователя в нее добавляется запись. Можно писать действия в лог-файл. Можно использовать Google Analytics, где это уже сделано.

> подгрузка видосов,


Тут куки не причем. Сформулируй конкретную задачу.

> сохранение действий.


Это по моему то же, что и выше. Делается табличка или файл.
654 1146704
>>45890

Теория программирования не научит тебя писать читаемый код или правильно использовать ООП. Или быстро решать задачу.

>>45789

Код надо выравнивать. У тебя он прижат влево (ты прямо в ideone пишешь? Установи notepad++, sublime text, netbeans, eclipse pdt, phpstorm или другой редактор кода) и потому читать очень тяжело. Или пропусти код через phpformatter.com.

> $amount7 = 02020200;


Это число в 8-чной системе счисления:

- что такое 8-чные числа https://ru.wikipedia.org/wiki/Восьмеричная_система_счисления
- мануал, где говорится о том что числа с 0 восьмеричные: http://php.net/manual/ru/language.types.integer.php

И когда ты пишешь 015, то PHP это понимает как 8-чную форму числа 8 + 5 = 13.

По коду:

> array_push


Проще писать $array[] = $string;

> $hundWithoutDec


hundreds

> if ($num == 0) {


> return $num;


надо возвращать, не 0, а "ноль"

> $hundDec


lastTwo, tensAndUnits

> $hundDecWithoutOne


units, ones

> hundredThous


thousands

> hundWithoutMil


rest, remainder, lastThreeDigits

> $fem = $hundWithoutMil % 10;


$female не надо вычислять - оно всегда равно 1 для тысяч ("тысяча" женского рода) и 0 для миллионов/единиц.

> $numberToString = array();


result, string

> $mill = spellSmallNumber($millions,NULL);


> array_push($numberToString,$mill ,NULL);


$result[] = spellSmallNumber($millions, NULL);

Самое главное, исправь форматирование и пройдись по именам переменных - сделай их попонятнее.

А так, алгоритм верный, все почти готово.
654 1146704
>>45890

Теория программирования не научит тебя писать читаемый код или правильно использовать ООП. Или быстро решать задачу.

>>45789

Код надо выравнивать. У тебя он прижат влево (ты прямо в ideone пишешь? Установи notepad++, sublime text, netbeans, eclipse pdt, phpstorm или другой редактор кода) и потому читать очень тяжело. Или пропусти код через phpformatter.com.

> $amount7 = 02020200;


Это число в 8-чной системе счисления:

- что такое 8-чные числа https://ru.wikipedia.org/wiki/Восьмеричная_система_счисления
- мануал, где говорится о том что числа с 0 восьмеричные: http://php.net/manual/ru/language.types.integer.php

И когда ты пишешь 015, то PHP это понимает как 8-чную форму числа 8 + 5 = 13.

По коду:

> array_push


Проще писать $array[] = $string;

> $hundWithoutDec


hundreds

> if ($num == 0) {


> return $num;


надо возвращать, не 0, а "ноль"

> $hundDec


lastTwo, tensAndUnits

> $hundDecWithoutOne


units, ones

> hundredThous


thousands

> hundWithoutMil


rest, remainder, lastThreeDigits

> $fem = $hundWithoutMil % 10;


$female не надо вычислять - оно всегда равно 1 для тысяч ("тысяча" женского рода) и 0 для миллионов/единиц.

> $numberToString = array();


result, string

> $mill = spellSmallNumber($millions,NULL);


> array_push($numberToString,$mill ,NULL);


$result[] = spellSmallNumber($millions, NULL);

Самое главное, исправь форматирование и пройдись по именам переменных - сделай их попонятнее.

А так, алгоритм верный, все почти готово.
655 1146705
>>45631

> наверное самое эффективное решение это выдавать ссылки на файл в публичной папке, а в этой папке отключить обработку скриптов.



Тут есть подвох, что файлы могут быть с самыми разными именами: file.php, .htaccess, файл из иероглифов. И это требует тщательной настройки сервера - стоит сделать ошибку и он начнет радостно выполнять php-файлы. Плюс, может ты захочешь считать статистику скачиваний, ограничивать доступ.

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

> Каким образом в реальном мире производятся фоновые задачи?


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

Использовать БД не принципиально - можно например постить задачи, сообщения о прогрессе, ошибке/успехе в очередь сообщений вроде RabbitMQ. Как удобнее. Можно использовать и то, и другое.

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

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

Если ты ищешь готовую функцию, то такой нет. Если ты думаешь, что PHP ограничен выполнением скриптов при вводе URL в адресную строку, то ты ошибаешсья - программу PHP можно запустить отдельно от веб-сервера, вручную или прописав ее в автоматический запуск при включении сервера под наблюдением супервизора.

> По наводке из статьи опа прочитал про gearman, мало что понял,


Задавай вопросы

> есть еще какой-то крон


Ну так изучи его.

> Вот как например ютуб конвертирует видео?


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

По Ютубу есть кое-какая инфа тут:

- https://www.insight-it.ru/highload/2008/arkhitektura-youtube/
- https://www.insight-it.ru/highload/2012/arkhitektura-youtube-2012/

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


Нет, с чего бы? Только неэффективно ради превьюшки качать огромную картинку. Но конечно, это зависит от настройки сервера - если ты скажешь ему, что картинки надо выполнять как php-скрипты, то все возможно.
655 1146705
>>45631

> наверное самое эффективное решение это выдавать ссылки на файл в публичной папке, а в этой папке отключить обработку скриптов.



Тут есть подвох, что файлы могут быть с самыми разными именами: file.php, .htaccess, файл из иероглифов. И это требует тщательной настройки сервера - стоит сделать ошибку и он начнет радостно выполнять php-файлы. Плюс, может ты захочешь считать статистику скачиваний, ограничивать доступ.

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

> Каким образом в реальном мире производятся фоновые задачи?


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

Использовать БД не принципиально - можно например постить задачи, сообщения о прогрессе, ошибке/успехе в очередь сообщений вроде RabbitMQ. Как удобнее. Можно использовать и то, и другое.

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

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

Если ты ищешь готовую функцию, то такой нет. Если ты думаешь, что PHP ограничен выполнением скриптов при вводе URL в адресную строку, то ты ошибаешсья - программу PHP можно запустить отдельно от веб-сервера, вручную или прописав ее в автоматический запуск при включении сервера под наблюдением супервизора.

> По наводке из статьи опа прочитал про gearman, мало что понял,


Задавай вопросы

> есть еще какой-то крон


Ну так изучи его.

> Вот как например ютуб конвертирует видео?


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

По Ютубу есть кое-какая инфа тут:

- https://www.insight-it.ru/highload/2008/arkhitektura-youtube/
- https://www.insight-it.ru/highload/2012/arkhitektura-youtube-2012/

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


Нет, с чего бы? Только неэффективно ради превьюшки качать огромную картинку. Но конечно, это зависит от настройки сервера - если ты скажешь ему, что картинки надо выполнять как php-скрипты, то все возможно.
656 1146706
>>45621

Можно всегда показать код и задать вопрос.

>>45606

Это числа в 8-чной системе счисления: http://php.net/manual/ru/language.types.integer.php

>>45497

Код покажи.

Также, есть пример кода в сети - он похож на твой? http://code.iamkate.com/php/sending-files-using-curl/

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

>>45457

Можно смотреть на библиотеки крупных компаний: Гугл/Яндекс. А так, я не смогу сформулировать требования, думаю, тут те же подходы, что и при написании внутреннего кода, только побольше комментариев и документации. Чтобы код был простой и логичный, без побочных эффектов и "магии".

Примеры:

- https://github.com/google/google-api-php-client (он сложный, так как там много API)
- https://github.com/nixsolutions/yandex-php-library

>>45436

Трудно комментировать, не зная постановки задачи.

>>45426

Что они вообще пришли и что нет ошибки. Ну и может у тебя какие-то дополнительные запреты есть.
656 1146706
>>45621

Можно всегда показать код и задать вопрос.

>>45606

Это числа в 8-чной системе счисления: http://php.net/manual/ru/language.types.integer.php

>>45497

Код покажи.

Также, есть пример кода в сети - он похож на твой? http://code.iamkate.com/php/sending-files-using-curl/

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

>>45457

Можно смотреть на библиотеки крупных компаний: Гугл/Яндекс. А так, я не смогу сформулировать требования, думаю, тут те же подходы, что и при написании внутреннего кода, только побольше комментариев и документации. Чтобы код был простой и логичный, без побочных эффектов и "магии".

Примеры:

- https://github.com/google/google-api-php-client (он сложный, так как там много API)
- https://github.com/nixsolutions/yandex-php-library

>>45436

Трудно комментировать, не зная постановки задачи.

>>45426

Что они вообще пришли и что нет ошибки. Ну и может у тебя какие-то дополнительные запреты есть.
657 1146707
>>45379

species можно сделать ENUM или внешним ключом (ссылкой) на таблицу видов животных, если их ограниченное количество.

> список владельцев с полями, по id животного


> список животных с полями, по id владельца


> информацию по владельцу(ам), по некоторой известной инфе о животном (клеймо, микрочип)



Запросом SELECT с JOIN. Ты изучал джойны? Если нет, то изучи.

>>45388

> тормознутые транзакции откинуть


Это бессмысленное утверждение. Что значит "тормознутые транзакции"? В случае InnoDB любое изменение данных это транзакция.

> Главное чтоб быстро выбирало крупные данные и без лишних полей.


Транзакции тут точно не при чем - они относятся к изменению данных.

>>45329

>тормозов из-за транзакций.


Почему ты решил, что дело в них? Может, у тебя индексы не сделаны? диск медленный? памяти мало выделено? еще что-то не так?

Тебе надо научиться настраивать MySQL, а также профилировать запросы. например, освоить команду EXPLAIN, ну и посмотреть в htop, iotop на процесс MySQL - сколько он ест памяти, CPU, диска.

Внешние ключи и транзакции экономят твое время на исправление багов в данных в БД.

>>45170

Это называется Roadmap - гугли "php roadmap". Но, увы, я там ничего не нашел.

>>45220

Попробуй сдампить echo bin2hex($s), где $s - строка с кириллицей, полученная через fgets() и напиши что получится - может, это даст ответ. Может, там какие-то коды есть, которые интерпретируются как перевод строки.

Так не сказать.
657 1146707
>>45379

species можно сделать ENUM или внешним ключом (ссылкой) на таблицу видов животных, если их ограниченное количество.

> список владельцев с полями, по id животного


> список животных с полями, по id владельца


> информацию по владельцу(ам), по некоторой известной инфе о животном (клеймо, микрочип)



Запросом SELECT с JOIN. Ты изучал джойны? Если нет, то изучи.

>>45388

> тормознутые транзакции откинуть


Это бессмысленное утверждение. Что значит "тормознутые транзакции"? В случае InnoDB любое изменение данных это транзакция.

> Главное чтоб быстро выбирало крупные данные и без лишних полей.


Транзакции тут точно не при чем - они относятся к изменению данных.

>>45329

>тормозов из-за транзакций.


Почему ты решил, что дело в них? Может, у тебя индексы не сделаны? диск медленный? памяти мало выделено? еще что-то не так?

Тебе надо научиться настраивать MySQL, а также профилировать запросы. например, освоить команду EXPLAIN, ну и посмотреть в htop, iotop на процесс MySQL - сколько он ест памяти, CPU, диска.

Внешние ключи и транзакции экономят твое время на исправление багов в данных в БД.

>>45170

Это называется Roadmap - гугли "php roadmap". Но, увы, я там ничего не нашел.

>>45220

Попробуй сдампить echo bin2hex($s), где $s - строка с кириллицей, полученная через fgets() и напиши что получится - может, это даст ответ. Может, там какие-то коды есть, которые интерпретируются как перевод строки.

Так не сказать.
658 1146708
>>44614

Не надо смотреть на моду, надо смотреть на постановку задачи.

>>44424

Почему не установить и не настроить PHP/MySQL + Apache если встроенный PHP сервер не сработает?

>>44022

Если ты слабо знаешь программирование, то проще взять CMS. Некоторые Друпал рекомендуют, хотя он не простой. С ModX не знаком.
изображение.png29 Кб, 753x582
659 1146717
>>46702

>Напиши список классов, полей и методов (без кода) и обсудим.



Окей, тогда отталкиваясь от совета:

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


Сделаю максимально просто для начала.

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

1. Ну для начала нужен класс Animal, у него будут поля $x и $y - это банально место положение на нашей карте.
Далее например будет абстрактный метод lookAround() - который будет переопределен для мышки и кошки отдельно, пока сложно понять что он должен возвращать, допустим пусть возвращает все доступные животному клетки(координаты) со значением привлекательности каждой из этих клеток.

Опять же вот думаю об этом, и если у нас например объекты хранят в себе координаты, то для кошечки, когда она смотрит вокруг, а она будет смотреть на всё поле, для КАЖДОЙ долбанной клеточки на поле будет вызываться перебор ВСЕХ объектов в мире, что бы высчитать для этой клеточки привлекательность, ведь надо что бы рядом с клеточкой было как можно больше мышек и как можно меньше других кошек скажем. Будет адуха адская в плане неоптимальности решения, ну да и черт с ним.

Допустим посмотрели вокруг, и нужно сделать ход, для этого другой метод, которому уже передаем массив клеток с их привлекательностью, и кошечка уже принимает решение куда сходить.
Либо кошечка ходит просто на САМУЮ привлекательную клетку из доступных, либо например сделать так, что бы она ходила на самую привлекательную клетку, из тех, которые лежат на кротчайших путях к САМОЙ привлекательной клетке на поле.
Условно говоря пикрил (пока рисовал, думал что кошечка ходит на 1 клетку за ход, а там вроде бы на 2 по условию задачи, так что не суть, просто как пример)

Для мышки аналогично сделать, опять же перебирать все все объекты на поле, что бы вычислить привлекательность для каждой из тех клеток которые она видит, благо видит она всего +-4 в каждую сторону, так что итераций будет в сотни раз меньше в случае средненького поля.
Ну и методы подсчета привлекательности переделать, подальше от кошек, стен и скопления других мышей ей прописать например. Ну или наоборот что бы жалась к другим мышкам, глядишь в толпе выжить проще и съедят не тебя (бедная глупая мышка, только проще для кошки будет с каждым ходом становиться, когда они в кучке)

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

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

Ну и какой-нибудь класс по типу gameLoop, для того что бы в него всё свалить, запускать на каждой итерации которой все живые животные по очереди будут ходить, а потом будет отрисовываться карта. И так столько сколько задано.
изображение.png29 Кб, 753x582
659 1146717
>>46702

>Напиши список классов, полей и методов (без кода) и обсудим.



Окей, тогда отталкиваясь от совета:

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


Сделаю максимально просто для начала.

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

1. Ну для начала нужен класс Animal, у него будут поля $x и $y - это банально место положение на нашей карте.
Далее например будет абстрактный метод lookAround() - который будет переопределен для мышки и кошки отдельно, пока сложно понять что он должен возвращать, допустим пусть возвращает все доступные животному клетки(координаты) со значением привлекательности каждой из этих клеток.

Опять же вот думаю об этом, и если у нас например объекты хранят в себе координаты, то для кошечки, когда она смотрит вокруг, а она будет смотреть на всё поле, для КАЖДОЙ долбанной клеточки на поле будет вызываться перебор ВСЕХ объектов в мире, что бы высчитать для этой клеточки привлекательность, ведь надо что бы рядом с клеточкой было как можно больше мышек и как можно меньше других кошек скажем. Будет адуха адская в плане неоптимальности решения, ну да и черт с ним.

Допустим посмотрели вокруг, и нужно сделать ход, для этого другой метод, которому уже передаем массив клеток с их привлекательностью, и кошечка уже принимает решение куда сходить.
Либо кошечка ходит просто на САМУЮ привлекательную клетку из доступных, либо например сделать так, что бы она ходила на самую привлекательную клетку, из тех, которые лежат на кротчайших путях к САМОЙ привлекательной клетке на поле.
Условно говоря пикрил (пока рисовал, думал что кошечка ходит на 1 клетку за ход, а там вроде бы на 2 по условию задачи, так что не суть, просто как пример)

Для мышки аналогично сделать, опять же перебирать все все объекты на поле, что бы вычислить привлекательность для каждой из тех клеток которые она видит, благо видит она всего +-4 в каждую сторону, так что итераций будет в сотни раз меньше в случае средненького поля.
Ну и методы подсчета привлекательности переделать, подальше от кошек, стен и скопления других мышей ей прописать например. Ну или наоборот что бы жалась к другим мышкам, глядишь в толпе выжить проще и съедят не тебя (бедная глупая мышка, только проще для кошки будет с каждым ходом становиться, когда они в кучке)

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

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

Ну и какой-нибудь класс по типу gameLoop, для того что бы в него всё свалить, запускать на каждой итерации которой все живые животные по очереди будут ходить, а потом будет отрисовываться карта. И так столько сколько задано.
660 1146724
>>46717

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

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



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

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

> Опять же вот думаю об этом, и если у нас например объекты хранят в себе координаты, то для кошечки, когда она смотрит вокруг, а она будет смотреть на всё поле, для КАЖДОЙ долбанной клеточки на поле будет вызываться перебор ВСЕХ объектов в мире, что бы высчитать для этой клеточки привлекательность, ведь надо что бы рядом с клеточкой было как можно больше мышек и как можно меньше других кошек скажем



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

И еще мысль. Ты вот сейчас мыслишь по-программистски - надо любой ценой оптимизировать потребление CPU. Но в реальной работе программиста бывают и другие варианты:

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

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

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

В твоем случае, я уже писал выше, можно 1) использовать индексы для поиска ближайщих соседей, причем, что важно, можно сначала писать без индексов и только потом их добавить 2) можно что-то кешировать, например, если несколько кошек делают одни и те же вычисления, можно закеширвать их результаты.

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

У нас все таки задача больше на ООП, чем на игровые стратегии.
660 1146724
>>46717

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

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



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

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

> Опять же вот думаю об этом, и если у нас например объекты хранят в себе координаты, то для кошечки, когда она смотрит вокруг, а она будет смотреть на всё поле, для КАЖДОЙ долбанной клеточки на поле будет вызываться перебор ВСЕХ объектов в мире, что бы высчитать для этой клеточки привлекательность, ведь надо что бы рядом с клеточкой было как можно больше мышек и как можно меньше других кошек скажем



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

И еще мысль. Ты вот сейчас мыслишь по-программистски - надо любой ценой оптимизировать потребление CPU. Но в реальной работе программиста бывают и другие варианты:

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

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

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

В твоем случае, я уже писал выше, можно 1) использовать индексы для поиска ближайщих соседей, причем, что важно, можно сначала писать без индексов и только потом их добавить 2) можно что-то кешировать, например, если несколько кошек делают одни и те же вычисления, можно закеширвать их результаты.

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

У нас все таки задача больше на ООП, чем на игровые стратегии.
661 1146729
>>46724
Я как раз и пытаюсь выйти на новый уровень, потому что я уже поработал 2 года говношлепом на фреймворке, когда тупо херачишь говнокод быстрее быстрее, лишь бы работало по уже отработанной схеме, просто потому что надо. Ладно, не буду об этом.

Не могу в общем при написании отделаться от ступора, например когда тебе в мир нужно передать объект животное когда ты его вроде бы там логично спавнишь, и при этом же в животное передовать мир, когда ты смотришь вокруг, получается такая вот какая-то взаимозависимость, к чему я ВООБЩЕ НЕ привык на своих нубоработах.

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


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

>1) использовать индексы для поиска ближайщих соседей, причем, что важно, можно сначала писать без индексов и только потом их добавить


Не понял что тут имеется в виду? Хранить отдельно координаты? скажем еще и что бы мир знал что у него в какой клетке и через него спрашивать а кто тут у нас в округе сидит, вместо того что бы опрашивать все объекты в мире? Я над этим уже много думал. Наверное дублирование всё же нужно в хорошей системе. Просто потому что ну как с базами, если всё пытаться к третьей форме приводить, то ты очумеешь делать простейшие запросы собирая страничку юзера, так и тут, одуреешь перебирать все объекты мира, в надежде узнать есть ли кто рядом в соседней клетке, КОГДА МОЖНО ПРОСТО ПРОДУБЛИРОВАТЬ ИНФОРМАЦИЮ 1 РАЗ, и иметь возможность спросить у overseer-объекта кто у нас там рядом в соседней клетке. Ты об этом?
662 1146730
>>46729

Под индексами я имею в виду специальные структуры данных, оптимизированные для поиска ближайших объектов, я упомянул их тут >>46702

То есть индекс здесь это класс, который ищет объекты в определенном радиусе быстрее, чем полным перебором.
663 1146732
>>46705
Архивировать на клиенте файлы недопустимых расширений, отправлять на сервер файл вида file.php.tar.gz и хранить на сервере в виде архива, будет плохой идеей? Я тоже решаю эту задачу, только у меня там еще потуга сделать более или менее полноценный фронт-енд.
664 1146755
>>46698

>Они просто общаются с веб-сервером по HTTP вместо CGI/FastCGI.


И да, и нет. Контейнер сервлетов - такой же полноценный веб сервер. Да и несервлетные приложения тоже.

>В сравнении с CGI это усложняет приложение (ты вряд ли напишешь полноценный HTTP сервер на bash, а с CGI можно работать хоть из bash скрипта), приводит к дублированию функционала (разбором HTTP мог бы заниматься только веб-сервер).


Ты же не пишешь свой сервер. Ты точно так же берёшь томкат/аппликейшн сервер/библиотеку и пользуешься. И опять: веб сервер - это не только апач или нджинкс.

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


Они работают полноценно. И на этом основаны всякие ништяки микросервисов вроде service discovery и client side load balancing.

>>46700
Паттерны (могу ошибаться) начал собирать Фаулер.
Фабрику, синглтон и всякие прокси описаны задолго до него бандой четырех. Фаулер именно по ентерпрайзным паттернам угарел.
665 1146757
>>46661
Это то же самое говно, что на рутрекере. Написано, что 2016, но по факту там материалы за 2015-2016.
666 1146793
>>46757
Ладно, поясню тебе на пальцах. Там php 5.5 - что самое главное. Там уже есть ооп и прочее. Те изменения, что завезли пхп 7, тебе всё равно в первый год не понадобятся, я базарю.

Во вторых подобный курс - это всё равно лишь основы языка и не более. Тебя научат как сделать простенький сайт на коленке с несложной версткой и основами владения mysql опять же.

Что в подобном курсе от 2014, что от 2018, тебе будут объяснять по сути одно и тоже, тупо в мелочах отличия, которые ты забудишь через пару дней - базарю. А еще если ты не будешь сидеть и ждать пока тебе подкинут идеальный гайд как стать синьёром-php за 5 дней без регистрации и смс, а прямо сразу посомтришь хотя бы первый день, то ты уже бы сделал для своего потенциального будущего куда больше, чем возможно за всю предыдущую жизнь в школе (и универе).
667 1146803
>>46681
Вкатился после просмотров его уроков. Смотрел дохуя разного - все остальное васянская хуйня
668 1146806
>>46757
Ну я год назад смотрел. Знач ошибся. А вообще новые от него я бы и сам глянул
download.png212 Кб, 1852x1008
669 1146883
>>46706

>Трудно комментировать, не зная постановки задачи.



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

Хочу помацать InnoDB за транзакции и форейгн-ключики.

Как видишь, уже на диаграмме пиздец, а чо будет дальше та?

Почитал про джойны, примеры работают, а как их к этой базе применить не доходит.

Еще внешние ключи ну никак не могу понять, я вот их наставил тут, но походу немного далеко уехал с ними.
222.png15 Кб, 768x614
670 1146993
Есть массив массивов вот такого вида. Каждая запись в нем, это: число, буква, и еще один массив со строками.

Как мне отсортировать этот массив по букве? Чтобы записи с одинаковыми буквами были сгруппированы внутри большого массива.
671 1147161
>>46793
Понял, спасибо.
672 1147201
>>46993
usort(): http://php.net/manual/en/function.usort.php

<?php
$a = [[0, 'b', 'b string'],
[1, 'a', 'a string'],
[2, 'd', 'd string'],
[3, 'f', 'f string'],
[4, 'e', 'e string'],
[5, 'a', 'a2 string']];

usort($a,
function($a, $b){
if ($a[1] == $b[1]) {
return 0;
}
elseif ($a[1] < $b[1]) {
return -1;
} else {
return 1;
}
});
673 1147205
>>47201
Дополню тебя, что в PHP7 (который вышел аж в 2015-м году) есть spaceship оператор и cтену if'ов в колбеке можно заменить одной строкой: return $a <=> $b;

>1146129


>Еще мне порой очень сильно не хватает фантазии на то, чтобы придумать название переменной.



Не можешь дать нормальное имя переменной - не до конца понимаешь, что в ней находится. Плохое именование от непонимания.
1345.jpg39 Кб, 600x748
674 1147307
Создал электронного Льва Толстого, анон сойди с небес и подскажи какой из вариантов решении более правильный.

https://ideone.com/cMvAiV
https://ideone.com/A1PoXo

Почему во втором решении код выглядит как не читабельная каша?
675 1147316
>>47307
там 2 строчки кода в каждом решении, он не может быть неправильным.

>Почему во втором решении код выглядит как не читабельная каша?


Потому что ты не привык просто пока к каким-то операторам или синтаксису и тебе нужно больше практиковаться.

Не парься над такими легкими задачами, то что ты решил её двумя способами - это уже хорошо само по себе, а пытаться вычислить идеальное решение - это глупо, решай так, как тебе больше нравится, думай об этом как о СВОЁМ СОБСТВЕННОМ стиле программирования.

ебучая система образования сука с её заучиванием идеальных путей и алгоритмов, когда тебя именно кормят идеальными путями решения всяких уравнений и прочего говна, а потом ты по жизни везде пытаешься под это подстроиться :( Вместо того что бы просто решать проблемы, ты ищешь идеальный, "правльный" путь её решения. Тьфу пиздос кароче горит аж, потому что у меня тупо саем по жизни
676 1147348
>>43562
Так никто и не проверит? Я что-то не так сделал?
677 1147350
>>47348
Всё так, ебашь дальше.
678 1147404
Ребят, есть скрипт, парсящий xml-документ. Скажите, в какую сторону гуглить, если я хочу, чтобы xml-документ для парсинга и вывода результатов на страницу выбирался с помощью диалогового окошка?
679 1147412
>>46717

>кошечка

680 1147520
>>47316
спасибо
Node JS 681 1147710
Интересует мнение пехепешников.
Сам я пхп макакер, с сайтами приходится работать редко, в основном пишу разные парсеры, ботов, спамеры и пр хуйню-малафью. Ничего другого кроме пхп не знаю когдато знал жс и немного кресты но нихуя не помню. Часто ловлю себя на мысле "ах вот если бы то или се", "вот еслибы запустить куски моего кода асинхронно и кококо". Подумываю взяться учить ноду, стоит ли этим заниматься в 2к18? Спешить никуда не планирую, буду в свободное время посматривать уроки, но может стоит обратить внимание на чтото более актуальное?
682 1147796
>>47710
напиши в дискорд hiremind#0595, как раз ищем нечто такого же, неспешного джуна.
683 1147860
>>47796
сенкс, но у меня есть раб-ота, просто хочу попробовать в другой язык
684 1148023
>>43225

>А еще, если вдруг ты не очень уверен в ООП, то у меня еще есть пара задач - про Гостиницу и Агенство - не хочешь хотя бы глянуть? >https://phpclub.tech/pr/chain/1108694/



Сап пхпач, что то тред совсем утонул, еле нашел.

Запилил немного задание про гостиницу.
https://github.com/homohomozak/oop

Хранитель треда посмотри пожалуйста, в правильном ли я направлении двигаюсь?
685 1148069
>>35053 (OP)
Вкатываюсь в пхп после питона, возник вопрос: почему в пхп функцию можно вызвать до объявления?
686 1148072
>>48069
таков интерпритатор пхп, а тебя это смущает?
687 1148151
>>47710
А в чём фишка нодовской асинхронности? Может кто-нибудь расскажет? Ну тоесть я так понял это когда ты отправляешь несколько запросов, и они отрабатываются отдельным потоком каждый? Но ведь по факту там просто формирование очереди запросов и вся асинхронность получается чисто на бумаге. Или я не прав?
688 1148334
Я тут посмотрел вакансии на hh, примерно 30% компаний указывают что нужна техническая вышка.
У меня вопрос к устроившимся анонам, в остальных компаниях без вышки в большинстве случаев покажут на дверь?
689 1148355
>>48334
Если ты анон с нулем опыта и указана вышка, то скорее всего да.
690 1148376
>>48355
то есть чуваков с опытом/портфолио берут и без вышки?
вот допустим я с головой ухожу в backend может ли сказаться нехватка знаний по высшей математике/азов программирования что изучают в профильных вузах?
691 1148377
>>48376

> может ли сказаться


в будущем, при разработке чего-либо серьезного
692 1148380
>>48376
А что мешает п_одучить математику или "азы программирования"? Открываешь Кнута или Кормена и читаешь
693 1148402
>>48380

> Открываешь Кнута или Кормена и читаешь


И ты попрежднему нихуя не понимаешь. Зато можешь говорить, что то или иное словечко видел у кнута.
694 1148405
>>48380
А что мешает п_одучить математику или "азы хирургии"? Открываешь учебник по биологии за 11 класс и читаешь.
Вот примерно также ты сейчас сказал.
На деле тебе нужны будут тонны практики. Так что советую её получить.
695 1148406
>>48376
В сурьезные конторы, да и в некоторых случаях заграницу без вышки не выйдет. Никто не запрещает попробовать, откажут ну и хуй с ними.
Во всех остальных случаях не так жеско. Где то якобы требуют, а на деле похуй, где то напрямую говорят нам насрать. На срилансе вообще никого не ебет, что ты там закончил, главное пили таски и не лажай сильно.

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

А если английский знаешь, то пилишь портфолио или нарабатываешь опыт на галерах, и все получится. Книжки можешь почитать, но это для общего развития. Ты больше узнаешь из практики, чем из книг.
696 1148409
>>48406
Как же я обожаю этот тред. Тут самфые лучшие и добрые аноны сидят. Спасибо и сори за офф. Мимопроходил.
697 1148421
>>48405
В универе ты эту практику всё равно не получишь, так что разницы не вижу
image.png675 Кб, 1110x478
698 1148424
>>48023
Бамп, хранитель треда, помоги.
699 1148429
>>48405
При чём тут биология за 11 класс? Чел спрашивал про азы программирования, а их, т.е. алгоритмы, структуры данных и прочее, как раз в этих книгах и можно найти (плюс еще пара книг по архитектуре, сетям, операционным системам и пр).
А дальше да, уже дело за практикой.

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

Ты не опроверг мои слова.
700 1148431
>>48429
Так я и не хотел опровергнуть, я хотел дать другую перспективу точки зрения. Ну и я сам прочитал овер 9000 книг, но на работу меня не брали пока не появилось более менее вменяемое портфолио и кое какой рассказ об участи в проектах. Никого не смутило что проэкты я сам для себя придумал и написал.
701 1148433
>>48431
Потому что работодателю по большей части пофиг на твои знания, будь ты хоть ученым в области информатики. Он заинтересован только в том, сможешь ли ты выполнить свою работу или нет, сможет ли он на тебе заработать или нет.
ХОД КОНЕМ ГЕНИАЛЬНО!.png18 Кб, 800x900
702 1148481
Пишу свой первый бложик и реквеструю у анона не много мудрости.
В БД лежат категории и статьи, хочу выводить каскадом по 1 блоку с n-количеством статей своей категории, следующий блок новой категории уже идет справа, как на пикрелейтед.

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

Можно запрашивать из бд четные категории влево, а нечетные вправо, но тогда как быть с блоками ?
703 1148482
>>48429
Твои азазы, как мотематика, пригождаются, если ты илонмашк. Простому джуну в 99% они не нужны. А что нужно будет освоит в процессе.
Безымянный.png32 Кб, 718x386
704 1148490
Братцы, поясните, как лучше всего хранить прикрепленные файлы к постам на мелкопараше. Сделаю табличку аттачей, но какая структура папок будет наиболее верной. Папочка для каждого треда или как?
705 1148567
За сколько дней вы сделали студентов?
Еще с осени не могу закончить))) Бросал раз 5.
За сколько часов такую задачу должен сделать джун?
706 1148575
Реквестирую гайд по пхп для не новичка в программировании. Чтобы не поясняли 5 лет что такое переменная, а сразу к сути. Желательно видосик, хотя врядли такое существуют.
707 1148577
>>48376
1. Программирование наверное единственная профессия, где на образование смотря в последнюю очередь т.к. тут реально нужно уметь делать и это важно в первую очередь.
2. Образование может быть плюсом если ты нубяра полнейший. Друг учился, его взяли работать т.к. понимали, что он учится соответственно его нубство - явление временное и он развивается почучуть, а не забил хуй.

Кукареки про математику придумали долбоебы, которые никогда не работали, нахуй тебе ее знать, сука, объясни? Сам хоть понимаешь? Если конечно под знанием математики подразумевают умение сложить 2+2, то это везде надо уметь и только школьный довнич может назвать это "знанием математики", а не признаком недауна.

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

И самое главное - опыт, чем быстрее начнешь работать - тем лучше. Опытного человека всегда видно и всем похуй есть у него образование или нет, чем больше опыта тем более похуй тебе будет на образование и тем менее будет стоять вопрос "если уволят куда я пойду"
708 1148585
>>48575
Скачай Катерова да пропусти пару тем
709 1148590
>>48577
Ты лучше скожи когда оп придет...
710 1148812
Такой вопрос, а насколько безопасна такая регистрация и авторизация через куки как в задаче про студентов? Куки же можно угнать у пользователя.
711 1148818
Как сделать чтобы данные из post формы не сохранялись? Сделал говноскрипт - шортлинкер aka goo.gl, создает файлы с рандомным именем с редиректом внутри, ввожу в него ссылку, он создает, все заебись, а потом обновляю страницу, и он с той же ссылкой (которая уже не введена) создает еще один.
712 1148838
>>48818
Покажи код
713 1148841
>>48812

>Куки же можно угнать у пользователя


Тоже хотелось бы узнать подробнее об этом вопросе

Куки можно угнать:
1. С помощью xss

Чтобы избежать этого нужно выводить все вводимые данные пользователем с помощью функции htmlspecialchars(...)
И, дополнительно, поставить кукисам параметр httpOnly

https://github.com/codedokode/pasta/blob/master/security/xss.md

https://secure.php.net/manual/en/function.htmlspecialchars.php
https://secure.php.net/manual/en/function.setcookie.php
https://en.wikipedia.org/wiki/Cross-site_scripting

2. Проведя атаку "Человек посередине"

Чтобы это избежать, нужно использовать зашифрованное соединение, например https

https://ru.wikipedia.org/wiki/Атака_посредника

3. Имея доступ к устройству пользователя

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

Почему бытует мнение, что переход по незнакомым ссылкам чревато? Посторонние сайты же не имеют доступа к кукам вне своего домена. И единственное чем может быть это полезно, это сбором информации о клиенте и его ip-адресе, а так же рамещением фейковой формы, для залогинивания, что, на мой взгляд, совершенно бесполезно.
713 1148841
>>48812

>Куки же можно угнать у пользователя


Тоже хотелось бы узнать подробнее об этом вопросе

Куки можно угнать:
1. С помощью xss

Чтобы избежать этого нужно выводить все вводимые данные пользователем с помощью функции htmlspecialchars(...)
И, дополнительно, поставить кукисам параметр httpOnly

https://github.com/codedokode/pasta/blob/master/security/xss.md

https://secure.php.net/manual/en/function.htmlspecialchars.php
https://secure.php.net/manual/en/function.setcookie.php
https://en.wikipedia.org/wiki/Cross-site_scripting

2. Проведя атаку "Человек посередине"

Чтобы это избежать, нужно использовать зашифрованное соединение, например https

https://ru.wikipedia.org/wiki/Атака_посредника

3. Имея доступ к устройству пользователя

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

Почему бытует мнение, что переход по незнакомым ссылкам чревато? Посторонние сайты же не имеют доступа к кукам вне своего домена. И единственное чем может быть это полезно, это сбором информации о клиенте и его ip-адресе, а так же рамещением фейковой формы, для залогинивания, что, на мой взгляд, совершенно бесполезно.
714 1148843
>>48567

>За сколько часов такую задачу должен сделать джун?


За 2-3 дня

Не не отчаивайся, я делал её 2 года https://github.com/someApprentice/Students/graphs/code-frequency
Зато сейчас могу решить её за сутки - полагаю, у каждого своя скорость
715 1148844
>>48490
В задаче на хостинг файлов есть рекомендации на этот счет: https://gist.github.com/codedokode/9424217#Удобство-администрирования-сервера
716 1148847
>>48481
Из бд запрашиваешь все нужные категории, а в представлении сортируешь и выводишь в блоки как тебе нужно

Например

<div class="content__left">
<? foreach($categories as $key => $category): ?>

<? if ($key % 2 == 1): ?>
...
<? endif; ?>

<? endforeach; ?>
</div>

<div class="content__right">
<? foreach($categories as $key => $category): ?>

<? if ($key % 2 == 0): ?>
...
<? endif; ?>

<? endforeach; ?>
</div>
717 1148848
>>47404
Гугли как в php обрабатывать форму

В шапке есть урок на эту тему: https://github.com/codedokode/pasta/blob/master/forms.md
718 1148872
>>48844
Понял, спасибо
719 1148899
>>48847
А потом все это обернуть в цикл, что бы левый и правый блоки чередовало. Спасибо.
720 1148916
>>48838
https://ideone.com/VM1bq4
Алсо, почему он из массива только цифры берет, и вообще берет не 5?
Алсо, насколько я понял, isset это не совсем то, что мне нужно для обработки нажатия. Что мне нужно?
721 1148917
>>48585
братюнь, ты вот рекомендуешь котерова качать, мне интересно, а ты сам где работаешь? у тебя тимлид проводит код ревью? заставляет тесты писать?
722 1148973
>>48818
После того, как сделал свою ссылку, делай рефреш страницы и всё.

P.S. Для шортлинкера лучше не использовать рандомные комбинации, а последовательно увеличивать последовательность символов.
723 1149017
>>48916

>Алсо, почему он из массива только цифры берет, и вообще берет не 5?


Не знаю, но с версией PHP7.2.2 берётся именно 5 https://3v4l.org/J9BpQ#output

Должно быть, это как-то связано с этим https://secure.php.net/manual/ru/migration72.incompatible.php#migration72.incompatible.rand-mt_rand-output

>Алсо, насколько я понял, isset это не совсем то, что мне нужно для обработки нажатия. Что мне нужно?


Тебе нужно $_SERVER['REQUEST_METHOD'] == 'POST'

https://secure.php.net/manual/ru/reserved.variables.server.php

А почему ты сохраняешь не в базу данных, а в файлы? И тем более в php скрипты? Лучше было бы в .json - как раз конструкция ключ -> значение
К тому же, у тебя должен быть отдельный php скрипт, который берёт параметр $_GET с ключом к твоей ссылки, и делает редирект - никаких $_SERVER['SERVER_NAME'] делать не нужно (http://htmlbook.ru/samhtml/ssylki/absolyutnye-i-otnositelnye-ssylki):

/redirect.php?key=foo42

<?php
if (isset($_GET['key'])) {
$key = $_GET['key'];

// открываем файл $key.json
// парсим хэш
// делаем редирект
}

А на странице с формой всё делается ещё проще:

if (форма отправлена) {
// валидируем ссылку
// создаем массив [$key => $url]
// преобразуем его в json
// сохраняем json
// перенаправляем на страницу с результатом и выводим ссылку на redirect.php?key=$key
}

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

Функции которые тебе могут понадобиться:
https://secure.php.net/manual/ru/function.json-encode.php обрати внимание на опции JSON_HEX_ https://secure.php.net/manual/ru/json.constants.php
https://secure.php.net/manual/ru/function.json-decode.php
https://secure.php.net/manual/ru/function.htmlspecialchars.php
https://secure.php.net/manual/ru/function.fclose.php
723 1149017
>>48916

>Алсо, почему он из массива только цифры берет, и вообще берет не 5?


Не знаю, но с версией PHP7.2.2 берётся именно 5 https://3v4l.org/J9BpQ#output

Должно быть, это как-то связано с этим https://secure.php.net/manual/ru/migration72.incompatible.php#migration72.incompatible.rand-mt_rand-output

>Алсо, насколько я понял, isset это не совсем то, что мне нужно для обработки нажатия. Что мне нужно?


Тебе нужно $_SERVER['REQUEST_METHOD'] == 'POST'

https://secure.php.net/manual/ru/reserved.variables.server.php

А почему ты сохраняешь не в базу данных, а в файлы? И тем более в php скрипты? Лучше было бы в .json - как раз конструкция ключ -> значение
К тому же, у тебя должен быть отдельный php скрипт, который берёт параметр $_GET с ключом к твоей ссылки, и делает редирект - никаких $_SERVER['SERVER_NAME'] делать не нужно (http://htmlbook.ru/samhtml/ssylki/absolyutnye-i-otnositelnye-ssylki):

/redirect.php?key=foo42

<?php
if (isset($_GET['key'])) {
$key = $_GET['key'];

// открываем файл $key.json
// парсим хэш
// делаем редирект
}

А на странице с формой всё делается ещё проще:

if (форма отправлена) {
// валидируем ссылку
// создаем массив [$key => $url]
// преобразуем его в json
// сохраняем json
// перенаправляем на страницу с результатом и выводим ссылку на redirect.php?key=$key
}

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

Функции которые тебе могут понадобиться:
https://secure.php.net/manual/ru/function.json-encode.php обрати внимание на опции JSON_HEX_ https://secure.php.net/manual/ru/json.constants.php
https://secure.php.net/manual/ru/function.json-decode.php
https://secure.php.net/manual/ru/function.htmlspecialchars.php
https://secure.php.net/manual/ru/function.fclose.php
724 1149019
>>48843

>correntPage


Исправь.
725 1149023
>>49019
Исправил
726 1149024
>>49023
Красиво конечно сделано. Приятно просматривать файлы, все понятно сразу что где куда. 2 года ты это постоянно делал или прерывался? Считаешь проект законченным?
727 1149026
>>49024
У меня были большие перерывы в год и по полгода... Я не помню уже

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

Я не сделал ничего, я просто делал, что мне говорил ОП треда
image.png66 Кб, 573x158
728 1149038
Как сделать так что бы он распознавал пробелы и буквы латиницы? Может есть какие флаги?
729 1149048
>>49038
Кури в сторону mb_ функций
730 1149061
>>49017
Нихуя себе ты накатал.

> Не знаю, но с версией PHP7.2.2 берётся именно 5


У меня вообще была версия 5 почему-то в вампе, лол. Переключил на 7.1.9, все также.

> Должно быть, это как-то связано с этим https://secure.php.net/manual/ru/migration72.incompatible.php#migration72.incompatible.rand-mt_rand-output


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

> Тебе нужно $_SERVER['REQUEST_METHOD'] == 'POST'


Блядь, охуеть, а именно конкретного онклика нет? Язык-костыль.

> А почему ты сохраняешь не в базу данных, а в файлы? И тем более в php скрипты? Лучше было бы в .json - как раз конструкция ключ -> значение


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

>>48973

> После того, как сделал свою ссылку, делай рефреш страницы и всё.


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

> P.S. Для шортлинкера лучше не использовать рандомные комбинации, а последовательно увеличивать последовательность символов.


В смысле увеличивать последовательность символов? Чтобы после сотого раза у меня моя короткая ссылка была длиннее чем какой-нить запрос в гугл на русике?
Алсо, наоборот же. Потому что тогда юзеру можно будет смотреть че там другие юзеры делают.
731 1149135
>>49061
Ты пиздец тупой, еще и быдлан, тебе уважаемый человек в треде отвечал вежливо, а ты хуйню несешь.

>В смысле увеличивать последовательность символов?


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

Поэтому если у тебя ссылки например были бы из цифр, то нельзя просто руярить случайное число /34533, /43234 /21387 ... /34533 - так по мере накопления у тебя будут тупо старые заменяться новыми и ты че совсем еблан рили?

/00001, /00002/, /00003, ... /99999 - все урлы равномерно заполнят все возможные комбинации чисел без пробелов и перезатираний.
732 1149167
Кто-нибудь поясните вкратце или дайте ссылку как на джеквери склепать комменты, как на дваче, конкретно ту часть, где тыкаешь мышкой в ид коммента на который отвечал и появляется окошко с этим комментом, и там можно ещё тыкнуть и появиться ещё окошко лесенкой... Короче, интересует именно как выстроить эту лесенку, как на дваче и чтобы она убиралась как на дваче, пре отводе мышки на коммент более высокого уровня либо вовсе с коммента. (Систему ссылок и получения данных комента по этой ссылке я уже сделал). Заранее спасибо.
Снимок экрана от 2018-03-03 22-05-39.png34 Кб, 599x381
733 1149168
не пойму в чём подвох, как работают эти padleft и padright, делал всё как на пикче и выводит еррор
https://ideone.com/8twAif
734 1149170
>>49168
У тебя функции pad% не объявлены.
735 1149202
>>49135

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


Лол, блядь. Быдлан я, охуеть. В треде про быдлоязык.

> Если ты рандомишь, то есть шанс что ты зарандомишь под новый запрос такой же урл, который ты уже отдавал когда-то.


Я написал про это под спойлером, васька сможет смотреть другие ссылки уменьшая число, а это как-то не комильфо. Я думаю 5-разрядного даже 16-ричного числа хватит чтобы нивелировать шанс перезаписи с лихвой, а ведь туда можно еще буков добавить. Да и вообще, можно просто сделать проверку на существование файла.
А как пофиксить кривой рандом так никто и не сказал.
image.png304 Кб, 705x368
736 1149203
>>48023
Бамп, опушка помоги :(
737 1149211
>>49202

> А как пофиксить кривой рандом так никто и не сказал


Все, я уже сам нагуглил, охуеть. Оказывается array_rand возвращает ключи, а не значения.
738 1149223
>>49061

>В смысле увеличивать последовательность символов


Возможно не совсем правильно выразился. Смотри.
Первая ссылка будет такой: shrt.er/0, вторая shrt.er/1, потом цифры закончатся и ты переходишь на буквы:
shrt.er/A
shrt.er/B
...
shrt.er/z

Потом добавляешь второй символ и всё заново:

shrt.er/00
shrt.er/01
...
shrt.er/zz

Ну и так далее.
Я сам делал шортенер с телеграм ботом даже, со статистикой переходов по странам,
времени и прочему
, но это очень тупой проект, ибо сервисов дохуя и новый никому не встрался.
739 1149230
У пыхи есть будущее в ближайшие 2.5 года?
Вопрос актуальный, т.к. учусь в Беларуси и попадаю на распределение, поменять место работы или стек не получится.
740 1149238
>>49230
Пыха стронг.
741 1149330
>>49202

>В треде про быдлоязык.


>Я думаю 5-разрядного даже 16-ричного числа хватит чтобы нивелировать шанс перезаписи с лихвой


Поссал на лицо смачно.
742 1149332
Правильно я понимаю, что в современных реалиях лучше не брать yii как то, на чем можно написать хелоу-ворд для гитхаба, что бы было проще найти работу?

https://habrahabr.ru/post/333398/
743 1149345
Сколько нормальная зп за час для джуниура, стрнонг джуна, и миддла?
744 1149352
Так как в треде почему-то много вопросов про работу и мало про программирование, то я принес вам статью про то, как работает система повышения в Гугле, как там становятся миддлами и сеньорами:

Почему я ушёл из Google и начал работать на себя
https://m.habrahabr.ru/post/350374/
745 1149355
>>49352

>https://m.


ммм, вкусно спасиб.
746 1149374
>>49355
Ведь так сложно убрать два символа, да?
747 1149375
Анончики.
Я раньше не замечал, что можно перечислять любое количество переменных для функции или что-то делаю неправильно?
Почему так, анон?

https://3v4l.org/6lVfP
748 1149378
>>49375
Можно, но ты делаешь это не правильно.

Вот ссылка на мануал: https://secure.php.net/manual/ru/functions.arguments.php#functions.variable-arg-list
749 1149380
>>49378
Я не это имел в виду. Можно ли ограничить количество переменных для функции, чтобы, если передаётся больше указанных, то выводилась ошибка?
750 1149385
1520163696320.png28 Кб, 637x212
751 1149481
Анон, что это за хуйня, и как ее пофиксить?
WAMP
752 1149483
>>49481
значит что нельзя иметь доступ к базе под этим пользователем. Там же разгараничения могут быть что под каждую базу свой юзер выделен. Что бы если спиздят пароли от одного лендоса, то другие не положили заодно например.
753 1149511
>>48023
>>48424
>>49203

> public function addNewRoom($number) {


Здесь в номерах не указываются их параметры (цена, вместимость).

> public function settleGuest($room_id, $guest_id) {


> $rooms[$room_id]->setGuest($guest);


Зачем тут id? Где их брать? У нас же есть объекты. id нужны только для баз данных, тут можно обойтись без них.

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

А так, начал в правильном направлении. Спрашивай, если что непонятно.
754 1149517
>>49211

>Оказывается array_rand возвращает ключи, а не значения.


Ну как-бы у ОПа в гайде всё написано же.
755 1149523
>>49202

>быдлоязык.


Вот это заявления. Оказывается в том что ты что-то не понимаешь язык виноват, а не ты. Ну хорошо.
756 1149525
>>48916

>почему он из массива только цифры берет, и вообще берет не 5?


А ты из массива и не берёшь ничего, только рандомируешь его ключи, а не элементы массива.

> берет не 5?


Так счёт идет от нуля. 0, 1, 2, 3, 4, 5. То-есть 6 элементов.

> isset это не совсем то, что мне нужно для обработки нажатия. Что мне нужно?


Почему нет то?
757 1149526
>>48917
Смирись, лучше Котерова никто книгу не написал. Остальные книги настолько плохи что даже для обучения не подходят. К тому-же спорить о стиле кода в 2018, когда всё форматируется под любой стандарт нажатием сочетания клавиш?
758 1149550
>>49375

Да, можно передать больше, чем надо. Проверить точное количество можно функциями func_num_args() и func_get_args().

>>49481

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

>>49380

Через if + func_num_args.

>>49332

Если ты ищешь работу, почему бы не пройти по сайтам вакансий вроде hh.ru и не посмотреть требования?

>>49230

Зайди на сайт вакансий и посмотри.

>>49168

Эти функции надо написать самому. Они добивают строку пробелами слева или справа до заданной длины. Пишутся с mb_strlen + str_repeat.

>>49345

Смотри сайты вакансий.

>>49167

Используй события вроде hover/mouseenter. На каждую ссылку ставить обработчик замучаешься, потому можно поставить один глобальный на документ с фильтром по классу/тегу ($.on). В случае наведения мыши показываем прелоадер, запускаем загрузку данных. Когда загрузятся - создаем абс. поз. относительно родителя див с нужным нам смещением и в него вставляем HTML код поста.

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

Что именно непонятно?
758 1149550
>>49375

Да, можно передать больше, чем надо. Проверить точное количество можно функциями func_num_args() и func_get_args().

>>49481

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

>>49380

Через if + func_num_args.

>>49332

Если ты ищешь работу, почему бы не пройти по сайтам вакансий вроде hh.ru и не посмотреть требования?

>>49230

Зайди на сайт вакансий и посмотри.

>>49168

Эти функции надо написать самому. Они добивают строку пробелами слева или справа до заданной длины. Пишутся с mb_strlen + str_repeat.

>>49345

Смотри сайты вакансий.

>>49167

Используй события вроде hover/mouseenter. На каждую ссылку ставить обработчик замучаешься, потому можно поставить один глобальный на документ с фильтром по классу/тегу ($.on). В случае наведения мыши показываем прелоадер, запускаем загрузку данных. Когда загрузятся - создаем абс. поз. относительно родителя див с нужным нам смещением и в него вставляем HTML код поста.

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

Что именно непонятно?
759 1149552
>>49061

> конкретного онклика нет?


onclick - это атрибут элемента DOM. На сервере никакого DOM нет, никаких нажатий нет, на сервер просто приходит HTTP-запрос и никакого "онклика" быть в принципе не может.

>>49038

Нету. Нужно это прописывать вручную в стиле "здесь может быть буква д или d, за ней у кириллицей или y латиницей".

>>48818

После успешной обработки POST запроса и создания новой ссылки надо делать редирект, чтобы страница загрузилась методом GET. Это называется POST-Redirect-GET: https://ru.wikipedia.org/wiki/Post/Redirect/Get

Работа с формами описана у меня в уроке https://github.com/codedokode/pasta/blob/master/forms.md

>>48916

Не надо создавать кучу PHP файлов. Ты скорее всего думаешь, что веб-сервер всегда ищет тот файл, который указан в URL. Но это можно настроить как угодно, например, чтобы всегда бы вызывался один и тот же скрипт index.php и уже в нем разбирался URL. Как именно это делать - зависит от используемого веб-сервера, в каждом по-разному. В апаче через htaccess и mod_rewrite, в встроенном в PHP веб-сервере через скрипт роутинга, в nginx через конфиг.

Обычно используют базу данных. Если неохота задействовать отдельную СУБД, можно использовать Sqlite, которая хранит таблицы в файлах.

При вставке в БД можно проверить, не занят ли нужный идентификатор, а также можно автоматически генерировать порядковые номера.

Если ты хочешь лучше научиться делать такие вещи, я советую посмотреть первый пост треда и задачу про студентов - в ней много комментариев и она учит как раз, как писать приложения с формами и таблицами.
760 1149553
>>49017

В JSON не лучше. Не стоит изобретать велосипед, когда есть:

- примитивные файловые key-value БД вроде BerkeleyDB и ее наледников
- файловая SQL БД Sqlite
- отдельные SQL СУБД вроде Postgres и MySQL

>>47404

А что значит "выбирался"? Просто select со списком документов не подойдет? Или тебе надо поле для загрузки файла? Изучи, какие поля есть в HTML формах.

>>48575

Может официальный мануал? http://php.net/manual/ru/index.php

>>48490

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

>>48841

Просто так куки угнать нельзя. Куки отдаются только тому сайту (домену), который их выставил. Но дальше начинаются интересные варианты.

Ну например, атака на DNS: злодей взламывает твой роутер (а китайские роутеры очень дырявы) и перехватывает DNS запросы, чтобы сайту example.com соответствовал бы их сервер и твой браузер бы отправлял куки туда. Защита: использование HTTPS, установка флага secure у кук, чтобы их не отдавало по HTTP.

Или социнженерия: отправляем письмо с просьбой посмотреть документ info.doc.____________.exe.

> Так же, хотелось бы узнать, есть ли такой способ кражи, при переходе на посторонний сайт.


Нет при условии отсутствия уязвимостей в браузере и ОС.

> переход по незнакомым ссылкам чревато?


Потому, что браузеры и ОС не идеальные и в них могут быть уязвимости, которые позволяют запустить вредоносный код на машине или обойти ограничения. Но если ты обновляешь браузер и ОС, не используешь флеш, Adobe Reader и ява-плагин и используешь браузер с печочницой (вроде Chrome), то вероятность этого не велика. Так как уязвимости такого уровня стоят десятки тыс. долл. и вряд ли кто-то ради протроянивания твоего пк будет столько тратить. Если ты конечно не связан с военными тайнами какими-нибудь.

Регулярно проводится конкурс pwn2own на взлом браузеров (запуск вредоносного кода при посещении сайта). Ты можешь по призовым выплатам оценить, насколько сложен взлом: https://habrahabr.ru/company/kingservers/blog/324480/

Часто ломают не сами браузеры, а плагины, в которых защита слабее: флеш много раз ломали, adobe reader, ява-плагин. Потому Гугл пытается поскорее вытеснить флеш и использует свой просмотрщик для PDF. Ломают через офисные приложения (Word, Excel). Так как их разработчики не выстраивают такую надежную защиту, как Гугл, а иногда делают откровенное решето (макросы в офисных приложениях). Также, были случаи, когда ломали браузер за счет уязвимости в виндовой библиотеке, отвечающей за вывод шрифтов - Хром по моему позже от нее отказался.

> Браузер Safari поддался участникам соревнования четыре раза, Firefox — один раз, Google Chrome взломать пытались, но не хватило времени.


А раньше по моему взламывали.

> а так же рамещением фейковой формы, для залогинивания, что, на мой взгляд, совершенно бесполезно.



Вообще-то через фейковые формы входа в Гугл-аккаунт была взломана какая-то американская партия и они очень обиделись. Фишинг работает, и еще как. Потому что пароли довольно неудобная и ненадежная система, в адресную строку никто не смотрит, плюс браузеры пишут там "Надежный" при наличии HTTPS, вводя пользователя в заблуждение. Я сторонник аппаратных ключей, которые можно носить с собой. Хотя, конечно, их можно отобрать силой.
760 1149553
>>49017

В JSON не лучше. Не стоит изобретать велосипед, когда есть:

- примитивные файловые key-value БД вроде BerkeleyDB и ее наледников
- файловая SQL БД Sqlite
- отдельные SQL СУБД вроде Postgres и MySQL

>>47404

А что значит "выбирался"? Просто select со списком документов не подойдет? Или тебе надо поле для загрузки файла? Изучи, какие поля есть в HTML формах.

>>48575

Может официальный мануал? http://php.net/manual/ru/index.php

>>48490

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

>>48841

Просто так куки угнать нельзя. Куки отдаются только тому сайту (домену), который их выставил. Но дальше начинаются интересные варианты.

Ну например, атака на DNS: злодей взламывает твой роутер (а китайские роутеры очень дырявы) и перехватывает DNS запросы, чтобы сайту example.com соответствовал бы их сервер и твой браузер бы отправлял куки туда. Защита: использование HTTPS, установка флага secure у кук, чтобы их не отдавало по HTTP.

Или социнженерия: отправляем письмо с просьбой посмотреть документ info.doc.____________.exe.

> Так же, хотелось бы узнать, есть ли такой способ кражи, при переходе на посторонний сайт.


Нет при условии отсутствия уязвимостей в браузере и ОС.

> переход по незнакомым ссылкам чревато?


Потому, что браузеры и ОС не идеальные и в них могут быть уязвимости, которые позволяют запустить вредоносный код на машине или обойти ограничения. Но если ты обновляешь браузер и ОС, не используешь флеш, Adobe Reader и ява-плагин и используешь браузер с печочницой (вроде Chrome), то вероятность этого не велика. Так как уязвимости такого уровня стоят десятки тыс. долл. и вряд ли кто-то ради протроянивания твоего пк будет столько тратить. Если ты конечно не связан с военными тайнами какими-нибудь.

Регулярно проводится конкурс pwn2own на взлом браузеров (запуск вредоносного кода при посещении сайта). Ты можешь по призовым выплатам оценить, насколько сложен взлом: https://habrahabr.ru/company/kingservers/blog/324480/

Часто ломают не сами браузеры, а плагины, в которых защита слабее: флеш много раз ломали, adobe reader, ява-плагин. Потому Гугл пытается поскорее вытеснить флеш и использует свой просмотрщик для PDF. Ломают через офисные приложения (Word, Excel). Так как их разработчики не выстраивают такую надежную защиту, как Гугл, а иногда делают откровенное решето (макросы в офисных приложениях). Также, были случаи, когда ломали браузер за счет уязвимости в виндовой библиотеке, отвечающей за вывод шрифтов - Хром по моему позже от нее отказался.

> Браузер Safari поддался участникам соревнования четыре раза, Firefox — один раз, Google Chrome взломать пытались, но не хватило времени.


А раньше по моему взламывали.

> а так же рамещением фейковой формы, для залогинивания, что, на мой взгляд, совершенно бесполезно.



Вообще-то через фейковые формы входа в Гугл-аккаунт была взломана какая-то американская партия и они очень обиделись. Фишинг работает, и еще как. Потому что пароли довольно неудобная и ненадежная система, в адресную строку никто не смотрит, плюс браузеры пишут там "Надежный" при наличии HTTPS, вводя пользователя в заблуждение. Я сторонник аппаратных ключей, которые можно носить с собой. Хотя, конечно, их можно отобрать силой.
761 1149554
>>48812

Безопасна. Куки угнать можно только при наличии уязвимостей.

>>48069

Потому что видимо сначала PHP парсит файл, создает функции, а потом только выполняет код. В JS по моему так же.

http://php.net/manual/ru/functions.user-defined.php

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



>>48151

Тут есть паста, но не уверен, что она хорошо объяснит: https://gist.github.com/codedokode/ffd520440a970c07c1c6 - про асинхронность в конце.

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

Желательно понимать что такое процессы, ядро ОС и тд. То есть изучить основы линукса и может быть сетевого программирования (Сокеты Беркли, TCP, UDP) не помешало бы, иначе можно так и не понять многое.
762 1149556
>>47348
>>43562

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

>https://ideone.com/Ex02H6


Верно

> https://ideone.com/SkhAgb


Правильно

> https://ideone.com/hyhfDi


На кубике не может выпасть 0, нижний предел должен быть 1

> https://ideone.com/MTPdrc


exit не требуется. В последнем условии можно вместо elseif(...) писать просто else без условий. А так, верно.

> https://ideone.com/g5S7HB


Ну ок, верно.

> https://ideone.com/GA0QeW


bankPercent никак не используется, но ответ получается верный.

> https://ideone.com/sgoWlo


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

Ну например, так:

- вычисляем баланс с добавлением процентов и коммиссии
- определяем, сколько мы платим в этом месяце (используя min()/max()) и кладем в переменную
- платим
- если дошли до нуля - кредит выплачен

> https://ideone.com/DjYdhn


Верно

> https://ideone.com/a81rh0


Верно

> https://ideone.com/NCaes9


Ок, верно

> https://ideone.com/W7k6HB


Правильно

> https://ideone.com/c6Lwqo


Вроде как работает, но есть одна проблема. Символы, которые ты используешь, я не очень хорошо знаю (да и ты наверно тоже) и есть вероятность, что где-то там ты мог использовать один и тот же символ для нескольких букв. Легко ведь не заметить. Можешь ли ты программно проверить - все ли символы уникальные или среди них есть 2 одинаковых?
762 1149556
>>47348
>>43562

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

>https://ideone.com/Ex02H6


Верно

> https://ideone.com/SkhAgb


Правильно

> https://ideone.com/hyhfDi


На кубике не может выпасть 0, нижний предел должен быть 1

> https://ideone.com/MTPdrc


exit не требуется. В последнем условии можно вместо elseif(...) писать просто else без условий. А так, верно.

> https://ideone.com/g5S7HB


Ну ок, верно.

> https://ideone.com/GA0QeW


bankPercent никак не используется, но ответ получается верный.

> https://ideone.com/sgoWlo


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

Ну например, так:

- вычисляем баланс с добавлением процентов и коммиссии
- определяем, сколько мы платим в этом месяце (используя min()/max()) и кладем в переменную
- платим
- если дошли до нуля - кредит выплачен

> https://ideone.com/DjYdhn


Верно

> https://ideone.com/a81rh0


Верно

> https://ideone.com/NCaes9


Ок, верно

> https://ideone.com/W7k6HB


Правильно

> https://ideone.com/c6Lwqo


Вроде как работает, но есть одна проблема. Символы, которые ты используешь, я не очень хорошо знаю (да и ты наверно тоже) и есть вероятность, что где-то там ты мог использовать один и тот же символ для нескольких букв. Легко ведь не заметить. Можешь ли ты программно проверить - все ли символы уникальные или среди них есть 2 одинаковых?
763 1149557
>>47307

Оба верные.

Вообще, во втором решении можно было сделать цикл из 2 шагов, а после него - отдельно сделать вывод третьей строки. В цикл надо помещать только действия, которые повторяются, а последняя строка не повторяется.

Сложно выглядит код наверно из-за длинных выражений вроде $line[$i] = $word1[array_rand($word1) ]....

Лучше это выражение разбить на части покороче:

$part1 = $word1[array_rand($word1)];
$part2 = ...
...
echo $part1 . ' ' . $part2....;

И вместо массива $line сразу использовать echo.

> for ($i = 1; ; $i++) {


Цикл с явным указанием числа повторений гораздо понятнее.

Но это хорошо, что ты замечаешь, что код плохо выглядит.

>>46883

> Почитал про джойны, примеры работают, а как их к этой базе применить не доходит.


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

Почти все задачи на SQL решаются именно через джойн + иногда группировка.

> Еще внешние ключи ну никак не могу понять,


Если в таблице стоит ссылка на ячейку другой таблицы, то это внешний ключ. Вот и все. Где и как ставится внешний ключ, зависит от типа связи. Их там всего несколько - 1:1, 1:M и M:N. И еще вариации, например, бывает связь 1:M, а бывает [0, 1]:M. То есть левая сущность может быть обязательной, а может и нет.

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

Вот тут неплохо объясняются типы связей, джойны и внешние ключи: http://jtest.ru/bazyi-dannyix/sql-dlya-nachinayushhix-chast-3.html

По схеме БД: процедуры (в receptions) придется в будущем всего выносить в отдельную таблицу. У них могут быть свои какие-то атрибуты, цены и тд.

Также, у тебя есть избыточные связи. Например, в receptions приписан owner. Если pay_ticket привязан к reception, то owner в нем не лишний ли? Да и если еще подумать, может быть счет логично выписывать на животное, а не на конкретного владельца? Их ведь там несколько.

То же самое касается поля employee. Хотя конечно бухгалтерия дело сложное, и может там счет выписывает другой сотрудник?

Также, насчет именования таблиц/полей, советовал бы гайд http://www.sqlstyle.guide/ru/

Насчет связи между receptions и pets - а не может хозяин придти без животного? На консультацию например? Это учтено?

Насчет связи между receptions и pay_tickets - мне кажется, должно быть связь 1 receptions - (0..N) pay_tickets. То есть по итогам приема может быть выписано сколько угодно счетов (инвойсов?).

Связь между prescriptions и pay_tickets - я не уверен, что она нужна. Разве выдача рецепта как-то связана с оплатой? Вполне возможно, что врач решил выписать рецепт бесплатно.

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

> Еще внешние ключи ну никак не могу понять, я вот их наставил тут, но походу немного далеко уехал с ними.


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

> Почитал про джойны, примеры работают, а как их к этой базе применить не доходит.


Ну простой пример: вывести дату приема и имя животного на приеме:

SELECT r.date, p.name FROM receptions r JOIN pets p ON p.id = r.pet;

Почитай статью выше.
763 1149557
>>47307

Оба верные.

Вообще, во втором решении можно было сделать цикл из 2 шагов, а после него - отдельно сделать вывод третьей строки. В цикл надо помещать только действия, которые повторяются, а последняя строка не повторяется.

Сложно выглядит код наверно из-за длинных выражений вроде $line[$i] = $word1[array_rand($word1) ]....

Лучше это выражение разбить на части покороче:

$part1 = $word1[array_rand($word1)];
$part2 = ...
...
echo $part1 . ' ' . $part2....;

И вместо массива $line сразу использовать echo.

> for ($i = 1; ; $i++) {


Цикл с явным указанием числа повторений гораздо понятнее.

Но это хорошо, что ты замечаешь, что код плохо выглядит.

>>46883

> Почитал про джойны, примеры работают, а как их к этой базе применить не доходит.


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

Почти все задачи на SQL решаются именно через джойн + иногда группировка.

> Еще внешние ключи ну никак не могу понять,


Если в таблице стоит ссылка на ячейку другой таблицы, то это внешний ключ. Вот и все. Где и как ставится внешний ключ, зависит от типа связи. Их там всего несколько - 1:1, 1:M и M:N. И еще вариации, например, бывает связь 1:M, а бывает [0, 1]:M. То есть левая сущность может быть обязательной, а может и нет.

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

Вот тут неплохо объясняются типы связей, джойны и внешние ключи: http://jtest.ru/bazyi-dannyix/sql-dlya-nachinayushhix-chast-3.html

По схеме БД: процедуры (в receptions) придется в будущем всего выносить в отдельную таблицу. У них могут быть свои какие-то атрибуты, цены и тд.

Также, у тебя есть избыточные связи. Например, в receptions приписан owner. Если pay_ticket привязан к reception, то owner в нем не лишний ли? Да и если еще подумать, может быть счет логично выписывать на животное, а не на конкретного владельца? Их ведь там несколько.

То же самое касается поля employee. Хотя конечно бухгалтерия дело сложное, и может там счет выписывает другой сотрудник?

Также, насчет именования таблиц/полей, советовал бы гайд http://www.sqlstyle.guide/ru/

Насчет связи между receptions и pets - а не может хозяин придти без животного? На консультацию например? Это учтено?

Насчет связи между receptions и pay_tickets - мне кажется, должно быть связь 1 receptions - (0..N) pay_tickets. То есть по итогам приема может быть выписано сколько угодно счетов (инвойсов?).

Связь между prescriptions и pay_tickets - я не уверен, что она нужна. Разве выдача рецепта как-то связана с оплатой? Вполне возможно, что врач решил выписать рецепт бесплатно.

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

> Еще внешние ключи ну никак не могу понять, я вот их наставил тут, но походу немного далеко уехал с ними.


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

> Почитал про джойны, примеры работают, а как их к этой базе применить не доходит.


Ну простой пример: вывести дату приема и имя животного на приеме:

SELECT r.date, p.name FROM receptions r JOIN pets p ON p.id = r.pet;

Почитай статью выше.
764 1149558
>>46732

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

У той же mega.nz "толстый" фронтенд и она субъективно очень тормозная и сильно грузит процессор.
765 1149563
>>46883

Еще при проектировании БД стоит следовать принципам нормализации. Если ты с ними не знаком, то у меня тут относительно несложно идет объяснение: https://github.com/codedokode/pasta/blob/master/db/normalization.md
766 1149569
>>49557
>>49563
Спасибо, почитаю, постараюсь применить.
767 1149588
>>49526
это может и так, но ты ответь на вопрос, ты в конторе работаешь? пишешь поддерживаемый код? есть код-ревью? у вас такой код, который пишет котеров, пропустили бы?

речь не про psr. просто в любой нормальной фирме за такой код тебя сразу отправят в бухгалтерию забирать документы.
768 1149589
>>49588

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


За какой такой то? Почему Котерова не попросили забрать документы тогда? Он книги пишет, но видимо анону с двачей виднее каким должен быть код конечно же.
К тому-же он обьясняет и учит как применять то или иное, а не говорит мол пиши как я и только как я. У меня например не возникло сложностей интерпретировать его код. Почему у тебя такие сложности должны возникнуть?
769 1149596
>>49511

>Зачем тут id?


Я вот тут запнулся, мне надо придумать какой нибудь хэш для комнаты(он же идентификатор), но по идее идентификатор комнаты ее номер.
А вот по поводу гостя, какой идентификатор добавить?
Если сделать идентификатором пользователя имя и фамилию и использовать как ключ для доступа поля в массиве?

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

Еще мне очень интересно как на это все добавить тестов или вообще в идеале делать по тдд, если это конечно возможно?
770 1149599
>>49596
Имя + Фамилия могут повторяться. Например в соседние комнаты заселятся отец и сын Петровы, оба Иваны.

Вопрос ОП-у: что нужно делать первее — придумать сущности в PHP или структуру базы данных продумать?
771 1149602
>>49588

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


Брр, от тебя повеяло совком каким то, ты на заводе каком то работаешь наверно или тебе лет 50, угадал?
772 1149611
>>49589

>но видимо анону с двачей виднее каким должен быть код конечно же


видимо да, лол. любой анон, имеющий опыт написания промышленного поддерживаемого кода, будет более компетентным, чем котеров с его миллионом книг по пхп4.

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

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

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

мне 30, если тебе так важно.
773 1149616
>>49611
Короче ответов от тебя нет вообще никаких. Конкретики нет, одна обобщённая критика, причём ещё и PHP4, хотя у Котерова по 7 версии книга есть таки.

>любой анон, имеющий опыт написания промышленного поддерживаемого кода, будет более компетентным, чем котеров с его миллионом книг по пхп4.


Окей спорить не буду. Назови Другую книгу по PHP7?
774 1149621
>>49616

>Конкретики нет


я в прошлых тредах (98 или 97) подробно разбирал какой-то кусок его кода примеров к какой-то книге как раз по пхп7. немного лень искать, можешь это сделать сам по слову "котеров" в архиваче

>причём ещё и PHP4, хотя у Котерова по 7 версии книга есть таки


это ирония была. у него книги по пхп7, а код как на пхп4 (опять же, я приводил примеры с каким-то минимальным разбором почему так неправильно и как надо)

>Назови Другую книгу по PHP7


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

если тебе нужны именно книги, то есть очень урезанная адаптация книги clean code роберта мартина https://github.com/jupeter/clean-code-php хотя я рекомендую читать ее оригинал на джаве. еще есть http://www.phptherightway.com/ ну и мануал.
775 1149622
>>49616

>Конкретики нет, одна обобщённая критика


вот, не поленился и нашел:
https://phpclub.tech/pr/res/1109863.html#1114606
https://phpclub.tech/pr/res/1109863.html#1114646
776 1149623
>>49622
Спасибо анон
777 1149624
>>49616
https://phpclub.tech/pr/res/1109863.html#1116337 вот еще ОП комментировал его код
778 1149647
>>49552

> post-redirect-get


Спасибо, но я уже пофиксил это с помощью ajax'a. Теперь-то и выглядит это все не так костыльно, ты лично посылаешь запрос скрипту на серв, и лично получаешь и обрабатываешь от него ответ.

>>49525
Счет идет от нуля, а параметр отвечает за количество. Впрочем, неважно, когда я переделал код под возвращаемый массив с индексами, все заработало как надо.

> почему нет


В гугле написано, насколько я помню, что это проверяет, объявлена ли переменная. Не, ну оно и подходит, в принципе.

>>49523
Быдлоязык - потому что в него вкатывается всякое быдло ради 300кк/нсек(особенно в треде на мейлаче), а еще потому, что у меня бомбануло, он слишком не похож на другие нормальные языки, где берешь, и без задней мысли делаешь, а здесь какой-то пердолинг. И еще все эти долларчики, блядь, аж трясет от них.
Были бы халявные хосты с питоном или нодой, я бы туда убежал за милую душу.
779 1149649
>>49647

>потому что в него вкатывается всякое быдло ради 300кк/нсек


исторически так сложилось, что да. например, ты

>он слишком не похож на другие нормальные языки


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

>Были бы халявные хосты с питоном или нодой


шта? 5 долларов в месяц за свой впс с нужным окружением для программиста на нормальных языках слишком серьезная сумма?
780 1149685
>>49647
Похоже, что это почётное звание перешло к js. В моём окружении таким языком вообще Java является. Но стартанул я не очень, потом перескочил на что было.
К языку нет претензий - седьмой пых очень приятный.
белорус-на-распреде
781 1149718
Посмотрите пожалуйста код классов задачи про департаменты и выскажите критику.
https://ideone.com/PwMKoy
782 1149725
>>46704
Я отредактировал, php formater не работает.
https://ideone.com/4TsHlt
783 1149771
>>49647

Если ты используешь аякс - проверь, выполнены ли рекомендации по правильной работе с аяксом: https://github.com/codedokode/pasta/blob/master/js/ajax.md
784 1149773
Прочитал про новый тренд у "фронтенд специалистов" - блокировать показ сайта в ландшафтной ориентации: https://m.habrahabr.ru/post/350410/

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

Критикуя - предлагай, скажет читатель. Предлагаю: не можете сделать хорошо, делайте просто черный текст на белом фоне. Вы удивитесь, насколько это прекрасный дизайн.
785 1149825
>>35053 (OP)
Что думаете по этой пасте про пхп http://telegra.ph/PHP-03-05
786 1149839
>>49825
прочитал, перекатился в ruby тред
14543213087453.jpg78 Кб, 700x525
787 1149865
>>49825
Очень важное мнение.
788 1149880
>>49825

>error_reporting


Вот эта претензия меня всегда смущала, потому-что в других языках если я получаю ошибку, - по факту я либо кладу весь сайт! Либо весь сервис! ДЛЯ ВСЕХ ЮЗЕРОВ! (Привет ASP). Для тех кто в танке. Представьте что у одного юзера вкмылору произошла ошибка получения доступа к бд например. И из-за этого ВК лёг у всех. Удобно да? Поэтому говорить о том что это минус ну ооооочень странно. Да и настраивать error_reporting учат раньше чем Hello world писать.
789 1149881
>>49865

>Сам он настолько экзотичный, что я скорее отнес бы php к эзотерическим языкам программирования и поставил где-нибудь рядом с HOtMEfSPRIbNG.


Дальше можно не читать. Как вообще можно воспринимать человека всерьёз, если он по факту не знаком с целым семейством языков? Я вообще в шоке. Синтаксис похож вообще на всё что я знаю, разьве что кроме JS. И говорить что PHP экзотический? Либо толстота, либо крайне скудный опыт в ЯП.
790 1149885
>>49839
Руби помер 10 месяцев как. Да и вообще язык одного фрэймворка (Rails). Который за всю историю своего развития получил тонны похвал, тонны хвалебных статей, тонны упоминаний в IT сообществе и вообще язык хайп и чуть ли не идеальный язык программирования, но при этом худо бедно можно наскрести 2-3 приложения которые на нём действительно написаны.
Сорян за оффтоп. ПРосто я реально не понимаю зачем нужен руби.
Slowpoke.png23 Кб, 298x291
791 1149905
>>49885

>Руби помер 10 месяцев как.


А почему именно 10? Что за событие произошло 10 месяцев назад?
792 1149915
>>49905
Летом проходили сборы всяких хакатонов, и прочих набегов где обсуждаются языки программирования и прочее. Выяснилось что на мероприятия с руби в залах собирается по 5-10 человек, редко 40. Когда на аналогичные мероприятия собираются 1000-1200. Ну как-бы "At this moment Jonny knew - he fucked up."
793 1149920
>>49881
Ну эзотерика здесь скорее понимается не в плане синтаксиса, а в кучу мелочей в семантике, которые потом описаны.
794 1149921
>>49880

error_reporting это вредная и плохая идея. Если произошла ошибка - надо прекращать обработку запроса и отдавать 5xx.

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

Скрытие ошибок ни к чему хорошему не приведет, их просто будет труднее заметить.
795 1149925
>>49825

В PHP много плохого, это да. Синтаксис страшный, да. Работа с ошибками сломана безнадежно. Но есть и хорошее: тайп-хинты (ну-ка, покажите мне тайп-хинты в Руби, Питоне или JS), классы как в Яве (покажите мне классы в JS). Есть HHVM. В отличие от JS есть поддержка тредов.

Вообще, у разных языков свои сильные и слабые стороны. Мне нравится в плане возможностей Java и C#, они с типизацией, с классами и компилируются (хорошая производительность). Но в плане установки и использования они не такие простые как PHP, и Симфони там нету.

Плюсами PHP считается наличие большого числа разных CMS например. Тот же Вордпресс. Покажите мне вордпресс на JS.

Также, PHP очень просто в использовании. Пишешь файл 1.php, запускаешь встроенный веб-сервер - страница готова. Попробуйте сделать то же в Руби, Питоне, JS без поиска нужных библиотек.

> 1. Настройка и установка php - это весьма своеобразная история.



Набрать команду apt-get install php - это своеобразная история? Давайте посмотрим на Питон, где инструкция по установке почти любого приложения начинается с установки одного пакетного менеджера через другой. И с освоения virtualenv.

> То, где может искаться php.ini - это целый здоровый список в документации с целой кучей вариантов в зависимости от ОС и сервера.



Можно набрать php -i и посмотреть.

> Сюда же идёт тот факт, что php всегда намертво связано с веб-сервером и не может толком использоваться вне его



Может, хотя не очень понятно, зачем.

> что интерпретатор в общем случае живет в рамках одного http запроса.



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

> Зачем-то в динамический язык скопировали ООП из джавы.


> Зачем, почему, непонятно



Потому, что в Яве прекрасный ООП, в отличие от других языков.

> Долгое время, конечно же, не было пакетного менеджера


PEAR был.

> Безопасность среднего поделия на php ниже плинтуса,


Виноват ли в этом язык?

Ну и автор не назвал, какой язык он считает хорошим. Не беда; какой бы он не назвал, у меня есть, что ответить: https://habrahabr.ru/post/315152/
795 1149925
>>49825

В PHP много плохого, это да. Синтаксис страшный, да. Работа с ошибками сломана безнадежно. Но есть и хорошее: тайп-хинты (ну-ка, покажите мне тайп-хинты в Руби, Питоне или JS), классы как в Яве (покажите мне классы в JS). Есть HHVM. В отличие от JS есть поддержка тредов.

Вообще, у разных языков свои сильные и слабые стороны. Мне нравится в плане возможностей Java и C#, они с типизацией, с классами и компилируются (хорошая производительность). Но в плане установки и использования они не такие простые как PHP, и Симфони там нету.

Плюсами PHP считается наличие большого числа разных CMS например. Тот же Вордпресс. Покажите мне вордпресс на JS.

Также, PHP очень просто в использовании. Пишешь файл 1.php, запускаешь встроенный веб-сервер - страница готова. Попробуйте сделать то же в Руби, Питоне, JS без поиска нужных библиотек.

> 1. Настройка и установка php - это весьма своеобразная история.



Набрать команду apt-get install php - это своеобразная история? Давайте посмотрим на Питон, где инструкция по установке почти любого приложения начинается с установки одного пакетного менеджера через другой. И с освоения virtualenv.

> То, где может искаться php.ini - это целый здоровый список в документации с целой кучей вариантов в зависимости от ОС и сервера.



Можно набрать php -i и посмотреть.

> Сюда же идёт тот факт, что php всегда намертво связано с веб-сервером и не может толком использоваться вне его



Может, хотя не очень понятно, зачем.

> что интерпретатор в общем случае живет в рамках одного http запроса.



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

> Зачем-то в динамический язык скопировали ООП из джавы.


> Зачем, почему, непонятно



Потому, что в Яве прекрасный ООП, в отличие от других языков.

> Долгое время, конечно же, не было пакетного менеджера


PEAR был.

> Безопасность среднего поделия на php ниже плинтуса,


Виноват ли в этом язык?

Ну и автор не назвал, какой язык он считает хорошим. Не беда; какой бы он не назвал, у меня есть, что ответить: https://habrahabr.ru/post/315152/
796 1149926
>>49921

> Если произошла ошибка - надо прекращать обработку запроса и отдавать 5xx.


В том то и дело что ту не можешь узнать произошла ошибка или нет. Даже блоки try catch иногда не отрабатывают ошибку.

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


У тебя явно мало опыта в таких проектах на других языках. Пример ASP показывает что падает у всех, хотя ASP и старенький по современным меркам, но тем не мение он как раз из вот этой концепции.

>Скрытие ошибок ни к чему хорошему не приведет, их просто будет труднее заметить.


Что значит труднее заметить? На продакшне ты вообще не должен их замечать. И вообще вываливать тонны ошибок на юзера - как по мне КРАЙНЕ странная практика. На тестовом сервере ты можешь выставить ошибки и отловить всё что тебе угодно.
Опять же на ASP выводятся тонны ошибок если где-то в SQL запросе что-то пошло не так или вообще по любой другой причине, в результате я как програмист разработчик который может это исправить может и радубсь, но 5000 юзеров сайта недоумевают зачем им вообще знать что там какой-то SQL запрос неправильный? Сделать то они ничего с этим не могут.
797 1149929
>>49925

>они не нашли ничего лучше как по крону прибивать и перезапускать приложение.


Забавно что у Node.js точно также обстоят дела. Хотя это было в прошлом году, может сейчас есть что-то новое.
798 1149932
>>49925

>И это очень полезная фича.


Языки с корректно сделанной сборкой мусора и рантаймом (JVM и CLR) умеют жить очень в рамках одного процесса. Возможно, автор, как раз на них и ориентировался.

>Яве прекрасный ООП,


Но только он завязан на статическую типизацию, которой в ПХП толком не было.

>>49926
Опять-таки у приложений на той же JVM или CLR с обработкой ошибок всё хорошо и там как раз в веб приложениях обычно падает только обработчик конкретного запроса.
799 1149935
>>49929

Вообще, по идее утечки памяти можно находить. Для языка Си, например, есть Valgrind, думаю, что и для JS мог бы быть инструмент, но его никто не написал. Для PHP, кстати, тоже.

Вот кстати, отладка - отдельная вещь. Насколько я знаю, для PHP есть отладчики, увы, только в виде тяжелых IDE вроде PHPStorm или Netbeans, а для Node.JS или Go - вообще нету. То же касается профайлинга, у нас хотя бы xdebug есть.
800 1149939
>>49932

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

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

> Но только он завязан на статическую типизацию, которой в ПХП толком не было.



Это лучше чем вообще ничего.
801 1149941
>>49926

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

> В том то и дело что ту не можешь узнать произошла ошибка или нет. Даже блоки try catch иногда не отрабатывают ошибку.



Я как раз могу. Все фиксируется и логгируется. Даже падения процесса PHP можно фиксировать и логгировать, если запускать под супервизором например (ну и php-fpm их тоже по моему отслеживает).

> Пример ASP показывает что падает у всех, хотя ASP и старенький по современным меркам, но тем не мение он как раз из вот этой концепции.



Может быть у вас что-то было неправильно настроено.

> но 5000 юзеров сайта недоумевают зачем им вообще знать что там какой-то SQL запрос неправильный? Сделать то они ничего с этим не могут.


Именно потому им надо показывать не текст ошибки, а страницу 503. "тонны ошибок" там быть не может, так как обработка запроса прекращается на первой же ошибке и следовательно больше одной ошибки за раз быть вообще не может.

Почитай про ошибки и принцип fail fast: https://habrahabr.ru/post/218325/
802 1149951
>>49941

>Я как раз могу. Все фиксируется и логгируется. Даже падения процесса PHP можно фиксировать и логгировать, если запускать под супервизором например (ну и php-fpm их тоже по моему отслеживает).


Ну так-то да, вот только error_reporting довольно далеко от этого. То-есть претензия была к нему, и к тому что отслеживать ошибки трудно. А в итоге то всё-равно лезь в логи и смотри. Тогда причём тут error_reporting? Непонятно.

>Может быть у вас что-то было неправильно настроено.


Это весьма спорно. Поскольку настраивали всё аж спецы из Американского офиса Майкрософта. Ну и я сам имел около 5 проектов на ASP. И был весьма удивлён таким вот поведением.
Fail Fast! принцип Отлаживайте меньше и создавайте более на[...].png19 Кб, 781x229
803 1149965
>>49941
Я обычно на шрифты внимания не обращаю. но после первого параграфа глаза реально стали слезиться.
804 1149969
>>49951

Логи это лишь первичные данные. Ты с ними можешь потом делать что угодно, в том числе например пересылать данные из них в какую-то систему мониторинга.

> Тогда причём тут error_reporting?


При том, что это опция, позволяющая игнорировать отдельные виды ошибок и она вредная.

Что же тут может быть непонятного? Если у тебя произошла любая ошибка или предупреждение, ты останавливаешь скрипт, выдаешь пишешь ошибку в лог и выдаешь пользователю страницу 503.

И очень плохо, что в PHP так не сделано по умолчанию.

>>49965

Это вопрос к хабру. я когда-то читал эту статью в нормальном виде.

> Даже блоки try catch иногда не отрабатывают ошибку.


Потому что они ловят исключения, а не ошибки.
805 1150032
Помогите разобрать код, у автора есть статья и репозиторий на гитхабе, но не могу понять пару моментов:
что значит this.request в данном контексте? создается переменная request в которую записывается что?
https://github.com/dorsha/login-modal-react-redux/blob/master/src/util/api.js#L21

что тут происходит?
https://github.com/dorsha/login-modal-react-redux/blob/master/src/util/api.js#L23

Статья с частичным объяснением https://medium.com/@dorsha/implement-login-modal-with-redux-reselect-and-reactjs-668c468bcbe3
806 1150169
Не знаю где написать, напишу здесь.
Скиньте пожалуйста пример готового сайта, с фронт-эндом, бэк-эндом и всем вот этим. Интересует конкретно структура файлов и папок в нем.
807 1150203
>>50169
Эм... как бы тебе сказать. Я не понимаю зачем тебе структура файлов и папок на сайте, потому-что банально она может быть любой. Ну тоесть вообще любой. От банального все файлы в одной папке в корне, до каждый файл в своей подпапке. А некоторые JS вообще умудряются разнести функционал по 3-50 доменам! Так что структура папок и файлов тебе вообще не скажут ничего.
808 1150217
>>50203

> Так что структура папок и файлов тебе вообще не скажут ничего


Так мне и не нужно, чтобы они мне что-то говорили. Просто я поехавший перфекционист, и все должно быть максимально упорядочено. Сейчас вот пилю некое подобие сайта, накатал 1 индекс страницу, другие уже так как обмазался пыхой планирую загружать в нее из БД, так вот есть этот индекс, рядом с ним лежит папка res, и в ней все сразу: и жс, и сасс/сиэсэс, шрифты, картинки, либы, теперь там еще и пыха, которая вообще не из этой тарелки. Типа, я бы мог конечно навасянить себе свою личную структуру, но зачем придумывать велосипед.
code.png27 Кб, 593x93
809 1150342
>>49550
В мануале нашел вот такой способ, в чём подвох?
810 1150430
Подскажите немного с теорией. Повторяющийся парсинг популярного ресурса, с мультикурлом, группиповкой данных и извлечением контента проблем нет, интересуют именно способы обхода блокировок. Насколько я понимаю спуфать IP на уровне языка я не могу, максимум только поменять прокси/юзерагента на лету с помощью angry/rolling curl. Я вот думал может написать сервис-парсер, может даже на nodejs, который будет заниматься непосредственно пирсингом и наполнением промежуточной бд и отправкой данных в главное хранилище получая обратно следующий список страниц. Можно будет поднять любое количество нод, так как главный сервер будет решать какая нода что будет парсить. Интересно следующее, представляют ли облачные сервисы апи для поднятия/отключения ноды или каким образом это можно авторизировать? Буду благодарен за любую идею или информацию
811 1150434
ОП, посмотри задачу про Гостиницу, пожалуйста.

https://3v4l.org/ULIPK
812 1150518
>>50032
Сам разобрался, сам отвечу

>что значит this.request в данном контексте? создается переменная request в которую записывается что?


>https://github.com/dorsha/login-modal-react-redux/blob/master/src/util/api.js#L21


Функция checkStatus вызывается с привязанным контекстом с помощью checkStatus.bind(...), новой созданной переменной request устанавливается значение одноименной переменной из контекста.

>что тут происходит?


>https://github.com/dorsha/login-modal-react-redux/blob/master/src/util/api.js#L23


Очередь с рекурсивными промисами с кэррингом и привязкой контекста. Что может быть проще?
Новый request получает ссылку на вызов функций resolve и reject в созданном Promise, чтобы в дальнейшем можно было их вызвать в другом месте (в очереди будет запущен request, который является ф-ей postPut/get с привязаным контекстом). Сам промис возвращается как результат выполнения checkStatus, в то место где был вызван, и после запуска resolve или reject (в очереди) промис получит соответствующий статус и результат запроса (postPut/get) отправится в обработчик.
2018-03-06-112948586x443scrot.png273 Кб, 586x443
813 1150563
>>50518

> модалка для логина на реакте


> Очередь с рекурсивными промисами с кэррингом и привязкой контекста.


Вспомнился пик. Мне кажется, что раз задача такая простая, а код настолько сложный, то ему не место в продакшене. В проект будут приходить новые люди, им тоже нужно будет ломать голову над таким кодом?
814 1150579
>>35053 (OP)
Опушка, а не мог бы ты расставить якоря на каждой задаче? Что бы можно было бы пользоваться ссылками вида
http://archive-ipq-co.narod.ru/l1/pasta.html#vector

http://archive-ipq-co.narod.ru/l1/pasta.html#catsmice

например.
815 1150614
>>50563
Для меня весь js такой, слишком запутанный.
В защиту конкретно этого примера скажу, что модалка появляется автоматически, как только сервер ответил кодом 401 на любой запрос, и этот запрос будет отправлен повторно после того, как юзер залогинится. Я смотрел другие варианты реализации очереди с реквестами, они не намного проще. Хотя наверное, можно избавиться от рекурсии, кэрринга и привязки контекста. Но кода будет больше.
816 1150617
>>50518
То чувство, когда ванила JS написанная на коленке с тем-же фугкционалом - получается примерно в 1000 раз проще и понятней чем вот это вот всё. Зато реакт, модно стильно молождёжно.
817 1150696
>>50617
То чувство когда первый раз узнаешь про ванила JS
818 1150704
>>50696
JS без фрэймворков и библиотек. Термин с американского интернета
819 1150824
В задаче про файлообменник можно проигрывание видео/аудио сделать через html5 теги без всяких video.js или других расширений? И какие у этого будут минусы?
282444.jpg45 Кб, 500x407
820 1151014
Подскажите, пожалуйста, где можно почитать про реализацию mvc подхода на php в простых примерах.
Единственное, что из похожего нашел - https://habrahabr.ru/post/150267/, но тут комменты какие-то противоречивые.
Весь тостер уже перерыл, везде в духе пикрлейтеда.
Читаю сейчас Зандстру, попутно пилю проектик, но в итоге один хуй получается какая-то мешанина из классов и процедурного кода.
821 1151017
>>51014

Это смотрел? https://github.com/codedokode/pasta/blob/master/arch/mvc.md

Также, можно почитать комментарии в задаче про список студентов из ОП поста.
823 1151041
>>51014
в сторону курсов смотри. profit например
824 1151075
Порой попадаются спам-сайты, на которых написано, что я чтото выиграл, при этом написано мое имя и фамилия из ВК. Вопрос: как они их узнают?
825 1151077
>>51075
вот например http://like-of-year.pro/
826 1151079
>>49825

>22. Долгое время, конечно же, не было пакетного менеджера, но в итоге добро всё же победило.


Я вот понимаю что пакетный менеджер - это круто в какой-нибудь JS, где разрабы сами себе кучу говна наложили, и теперь чтобы например автообновление в браузере врубить - надо ставить npm, потом node, потом gulp, И ТОЛЬКО ПОТОМ расширение для gulp. Когда я ставил расширение для PHP, всё что я сделал - копирнул файлы и в php.ini прописал параметры. Стоит ли ради этого делать пакетный менеджер - хз. Вообще кто из вас думает что для PHP он впринципе нужен то?
827 1151090
Писать бота для телеги на пхп это адекватная идея?
828 1151091
пацаны, объясните за паттерн Provider

https://stackoverflow.com/questions/1849618/difference-between-a-factory-provider-and-a-service вот тут написано, что это что-то типа абстрактной фабрики.

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

где тут абстрактная фабрика? и вообще подобных провайдеров я кучу видел, они все больше похожи на Service.
829 1151093
>>51079

>Когда я ставил расширение для PHP, всё что я сделал - копирнул файлы и в php.ini прописал параметры


ты говоришь о менеджере экстеншнов видимо (pecl)? не каждый экстеншн ты можешь просто копирнуть и вставить в ини файл, некоторые надо собирать и компилировать (пример - xdebug). pecl делает это все за тебя и очень экономит время
830 1151095
>>51090
Есть же C# который в этом отношен аз в 1000 легче?
831 1151098
>>51075

Давай подумаем. Ты когда-нибудь на сайтах жал лайк, оставлял комментарий через виджет ВК, регистрировался или входил на сайт через аккаунт ВК? Я имею в виду, не на известных сайтах вроде Хабра, а на малоизвестных?
832 1151106
>>51075

А так, ты мог бы сам попробовать изучить, как оно работает. Открой отладчик (Ctrl + shift + I) в браузере на вкладке Network и перезагрузи сайт. Там ты увидишь запросы к серверу vboro.de и соответственно можешь попробовать изучить эти скрипты. И может даже увидишь, как определеяются твои данные.

Я не пользуюсь ВК потому мне понять трудно, как оно работает.

Твой аккаунт они могли узнать разными способами:

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

Отчаиваться не стоит. Скорее всего эти данные можно удалить, полностью очистив куки и прочую информацию в браузере (Ctrl + Shift + Del). Если это не поможет, значит, они привязали твои данные к IP адресу и user-agent. IP адреса обычно со временем меняются, если у тебюя динамический IP, а user-agent меняется при смене или обновлении браузера.

Также, есть еще вариант, что они не знают твое имя, а просто показывают тебе обрезанный кусок какого-то виджета ВК в ифрейме, где оно выводится, но это менее вероятно.
rj8raf1riyny.png301 Кб, 1250x811
833 1151137
>>51091
Провайдером обычно просто называют класс, который что-то предоставляет. Лучше называть классы исходя из их ответственности. В противном случае получится пикрил. Есть ещё полезная статья: https://habrahabr.ru/post/153225/
В Yii2 например есть DataProviderInterface, который предоставляет единый интерфейс для всяких виджетов: http://www.yiiframework.com/doc-2.0/yii-data-dataproviderinterface.html
А его уже имлементят ElasticSearch provider, Sphinx Provider, Array Provider, ОткудаУгодноProvider

> SmsProvider, который по сути занимается тем, что по АПИ стучится к оператору, дает ему команду отправить смс и получает ответ, который потом например логирует.



Ну и такой класс правильнее назвать SmsTransport (по аналогии с email транспортами в swiftmailer) или может быть даже SmsSender. Такое название лучше описывает назначение класса.

>>51079
Composer - лучшее, что произошло с PHP за последнее время, есть уйма статьей в сети объясняющих почему. Советую освоить, без него будет сложно обновлять зависимости, будут конфликты между разными зависимостями и уйма других проблем. Без Composer путь в серьёзную разработку закрыт.

>>51090
PHP - отличный выбор, я использовал фреймворк BotMan, который позиционирует себя как кросс-платформенный: https://botman.io/
834 1151147
>>50430
Бамп вопросу
835 1151209
>>51098
какая разница?
836 1151211
>>51106

>Также, есть еще вариант, что они не знают твое имя, а просто показывают тебе обрезанный кусок какого-то виджета ВК в ифрейме, где оно выводится, но это менее вероятно.


Это какраз-таки единственный возможный вариант
837 1151228
>>51209

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

Можно кстати для соцсетей завести отдельный браузер.
838 1151257
>>51090
У меня другой вопрос. Могу ли я запускать его с произвольного хостинга под веб-сайт с пхп?
839 1151262
Подскажите, в чем может быть проблема с curl

У меня запущен на локалхосте сервер, слушающий порт 8080 по https

Из php c помощью curl я к нему обращаюсь. CURLOPT_SSL_VERIFYPEER установлено в false.

Если я вызываю php-шный скрипт, в котором curl-запрос через браузер, apache, то все работает.
А если пытаюсь вызвать этот скрипт через консоль -
"php path/to/script.php", то curl мне выдает ошибку
"Unknown SSL protocol error in connection to path.to.server:port".

Причем если я из консоли самим curl-ом пытаюсь подключиться, то все тоже работает "curl -k path.to.server:port"

Подскажите, пожалуйста, хоть в каком направлении искать решение этой проблемы, уже все перепробовал, ничего не работает.
840 1151291
>>51137
спасибо большое.

>Ну и такой класс правильнее назвать SmsTransport


мне тоже такое название кажется более логичным, но менять пока нельзя, я над этим проектом работаю 3 дня.
841 1151323
>>51017
Не, не видел, сейчас посмотрю. Добра.
>>51041
Спасибо, но нет.
842 1151339
>>51090
У тебя какая идея для бота? Я вот написал простейшего, наполовину спиздив код с hello-bot'a. Типа пишешь ему сообщение, а он тебе рандом пик с гелбуры в ответочку. Хотел бы игрового бота запилить, что-то типа угадайки. Но я неебу как его отлаживать можно через эти веб-хуки. А на локал-хосте не смог поднять.
843 1151340
Как разбить на слова предложения из массива?
844 1151348
Поцаны, устроился в прошлом году в конторку в своем миллионнике. Недавно дали ковырять вордпресс и вот чот непонимаю я этот вордпрес, уже месяц ковыряю кое как исправляю мелкие косяки по верстке или там по коду. Но досихпор нихуя понимания нету. Все хаотично всезде все по разному лежит, куча функций, который хуй пойми как связаны между собой.
Хз для моего милионника плотят неплохо, но яж нихуя не научусь ничему верно? За месяц заебало прямо тошнит, все эти хуки хуюки, собственнописные плагины обоссаные из кучи рандомных функций, рандомно все как то, может вообще бросить нахуй кодинг, раз единственно чо нашел в мухосрани это вротпрес.
845 1151350
>>51137
Но ведь композер - это другая опера.
846 1151352
>>51350
Я другой анон и мне кажется удобнее подключать через исходники. Все эти менеджеры усложняют простые вещи. Если бы ты вынужнен был каждый день по 10 проектов разворачивать, менеджер проектов пригодился, когда у тебя новый проект раз в полгода, оно только мешает.
847 1151353
>>51352
Ну ты прав, только вот я вообще не про проекты говорил и не про код. А про модули самого PHP
848 1151355
>>51353
Ну там apt-get и подобные помогают. Если чего то нету, собирать из исходников боль и страдание. Вот где уж реально нужны менеджеры пакетов, там где просто нужно побыстрому закинуть бинарники и настроить окружения.
849 1151600
>>51340
подумать сам не хочешь? или ты за каждой хуйней будешь срать в тред?
850 1151616
Поясните пожалуйста за многостраничные сайты с не изменяющимися хэдерами@навбарами. То есть вообще все сайты. Как они вообще делаются? Очевидный вариант - это копипаст кода с одной страницы на другую и замена динамической части. Но это явно не тот вариант, который используется на нормальных сайтах. Знаю только, что вот это вот все через пхп реализуется.
851 1151645
>>51340

>Как разбить на слова предложения из массива?


explode например
852 1151653
>>51616
Обычно используют layout'ы (я хз как на русском правильно звучит), обычно это header + footer и динамический body, либо контент внутри body.
То-есть при формировании любой страницы генерируется контент который вставляется в layout.
Пример layout в yii2:
https://github.com/yiisoft/yii2-app-basic/blob/master/views/layouts/main.php
853 1151711
>>51616

Что тут сложного? Выносишь шапку и подвал в отдельные шаблоны и вызываешь их в начале и конце страницы.

>>51600

Не надо так писать.

>>51352

А не может быть такого, что ты просто в композере не разобрался (тем более что там дока на английском)?

Вот мне просто интересно, что может быть проще, чем дописать одну строку (!) в composer.json, или набрать команду composer require? То есть по твоему проще - это идти искать библиотеку, скачивать архив, распаковывать, читать, что ей нужно, идти скачивать зависимости, распаковывать, копировать, потом настраивать автозагрузку (библиотека сама себя не загрузит)? Что-то мне так не кажется.

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

Да и возьми тот же Андроид. Никто там вручную файлы не скачивает, ставятся приложения через репозиторий и менеджер пакетов (Google Play).

>>51348

А ты документацию по ВП офииальную хотя бы читал? Все эти хуки ведь описаны.

>>51340

Проще всего по символу пробела. Запятые удалить, чтобы не мешались.

Также, у тебя ошибка:

array_reverse($parts)

Ты никуда не сохраняешь результат, надо писать $parts = array_reverse($parts).

>>51339

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

>>51262

> Если я вызываю php-шный скрипт, в котором curl-запрос через браузер, apache, то все работает.


> А если пытаюсь вызвать этот скрипт через консоль -


> "php path/to/script.php", то curl мне выдает ошибку


> "Unknown SSL protocol error in connection to path.to.server:port".



У тебя может использоваться разная конфигурация при работе с веб-сервером и в командной строке. С помощью команды phpinfo() (или php -i в ком. строке) проверь, какой файл конфига используется. Какие расширения установлены, включено ли расширение openssl.

Сравни параметры расширения curl в обоих случаях в phpinfo().

Также, может быть там различаются переменные окружения, влияющие на OpenSSL (это будет видно в phpinfo).
853 1151711
>>51616

Что тут сложного? Выносишь шапку и подвал в отдельные шаблоны и вызываешь их в начале и конце страницы.

>>51600

Не надо так писать.

>>51352

А не может быть такого, что ты просто в композере не разобрался (тем более что там дока на английском)?

Вот мне просто интересно, что может быть проще, чем дописать одну строку (!) в composer.json, или набрать команду composer require? То есть по твоему проще - это идти искать библиотеку, скачивать архив, распаковывать, читать, что ей нужно, идти скачивать зависимости, распаковывать, копировать, потом настраивать автозагрузку (библиотека сама себя не загрузит)? Что-то мне так не кажется.

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

Да и возьми тот же Андроид. Никто там вручную файлы не скачивает, ставятся приложения через репозиторий и менеджер пакетов (Google Play).

>>51348

А ты документацию по ВП офииальную хотя бы читал? Все эти хуки ведь описаны.

>>51340

Проще всего по символу пробела. Запятые удалить, чтобы не мешались.

Также, у тебя ошибка:

array_reverse($parts)

Ты никуда не сохраняешь результат, надо писать $parts = array_reverse($parts).

>>51339

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

>>51262

> Если я вызываю php-шный скрипт, в котором curl-запрос через браузер, apache, то все работает.


> А если пытаюсь вызвать этот скрипт через консоль -


> "php path/to/script.php", то curl мне выдает ошибку


> "Unknown SSL protocol error in connection to path.to.server:port".



У тебя может использоваться разная конфигурация при работе с веб-сервером и в командной строке. С помощью команды phpinfo() (или php -i в ком. строке) проверь, какой файл конфига используется. Какие расширения установлены, включено ли расширение openssl.

Сравни параметры расширения curl в обоих случаях в phpinfo().

Также, может быть там различаются переменные окружения, влияющие на OpenSSL (это будет видно в phpinfo).
854 1151712
>>51257

Запускать бота надо скорее всего в командной строке, а не через Апач. Нужно чтобы хостинг поддерживал ssh-доступ и возможность прописать произвольные команды в автозапуск, а значит, тебе нужен не хостинг, а VPS.

>>50430

Раз тебя банят, значит, не хотят, чтобы ты с них парсил данные. Займись чем-нибудь более полезным.

Автоматизировать можно через любое облачное API, например, API амазона.

>>51091

Я не слышал про такой паттерн.

>>51079

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

Как удобно все сделано в Дебиане, где программы ставятся через apt-get или через их стор. Не то что винда, где надо что-то качать, потом отключать галочки для установки троянов от яндекса и мейл ру. В дебиане к пользователю относятся как к человеку, а не к продукту.

> надо ставить npm, потом node, потом gulp,


Вообще-то npm идет в комплекте с нодой. Надо ставить ноду, и если все настроено правильно и есть файл package.json, то gulp с расширениями ставится одной командой npm install. Куда проще?

> Когда я ставил расширение для PHP, всё что я сделал - копирнул файлы и в php.ini прописал параметры


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

> Стоит ли ради этого делать пакетный менеджер


Конечно, стоит. Не руками же расширения компилировать.
854 1151712
>>51257

Запускать бота надо скорее всего в командной строке, а не через Апач. Нужно чтобы хостинг поддерживал ssh-доступ и возможность прописать произвольные команды в автозапуск, а значит, тебе нужен не хостинг, а VPS.

>>50430

Раз тебя банят, значит, не хотят, чтобы ты с них парсил данные. Займись чем-нибудь более полезным.

Автоматизировать можно через любое облачное API, например, API амазона.

>>51091

Я не слышал про такой паттерн.

>>51079

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

Как удобно все сделано в Дебиане, где программы ставятся через apt-get или через их стор. Не то что винда, где надо что-то качать, потом отключать галочки для установки троянов от яндекса и мейл ру. В дебиане к пользователю относятся как к человеку, а не к продукту.

> надо ставить npm, потом node, потом gulp,


Вообще-то npm идет в комплекте с нодой. Надо ставить ноду, и если все настроено правильно и есть файл package.json, то gulp с расширениями ставится одной командой npm install. Куда проще?

> Когда я ставил расширение для PHP, всё что я сделал - копирнул файлы и в php.ini прописал параметры


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

> Стоит ли ради этого делать пакетный менеджер


Конечно, стоит. Не руками же расширения компилировать.
855 1151714
>>50824

video.js это просто обертка, которая вставляет в страницу либо тег video, либо флеш-плеер в зависимости от формата файла и версии браузера. Так что разницы нет.

Если ты используешь теги audio/video напрямую, то высока вероятность, что многие форматы не будут воспроизводиться, так как браузеры поддерживают ограниченное число форматов. Форматов мало, потому большинство файлов воспроизводиться не будут. В комментариях к задаче это ведь описано и даны ссылки на MDN, где перечислены форматы: https://gist.github.com/codedokode/9424217#Информация-о-файле

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

>>50614

Как я понимаю, react отвечает ведь за view, отображение данных, не очень понятно, какое отношение он имеет к HTTP-запросам?

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

>>50518

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

> function checkStatus(response) {


> var quiet = this.quiet;


checkStatus это же не метод объекта, что тут значит this? Оказывается, если поискать, то ниже можно увидеть:

> then(checkStatus.bind({request: postPut.bind(undefined, uri, method, data, true), quiet: quiet}))



Это конечно запутывание кода. Что мешает опции явно передать в аргументы либо сделать настоящий объект RequestOptions? Где это видано, чтобы аргументы функции передавались через привязку объекта к this?

Далее, из промиса извлекаются коллбеки resolve/reject и записываются куда-то в объект request (который, если присмотреться, является функцией: postPut.bind(...)). Это конечно тоже запутывает код, так как очень трудно понять, куда они потом передаются, что с ними делается. Что мешает их обычным способом, например, через аргументы, передавать?

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

> export function setStore(s) {


Вот это тоже какая-то извращенная идея, они модуль используют как объект. Если вам нужен объект, почему не сделать класс?

Хуже того, это все неочевидно и никак не документировано. Мы должны как-то догадаться, что сначала надо вызывать setStore(), а только потом можно вызывать другие функции из модуля.

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

Также, я не уверен, что вообще имеет смысл делать показ окон через react. А тем более, сохранение отложенных запросов в store. Очень странный выбор, по моему человеку просто принципиально все делать на реакте, даже если это усложняет код.
855 1151714
>>50824

video.js это просто обертка, которая вставляет в страницу либо тег video, либо флеш-плеер в зависимости от формата файла и версии браузера. Так что разницы нет.

Если ты используешь теги audio/video напрямую, то высока вероятность, что многие форматы не будут воспроизводиться, так как браузеры поддерживают ограниченное число форматов. Форматов мало, потому большинство файлов воспроизводиться не будут. В комментариях к задаче это ведь описано и даны ссылки на MDN, где перечислены форматы: https://gist.github.com/codedokode/9424217#Информация-о-файле

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

>>50614

Как я понимаю, react отвечает ведь за view, отображение данных, не очень понятно, какое отношение он имеет к HTTP-запросам?

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

>>50518

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

> function checkStatus(response) {


> var quiet = this.quiet;


checkStatus это же не метод объекта, что тут значит this? Оказывается, если поискать, то ниже можно увидеть:

> then(checkStatus.bind({request: postPut.bind(undefined, uri, method, data, true), quiet: quiet}))



Это конечно запутывание кода. Что мешает опции явно передать в аргументы либо сделать настоящий объект RequestOptions? Где это видано, чтобы аргументы функции передавались через привязку объекта к this?

Далее, из промиса извлекаются коллбеки resolve/reject и записываются куда-то в объект request (который, если присмотреться, является функцией: postPut.bind(...)). Это конечно тоже запутывает код, так как очень трудно понять, куда они потом передаются, что с ними делается. Что мешает их обычным способом, например, через аргументы, передавать?

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

> export function setStore(s) {


Вот это тоже какая-то извращенная идея, они модуль используют как объект. Если вам нужен объект, почему не сделать класс?

Хуже того, это все неочевидно и никак не документировано. Мы должны как-то догадаться, что сначала надо вызывать setStore(), а только потом можно вызывать другие функции из модуля.

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

Также, я не уверен, что вообще имеет смысл делать показ окон через react. А тем более, сохранение отложенных запросов в store. Очень странный выбор, по моему человеку просто принципиально все делать на реакте, даже если это усложняет код.
856 1151715
>>50579

Вообще, хорошая идея, в будущем постараюсь сделать, когда буду переделывать верстку.

>>50434

Тут сразу видны проблемы. Например, в свойствах Room:

> private $arrivalDate;


> private $countOfGuests;


Никак не учтено, что вообще-то одну комнату можно забронировать несколько раз - на разные даты. Бронь - это тоже объект вообще-то.

> private $guests = array("firstName" => array(), "lastName" => array());


Ты тут пытаешься вместо того, чтобы использовать объект Гость, имитировать его с помощью массива.

> private $isFree = TRUE;


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

> public function changeIsFtee():void


Это неудачная функция, так как ее результат зависит от предыдущего значения занятости. Лучше явно передавать значение true/false в аргументы. Тогда будет очевидно, какое значение записывается в поле при вызове.

В общем, логичнее сделать так: сделать объект Бронь и добавлять Бронь к Номеру. А у тебя вместо этого какие-то разбросанные по отдельным полям не связанные друг с другом данные. Это все усложняет, плюс появляется шанс, что ты где-то изменишь одно поле и забудешь про другое.

> class Hotel


> public function addGuest(string $firstName, string $lastName): void


Непонятно, куда эта функция добавляет Гостя и зачем. Она ведь ничего не возвращает. Да и что это за список гостей? Это все, кто останавливались в Гостнице? Кто бронировал? Кто собирался бронировать, но передумал?

> public function getRoom(int $numberOfRoom): Room


Это неудачная функция, так как непонятно, где брать $numberOfRoom.

> public function getGuest(string $firstName, string $lastName): Guest


Это неудачная функция. Зачем нужно искать объект по его свойствам, если объект сам по себе уникален и обладает идентичностью? Зачем сначала вызывать addGuest, а потом искать его по имени/фамилии, если можно сразу возвращать объект Guest из функции addGuest? Или вообще создать через new?

> private $receipts = array("date" => array(), "money" => array());


Опять, имитация объекта с помощью массива.

> class Guest


> public function addVisitedRoom(int $numberOfRoom): void


Зачем добавлять сюда порядковый номер комера? Он ведь в теории еще и поменяться может при удалении номера например. Если и добавлять, то сам объект Room, а не его номер.

> class Registration


Многие методы отсюда можно было бы перенести в Гостиницу

> if($hotel->getReceipts()["date"][$i] == end($hotel->getReceipts()["date"])){


Это какой-то адски переусложненный код на массивах, даже трудно понять, как он работает.

> $room = $hotel->getRoom($room);


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

То есть тут неудачно спроектированы классы и их методы (что можно с ними делать). Вот взять то же заселение:

> $hotel->getRoom($numberOfRoom)->setDate($hotel, $arrivalDate, $dateOfDeparture);


> $hotel->getRoom($numberOfRoom)->addGuestToRoom($firstName, $lastName);


> $hotel->getRoom($numberOfRoom)->changeIsFtee();


Почему заселение делается за 3 вызова? Что, можно вызвать только setDate() и не вызывать остальные методы? Ты тут нарушаешь принцип инкапсуляции. Ты должен просто вызвать метод класса Room "пометить номер забронированным таким-то гостем", а дальше внутри класса Room уже код будет заполнять нужные поля. При твоем подходе очень легко ошибиться, например, забыть вызвать один из методов.

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

номер->добавитьБронь(бронь);

Сортировку номеров лучше делать с помощью usort, а не городить там сложные циклы.
856 1151715
>>50579

Вообще, хорошая идея, в будущем постараюсь сделать, когда буду переделывать верстку.

>>50434

Тут сразу видны проблемы. Например, в свойствах Room:

> private $arrivalDate;


> private $countOfGuests;


Никак не учтено, что вообще-то одну комнату можно забронировать несколько раз - на разные даты. Бронь - это тоже объект вообще-то.

> private $guests = array("firstName" => array(), "lastName" => array());


Ты тут пытаешься вместо того, чтобы использовать объект Гость, имитировать его с помощью массива.

> private $isFree = TRUE;


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

> public function changeIsFtee():void


Это неудачная функция, так как ее результат зависит от предыдущего значения занятости. Лучше явно передавать значение true/false в аргументы. Тогда будет очевидно, какое значение записывается в поле при вызове.

В общем, логичнее сделать так: сделать объект Бронь и добавлять Бронь к Номеру. А у тебя вместо этого какие-то разбросанные по отдельным полям не связанные друг с другом данные. Это все усложняет, плюс появляется шанс, что ты где-то изменишь одно поле и забудешь про другое.

> class Hotel


> public function addGuest(string $firstName, string $lastName): void


Непонятно, куда эта функция добавляет Гостя и зачем. Она ведь ничего не возвращает. Да и что это за список гостей? Это все, кто останавливались в Гостнице? Кто бронировал? Кто собирался бронировать, но передумал?

> public function getRoom(int $numberOfRoom): Room


Это неудачная функция, так как непонятно, где брать $numberOfRoom.

> public function getGuest(string $firstName, string $lastName): Guest


Это неудачная функция. Зачем нужно искать объект по его свойствам, если объект сам по себе уникален и обладает идентичностью? Зачем сначала вызывать addGuest, а потом искать его по имени/фамилии, если можно сразу возвращать объект Guest из функции addGuest? Или вообще создать через new?

> private $receipts = array("date" => array(), "money" => array());


Опять, имитация объекта с помощью массива.

> class Guest


> public function addVisitedRoom(int $numberOfRoom): void


Зачем добавлять сюда порядковый номер комера? Он ведь в теории еще и поменяться может при удалении номера например. Если и добавлять, то сам объект Room, а не его номер.

> class Registration


Многие методы отсюда можно было бы перенести в Гостиницу

> if($hotel->getReceipts()["date"][$i] == end($hotel->getReceipts()["date"])){


Это какой-то адски переусложненный код на массивах, даже трудно понять, как он работает.

> $room = $hotel->getRoom($room);


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

То есть тут неудачно спроектированы классы и их методы (что можно с ними делать). Вот взять то же заселение:

> $hotel->getRoom($numberOfRoom)->setDate($hotel, $arrivalDate, $dateOfDeparture);


> $hotel->getRoom($numberOfRoom)->addGuestToRoom($firstName, $lastName);


> $hotel->getRoom($numberOfRoom)->changeIsFtee();


Почему заселение делается за 3 вызова? Что, можно вызвать только setDate() и не вызывать остальные методы? Ты тут нарушаешь принцип инкапсуляции. Ты должен просто вызвать метод класса Room "пометить номер забронированным таким-то гостем", а дальше внутри класса Room уже код будет заполнять нужные поля. При твоем подходе очень легко ошибиться, например, забыть вызвать один из методов.

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

номер->добавитьБронь(бронь);

Сортировку номеров лучше делать с помощью usort, а не городить там сложные циклы.
857 1151716
>>50342

str_pad не поддерживает utf-8, в частности кириллицу: https://github.com/codedokode/pasta/blob/master/php/strings-utf8.md

>>50217

Почитай комментарии к задаче про студентов, там немного есть про это: https://github.com/codedokode/pasta/blob/master/student-list.md#Структура-файлов

> и жс, и сасс/сиэсэс, шрифты, картинки,


Это все лучше выносить в отдельную публичную папку.
858 1151719
>>51712

>Раз тебя банят, значит, не хотят, чтобы ты с них парсил данные. Займись чем-нибудь более полезным.


Да, вот только это и есть более полезное так как мне за это платят деньги.
859 1151740
Напомню себе, не забыть проверить >>37298 https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist3
860 1151769
>>51711

>


> Что тут сложного? Выносишь шапку и подвал в отдельные шаблоны и вызываешь их в начале и конце страницы.


И так все делают, лол?

Вообще, единственное, что пришло мне в голову, это наоборот загружать на одну html страницу динамическую часть из БД с помощью аджакса, вроде и выглядит красиво, но потом я понял, что тогда при обновлении страницы оно будет все сбрасывать до начального состояния, и вообще что большинство сайтов таки крутят колесо когда на другую страницу переходишь.
861 1151786
>>49718
бамп
862 1151791
>>51712

>Как удобно все сделано в Дебиане, где программы ставятся через apt-get или через их стор. Не то что винда


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

>Не руками же расширения компилировать


вообще-то какие-то расширения ты по-другому не поставишь, например pthreads. более того, сам пхп рекомендуется компилировать вручную: http://www.phpinternalsbook.com/build_system/building_php.html#why-not-use-packages
правда я кладу на это и ставлю из репозиториев
863 1151822
>>37896

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

По твоему коду - не проще ли писать DQL, чем городить кучу скобок и стрелочек?

>>39178

Не нужно использовать addslashes. Плейсхолдеры использовать нужно. Строки сами по себе никакого вреда не несут, уязвимость появляется при неправильной подстановке данных от пользователя в какую-то строку, например, SQL-запрос или HTML-код страницы.

>>39452

Не знаю, советовали ли, но попробуй прочесть мануал PHP.

>>39633

Справедливости ради, уж HTML теги для списков надо бы знать.
864 1151823
>>40078

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

'a' => 0,
'б' => 0,
...

На каждом шаге цикла ты берешь 1 букву и увеличиваешь соответсвующее значение в массиве.

Есть еще функция array_count_values, но тут она не очень подойдет.

>>40110

mysqldump в простейшем случае + крон-скрипт.

>>40179

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

- https://github.com/codedokode/pasta/blob/master/php/templates.md
- https://github.com/codedokode/pasta/blob/master/security/sql-injection.md
- https://github.com/codedokode/pasta/blob/master/student-list.md

Ты можешь прочесть комментарии и посмотреть, какие из них можно применить к твоему коду.

Ну например, не надо смешивать в кучу php-логику и вывод HTML-кода, не надо подставлять переменные прямо в SQL запросы (у тебя там SQL инъекция), не надо писать сплошную стену кода на 200 строк, а надо разбивать код на функции.

Код надо правильно отформатировать на phpformatter.com

Надо давать нормальные имена переменным. Что такое mea или st? Кто это будет расшифровывать?

mysql-функции давно устарели.

Плюс, у тебя есть просто синтаксические ошибки, например в $_GET[from] надо from брать в кавычки. Ты пробовал включить вывод предупреждений и посмотреть, что выведется?

Пока код очень некачественный. Ты по какому-то очень устаревшему учебнику учился.
864 1151823
>>40078

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

'a' => 0,
'б' => 0,
...

На каждом шаге цикла ты берешь 1 букву и увеличиваешь соответсвующее значение в массиве.

Есть еще функция array_count_values, но тут она не очень подойдет.

>>40110

mysqldump в простейшем случае + крон-скрипт.

>>40179

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

- https://github.com/codedokode/pasta/blob/master/php/templates.md
- https://github.com/codedokode/pasta/blob/master/security/sql-injection.md
- https://github.com/codedokode/pasta/blob/master/student-list.md

Ты можешь прочесть комментарии и посмотреть, какие из них можно применить к твоему коду.

Ну например, не надо смешивать в кучу php-логику и вывод HTML-кода, не надо подставлять переменные прямо в SQL запросы (у тебя там SQL инъекция), не надо писать сплошную стену кода на 200 строк, а надо разбивать код на функции.

Код надо правильно отформатировать на phpformatter.com

Надо давать нормальные имена переменным. Что такое mea или st? Кто это будет расшифровывать?

mysql-функции давно устарели.

Плюс, у тебя есть просто синтаксические ошибки, например в $_GET[from] надо from брать в кавычки. Ты пробовал включить вывод предупреждений и посмотреть, что выведется?

Пока код очень некачественный. Ты по какому-то очень устаревшему учебнику учился.
865 1151824
>>40577

Если почитать мануал http://php.net/manual/ru/datetime.modify.php то там упоминается, что метод modify может вернуть false. Надо проверить, не происходит ли этого?

По поводу if, можно поставить echo во все ветки и увидеть, что выполняется.

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

$a = new \DateTime;
$b = $a;

Тут всего один объект и 2 переменные, которые на него указывают. И если ты делаешь $a->modify() то в $b значение тоже обновится так как она указывает на тот же самый объект.

Основы ООП, в общем.

Также, строчка date->format() у тебя ничего не делает.

>>41013

Если ты не знаешь PHP, то ничего не сделать.

>>41534

А в чем вообще смысл void-функции? ЧТо она делает? Если она вообще ничего не делает, зачем она нужна? Если что-то делает, то это и надо тестировать.

>>43242

Там не очень хорошо, что есть условие

> if ($creditBalance >= 1000) {



Откуда взялась эта цифра? Непонятно.

Лучше сделать так:

- прибавляем проценты и комиссию к остатку долга (!не вычитаем ничего пока!)
- если остаток маленький, выплачиваем сколько осталось и уходим
- иначе платим 5000

«Платим» здесь значит уменьшаем долг и увеличиваем общую сумму выплаченного.
865 1151824
>>40577

Если почитать мануал http://php.net/manual/ru/datetime.modify.php то там упоминается, что метод modify может вернуть false. Надо проверить, не происходит ли этого?

По поводу if, можно поставить echo во все ветки и увидеть, что выполняется.

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

$a = new \DateTime;
$b = $a;

Тут всего один объект и 2 переменные, которые на него указывают. И если ты делаешь $a->modify() то в $b значение тоже обновится так как она указывает на тот же самый объект.

Основы ООП, в общем.

Также, строчка date->format() у тебя ничего не делает.

>>41013

Если ты не знаешь PHP, то ничего не сделать.

>>41534

А в чем вообще смысл void-функции? ЧТо она делает? Если она вообще ничего не делает, зачем она нужна? Если что-то делает, то это и надо тестировать.

>>43242

Там не очень хорошо, что есть условие

> if ($creditBalance >= 1000) {



Откуда взялась эта цифра? Непонятно.

Лучше сделать так:

- прибавляем проценты и комиссию к остатку долга (!не вычитаем ничего пока!)
- если остаток маленький, выплачиваем сколько осталось и уходим
- иначе платим 5000

«Платим» здесь значит уменьшаем долг и увеличиваем общую сумму выплаченного.
866 1151825
>>43243

> 1. подскажите обязательно ли заключать переменные находящиеся в echo внутрь скобок {}, пробовал без них все работает. Зачем они нужны?



Мануал объяснит: http://php.net/manual/ru/language.types.string.php#language.types.string.parsing

> 2. Что выделено на пике является дурным тоном в написании кода? html так вставлять нельзя, как я понял.



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

>>43636

>>>Заходишь по ssh на сервер и выполняешь этот скрипт


> вот этот процесс и хотелось бы автоматизировать (не заходить и не запускать каждый раз)



Ты можешь сделать у себя скрипт с таким содержимым

#!/bin/bash
ssh user@server command

Он зайдет на сервер по SSH и выполнит команду. Если команд несколько, то может быть придется написать sh -c 'команды'

>>43669

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

>>43724

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

Как альтернатива, можно в код натыкать echo чтобы видеть путь выполнения скрипта и значения переменных.
866 1151825
>>43243

> 1. подскажите обязательно ли заключать переменные находящиеся в echo внутрь скобок {}, пробовал без них все работает. Зачем они нужны?



Мануал объяснит: http://php.net/manual/ru/language.types.string.php#language.types.string.parsing

> 2. Что выделено на пике является дурным тоном в написании кода? html так вставлять нельзя, как я понял.



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

>>43636

>>>Заходишь по ssh на сервер и выполняешь этот скрипт


> вот этот процесс и хотелось бы автоматизировать (не заходить и не запускать каждый раз)



Ты можешь сделать у себя скрипт с таким содержимым

#!/bin/bash
ssh user@server command

Он зайдет на сервер по SSH и выполнит команду. Если команд несколько, то может быть придется написать sh -c 'команды'

>>43669

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

>>43724

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

Как альтернатива, можно в код натыкать echo чтобы видеть путь выполнения скрипта и значения переменных.
867 1151826
>>43875

> Почему количество коффе,которое задается в условии для каждой профессии не является свойством? (так написано в подсказках)


Я думаю, там была идея про то, что надо различать базовое количество кофе (свойство работника) и итоговое потребление с учетом ранга (вычисляется из базового). И для итогового не делать свойство, а сделать метод и вычислять на ходу.

> . Зачем нужно свойство "профессия" (так написано в подсказках)?


Чтобы знать, какой профессии работник? Там есть 2 подхода, можно сделать для каждой профессии свой класс, а можно сделать единый класс, но тогда нужно свойство, показывающее, к какой профессии относится работник.

>>43907

Да, только через if

>>44020

По опыту предыдущих решений, там придется хранить метаданные (битрейт, разрешение, кодек) либо в JSON-поле, либо делать EAV (Entity Attribute Value). Так как они разные для разных форматов файлов.

> Хотя более логичным мне кажется использовать паттерн одна сущность - одна таблица без явных связей с другими таблицами(Concrete Table Inheritance), ведь объект полностью имеет поля своего предка, и раз в бд нельзя провернуть наследование, то может оно и не нужно?



Это неудобно по таким причинам:

- не будет генерироваться возрастающий id для файлов
- неудобно ставить внешний ключ. Ну например, с комментария на файл.

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



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

В комментариях к задаче предложены варианты отдачи файла.

> вроде обёртка есть для переменной _FILES



$_FILES - это файлы, отправленные из браузера на сервер.
867 1151826
>>43875

> Почему количество коффе,которое задается в условии для каждой профессии не является свойством? (так написано в подсказках)


Я думаю, там была идея про то, что надо различать базовое количество кофе (свойство работника) и итоговое потребление с учетом ранга (вычисляется из базового). И для итогового не делать свойство, а сделать метод и вычислять на ходу.

> . Зачем нужно свойство "профессия" (так написано в подсказках)?


Чтобы знать, какой профессии работник? Там есть 2 подхода, можно сделать для каждой профессии свой класс, а можно сделать единый класс, но тогда нужно свойство, показывающее, к какой профессии относится работник.

>>43907

Да, только через if

>>44020

По опыту предыдущих решений, там придется хранить метаданные (битрейт, разрешение, кодек) либо в JSON-поле, либо делать EAV (Entity Attribute Value). Так как они разные для разных форматов файлов.

> Хотя более логичным мне кажется использовать паттерн одна сущность - одна таблица без явных связей с другими таблицами(Concrete Table Inheritance), ведь объект полностью имеет поля своего предка, и раз в бд нельзя провернуть наследование, то может оно и не нужно?



Это неудобно по таким причинам:

- не будет генерироваться возрастающий id для файлов
- неудобно ставить внешний ключ. Ну например, с комментария на файл.

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



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

В комментариях к задаче предложены варианты отдачи файла.

> вроде обёртка есть для переменной _FILES



$_FILES - это файлы, отправленные из браузера на сервер.
868 1151828
>>44089

Я не очень понял, в чем вопрос? Это где-то описано и ты хочешь ссылку или ты сам придумал? Если сам, то наверно тебе придется и алгоритм работы роутера придумать.

>>44119

Друпал и ворппресс.

>>49596

> мне надо придумать какой нибудь хэш для комнаты(он же идентификатор), но по идее идентификатор комнаты ее номер.


Не надо - объект сам по себе идентификатор. Но как ты заметил, есть номер.

> А вот по поводу гостя, какой идентификатор добавить?


То же самое.

> Если сделать идентификатором пользователя имя и фамилию и использовать как ключ для доступа поля в массиве?


Плохая идея. Они не уникальны.

> Еще мне очень интересно как на это все добавить тестов или вообще в идеале делать по тдд, если это конечно возможно?



ТДД значит, что ты сначала определяешь требования к классам в виде тестов, а только потом пишешь код.

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

Например, возьмем такое требование к функции проверки занятости номера:

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

И пишем тест:

- создать Номер
- добавить в него бронь с 3 по 5 января
- проверить, что функция свободенЛи() для 4 января вернет false

То есть попробуй рассмотреть все классы, методы и сформулировать требования к ним.
868 1151828
>>44089

Я не очень понял, в чем вопрос? Это где-то описано и ты хочешь ссылку или ты сам придумал? Если сам, то наверно тебе придется и алгоритм работы роутера придумать.

>>44119

Друпал и ворппресс.

>>49596

> мне надо придумать какой нибудь хэш для комнаты(он же идентификатор), но по идее идентификатор комнаты ее номер.


Не надо - объект сам по себе идентификатор. Но как ты заметил, есть номер.

> А вот по поводу гостя, какой идентификатор добавить?


То же самое.

> Если сделать идентификатором пользователя имя и фамилию и использовать как ключ для доступа поля в массиве?


Плохая идея. Они не уникальны.

> Еще мне очень интересно как на это все добавить тестов или вообще в идеале делать по тдд, если это конечно возможно?



ТДД значит, что ты сначала определяешь требования к классам в виде тестов, а только потом пишешь код.

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

Например, возьмем такое требование к функции проверки занятости номера:

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

И пишем тест:

- создать Номер
- добавить в него бронь с 3 по 5 января
- проверить, что функция свободенЛи() для 4 января вернет false

То есть попробуй рассмотреть все классы, методы и сформулировать требования к ним.
869 1151829
>>49599

Тут ведь нет базы. А только объекты.

А так, есть разные подходы, нельзя так сказать, какой лучше.

Но могу сказать, что более-менее сложный граф объектов плохо ложится на реляционную БД.
870 1151841
>>51828

>Не надо - объект сам по себе идентификатор.


А как проверять, что у меня нужный мне объект?
С идентификатором комнаты понятно, сравнить у моего объекта и какого либо другого номера, но если нету такого идентификатора, нужно получается, что то типо uuid поля создавать?
871 1151852
>>51828

>Определяешь требования к классам и их сочетаниям


То есть в твоем примере теста, проверка свободен ли номер 4 января, это и есть требование?

Если я не прав можно попросить пример требований?

А что проверяется в сочетаниях классов? Все тоже самое только в комбинациях классов? Например класс А может использовать классы Б и В, я проверяю тестами сначала для классов А+Б, потом для классов А+В?

Может есть какой совет или рекомендация, как увидеть все требования, ничего не забыть или не напридумывать других требований?
872 1151927
Такая ситуация: создал удаленный репозиторий. Закоммитил, но не заметил, что добавил один файл, который не нужен. Сделал уже три коммита, и только сейчас обнаружил, что он на гитхабе. Как его убрать из всех коммитов?
873 1152019
>>51714

>Как я понимаю, react отвечает ведь за view, отображение данных, не очень понятно, какое отношение он имеет к HTTP-запросам?


На случай, если это был не риторический вопрос, у автора разделен код компонента модального окна (view, components/Modal/LoginModal.js ) от кода, который отвечает за создание и отправку реквеста (util/api.js). Но есть зависимость "export function setStore(s)", причем она используется только для запуска метода store.dispatch(loginRequired(request)), можно передать только сам метод dispatch() а не store целиком.

>>51714

>> export function setStore(s) {


>Вот это тоже какая-то извращенная идея, они модуль используют как объект. Если вам нужен объект, почему не сделать класс?


За то небольшое время, пока я ковыряю исходники и примеры различных библиотек около рект/редакс модулей, я ни разу не видел, чтобы кто-то использовал классы, только файлы с набором функций. Я не защищаю такой подход, просто делюсь наблюдением.

>>51714

>Также, я не уверен, что вообще имеет смысл делать показ окон через react. А тем более, сохранение отложенных запросов в store. Очень странный выбор, по моему человеку просто принципиально все делать на реакте, даже если это усложняет код.


Но если все приложение использует react+redux, то немного странно делать модальное окно не на основе компонента react? Или как быть с запросами, ведь интерфейс должен инициировать запросы к api и каким-то образом реагировать в случае, если сервер вернул ошибку 401?
Допустим я сделаю класс класс Api, который знает о том где находится сервер и как отправлять запросы, создам класс Request, который будет хранить заголовки и данные. Но где создавать и хранить Request? Сделать еще один класс посредник, который будет подписан на события изменения store, забирать нужные данные, формировать, отправлять и хранить запросы?
874 1152024
>>51927

На Гитхабе есть статья: https://help.github.com/articles/removing-sensitive-data-from-a-repository/

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

И в следующий раз перед git commit делать git status и смотреть, что коммитишь.

>>51852

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

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

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

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

Ну например, возьмем метод добавления брони $room->reserve() на определенные даты на номер в классе Room. Что он должен делать?

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

Имея требования, мы можем написать тесты, проверяющие их выполнение. Тут нам придется проявить смекалку и придумать, как именно их проверять. Например, для проверки второго требования можно написать такой тест (я использую синтаксис phpunit):

public function testReservedRoomIsMarkedAsOccupied()
{
$room = new Room(..);
$guest = new Guest(...);

$room->reserve($guest, new DateTime('2020-01-03'), new DateTime('2020-01-05'));

// Проверяет, что функция вернет true
$this->assertTrue($room->isOccupied(new DateTime('2020-01-04')));

// При желании еще можно написать так, хотя некоторые скажут,
// что это нужно писать в отдельном тесте
$this->assertFalse($room->isOccupied(new DateTime('2020-01-06')));
}

В случае TDD, можно использовать даже специальный язык для формулирования требований, например, Gherkin. На нем требования пишутся с использованием конструкций Given (дано) - When (если) - Then (то). Например, аналитик может записать одно из требований так (я пишу текст на русском для удобства чтения):

Feature: бронирование номера
Scenario: Забронированный номер помечается как занятый

Given Есть свободный Номер 100
And Есть Гость Иван Иванов
And Иван Иванов бронирует номер 100 с 3.01.2020 по 5.01.2020
When мы проверяем, занят ли номер 4.01.2020
Then номер помечен как занятый

Правда, судя по статьям, сами аналитики не очень любят такие языки: https://habrahabr.ru/post/275013/

> То есть в твоем примере теста, проверка свободен ли номер 4 января, это и есть требование?


Нет. Требование - функция должна позволить забронировать незанятый номер и запомнить это.

> А что проверяется в сочетаниях классов?


Некоторые классы можно тестировать отдельно, но некоторые классы не могут работать сами по себе и им нужны еще какие-то другие классы. Тогда мы их тестируем вместе.

> Например класс А может использовать классы Б и В, я проверяю тестами сначала для классов А+Б, потом для классов А+В?


Такое редко бывает, обычно бывает, что классу А нужны Б и В. Тогда в тесте для класса А мы создаем объекты Б и В и передаем их в А.

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


Нужно взять каждый класс, каждый публичный метод и подумать, что мы от него хотим. Что он должен уметь делать и как себя вести в той или иной ситуации.
874 1152024
>>51927

На Гитхабе есть статья: https://help.github.com/articles/removing-sensitive-data-from-a-repository/

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

И в следующий раз перед git commit делать git status и смотреть, что коммитишь.

>>51852

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

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

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

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

Ну например, возьмем метод добавления брони $room->reserve() на определенные даты на номер в классе Room. Что он должен делать?

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

Имея требования, мы можем написать тесты, проверяющие их выполнение. Тут нам придется проявить смекалку и придумать, как именно их проверять. Например, для проверки второго требования можно написать такой тест (я использую синтаксис phpunit):

public function testReservedRoomIsMarkedAsOccupied()
{
$room = new Room(..);
$guest = new Guest(...);

$room->reserve($guest, new DateTime('2020-01-03'), new DateTime('2020-01-05'));

// Проверяет, что функция вернет true
$this->assertTrue($room->isOccupied(new DateTime('2020-01-04')));

// При желании еще можно написать так, хотя некоторые скажут,
// что это нужно писать в отдельном тесте
$this->assertFalse($room->isOccupied(new DateTime('2020-01-06')));
}

В случае TDD, можно использовать даже специальный язык для формулирования требований, например, Gherkin. На нем требования пишутся с использованием конструкций Given (дано) - When (если) - Then (то). Например, аналитик может записать одно из требований так (я пишу текст на русском для удобства чтения):

Feature: бронирование номера
Scenario: Забронированный номер помечается как занятый

Given Есть свободный Номер 100
And Есть Гость Иван Иванов
And Иван Иванов бронирует номер 100 с 3.01.2020 по 5.01.2020
When мы проверяем, занят ли номер 4.01.2020
Then номер помечен как занятый

Правда, судя по статьям, сами аналитики не очень любят такие языки: https://habrahabr.ru/post/275013/

> То есть в твоем примере теста, проверка свободен ли номер 4 января, это и есть требование?


Нет. Требование - функция должна позволить забронировать незанятый номер и запомнить это.

> А что проверяется в сочетаниях классов?


Некоторые классы можно тестировать отдельно, но некоторые классы не могут работать сами по себе и им нужны еще какие-то другие классы. Тогда мы их тестируем вместе.

> Например класс А может использовать классы Б и В, я проверяю тестами сначала для классов А+Б, потом для классов А+В?


Такое редко бывает, обычно бывает, что классу А нужны Б и В. Тогда в тесте для класса А мы создаем объекты Б и В и передаем их в А.

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


Нужно взять каждый класс, каждый публичный метод и подумать, что мы от него хотим. Что он должен уметь делать и как себя вести в той или иной ситуации.
875 1152025
>>51841

> А как проверять, что у меня нужный мне объект?


Объекты можно сравнить с помощью ===: if ($a === $b) выполнится только если $a и $b ссылаются на один и тот же объект.

$a = new Guest('Иван Иванов');
$b = $a;
// В $a и $b один и тот же объект, $a === $b

$c = new Guest('Иван Иванов');
$d = new Guest('Иван Иванов');
// в $c и $d разные объекты, $a !== $b

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

>>49718
>>51786

> public function __construct($rank, $rate, $isBoss, $profession)


Если ты используешь PHP7 (я надеюсь, что да), то нужно расставить тайп хинты для аргументов, а также для возвращаемых значений функций, мануал http://php.net/manual/ru/functions.arguments.php

Для $isBoss лучше использовать значения true/false вместо 1/0.

> public function GetSalary()


>


> switch ($this->rank) {


Здесь для надежности надо добавить пункт default с выбросом исключения, если ранг не равен 1, 2 или 3.

> get_class($this)::COFFE*2


Это неправильно. Во-первых, ты бы мог просто написать static::COFFEE. Во-вторых, ты не должен в базовом классе обращаться к константам, которые добавят только в наследнике.

И тут есть еще одна проблема. А где вообще гарантия, что тот, кто пишет наследника, сделает эти константы? Это ведь никак не описано и никак не проверяется.

И еще одна проблема. А что, если кто-то создаст объект класса Employee? Он ведь не помечен как абстрактный, значит создавать его не запрещено. А констант в нем нет.

В ООП (да и не только в ООП) ты должен стараться так писать код, чтобы нельзя было его неправильно использовать. Если класс Employee используется только как основа для наследования, то надо пометить его абстрактным, чтобы никто даже не пытался создать объект такого класса.

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

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

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

Вместо констант тут нужно сделать так:

- пометить базовый класс как абстрактный
- определить в нем абстрактные методы вроде getBaseSalary(), которые должны будут реализовать наследники. Так мы укажем, какие методы обязан реализовать наследник, и PHP не позволит это не сделать. Про абстрактные методы мельком написано в уроке по ООП (где-то рядом с задачей Вектор).

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

> abstract class AbstractDepartment


> public $rank;


Это неправильно. Разве у Департамента есть свойство Ранг? Оно есть только у Работников.

> class BuyDepartment extends AbstractDepartment


Если департаменты отличаются только названием, то нет смысла для них делать отдельные классы. Они нужны, когда объекты одного типа различаются поведением (то есть в них есть одни и те же методы, но они разные).

Я бы советовал у Департамента сделать свойство списокРаботников и методы для приема на работу/увольнения работника.

Также, советовал бы сделать класс, представляющий всю Компанию.

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

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

Про инкапсуляцию:

----------

Инкапсуляция. У этого слова есть разные определения, в том числе такие что ничего не понять, потому объясню простыми словами.

Суть инкапсуляции в том, что класс скрывает (инкапслирует) в себе логику работы с данными и сами данные (помечает их private/protected), а наружу выставляет только методы. Пользователю этих методов не важно, как класс устроен внутри, как он хранит данные, ему достаточно вызвать нужный метод, чтобы получить результат.

Это упрощает понимание кода: тебе не надо читать и разбирать код класса, достаточно прочитать название метода (и может быть комментарий к нему). Также, это упрощает изменение кода: если какое-то свойство имеет уровень private, то доступ к нему возможен только из того же класса и тебе не надо бегать по всему коду и смотреть что там с этим свойством делается, тебе достаточно просмотреть один файл с этим классом.

При инкапсуляции автор класса строго ограничивает, что можно делать с объектом.

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

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

Если проводить аналогии, то можно представить кофе-машину. Ты нажимаешь кнопку (=вызываешь публичный метод) и получаешь кофе (=результат вызова этого метода), при этом ты не видишь что происходит внутри нее и тебе не надо в этом разбираться.
875 1152025
>>51841

> А как проверять, что у меня нужный мне объект?


Объекты можно сравнить с помощью ===: if ($a === $b) выполнится только если $a и $b ссылаются на один и тот же объект.

$a = new Guest('Иван Иванов');
$b = $a;
// В $a и $b один и тот же объект, $a === $b

$c = new Guest('Иван Иванов');
$d = new Guest('Иван Иванов');
// в $c и $d разные объекты, $a !== $b

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

>>49718
>>51786

> public function __construct($rank, $rate, $isBoss, $profession)


Если ты используешь PHP7 (я надеюсь, что да), то нужно расставить тайп хинты для аргументов, а также для возвращаемых значений функций, мануал http://php.net/manual/ru/functions.arguments.php

Для $isBoss лучше использовать значения true/false вместо 1/0.

> public function GetSalary()


>


> switch ($this->rank) {


Здесь для надежности надо добавить пункт default с выбросом исключения, если ранг не равен 1, 2 или 3.

> get_class($this)::COFFE*2


Это неправильно. Во-первых, ты бы мог просто написать static::COFFEE. Во-вторых, ты не должен в базовом классе обращаться к константам, которые добавят только в наследнике.

И тут есть еще одна проблема. А где вообще гарантия, что тот, кто пишет наследника, сделает эти константы? Это ведь никак не описано и никак не проверяется.

И еще одна проблема. А что, если кто-то создаст объект класса Employee? Он ведь не помечен как абстрактный, значит создавать его не запрещено. А констант в нем нет.

В ООП (да и не только в ООП) ты должен стараться так писать код, чтобы нельзя было его неправильно использовать. Если класс Employee используется только как основа для наследования, то надо пометить его абстрактным, чтобы никто даже не пытался создать объект такого класса.

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

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

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

Вместо констант тут нужно сделать так:

- пометить базовый класс как абстрактный
- определить в нем абстрактные методы вроде getBaseSalary(), которые должны будут реализовать наследники. Так мы укажем, какие методы обязан реализовать наследник, и PHP не позволит это не сделать. Про абстрактные методы мельком написано в уроке по ООП (где-то рядом с задачей Вектор).

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

> abstract class AbstractDepartment


> public $rank;


Это неправильно. Разве у Департамента есть свойство Ранг? Оно есть только у Работников.

> class BuyDepartment extends AbstractDepartment


Если департаменты отличаются только названием, то нет смысла для них делать отдельные классы. Они нужны, когда объекты одного типа различаются поведением (то есть в них есть одни и те же методы, но они разные).

Я бы советовал у Департамента сделать свойство списокРаботников и методы для приема на работу/увольнения работника.

Также, советовал бы сделать класс, представляющий всю Компанию.

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

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

Про инкапсуляцию:

----------

Инкапсуляция. У этого слова есть разные определения, в том числе такие что ничего не понять, потому объясню простыми словами.

Суть инкапсуляции в том, что класс скрывает (инкапслирует) в себе логику работы с данными и сами данные (помечает их private/protected), а наружу выставляет только методы. Пользователю этих методов не важно, как класс устроен внутри, как он хранит данные, ему достаточно вызвать нужный метод, чтобы получить результат.

Это упрощает понимание кода: тебе не надо читать и разбирать код класса, достаточно прочитать название метода (и может быть комментарий к нему). Также, это упрощает изменение кода: если какое-то свойство имеет уровень private, то доступ к нему возможен только из того же класса и тебе не надо бегать по всему коду и смотреть что там с этим свойством делается, тебе достаточно просмотреть один файл с этим классом.

При инкапсуляции автор класса строго ограничивает, что можно делать с объектом.

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

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

Если проводить аналогии, то можно представить кофе-машину. Ты нажимаешь кнопку (=вызываешь публичный метод) и получаешь кофе (=результат вызова этого метода), при этом ты не видишь что происходит внутри нее и тебе не надо в этом разбираться.
876 1152026
>>51769

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

> Вообще, единственное, что пришло мне в голову, это наоборот загружать на одну html страницу динамическую часть из БД с помощью аджакса, вроде и выглядит красиво,


Переусложнение.

>>49725

Не до конца отредактировал. Например:

> function spellSmallNumber($num, $female) {


> $result = array();



Должно быть

function spellSmallNumber($num, $female)
{
--->$result = array();

Без отступов тяжело читать код.

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

Искать форматтеры можно по "php beautify", хотя часть из них кривые. Вот этот работает, если повозиться с настройками: http://phpbeautifier.com/beautify.php

> $hundOne = $lastTwo % 10;


Название неудачное, лучше просто lastDigit или units.

> $units = floor($lastTwo / 10) * 10;


Десятки - это tens

> if ($female == 1 or $female == 2) {


Тут по задумке передается не последняя цифра (она уже есть в числе), а 1 если используется женский род (для тысяч) или 0 для мужского. Неазвисимо от того, какое число.

Так, алгоритм примерно правильный, но код читать невозможно. Надо отформатировать правильно. Во втором посте треда вроде написано, как форматировать код.
876 1152026
>>51769

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

> Вообще, единственное, что пришло мне в голову, это наоборот загружать на одну html страницу динамическую часть из БД с помощью аджакса, вроде и выглядит красиво,


Переусложнение.

>>49725

Не до конца отредактировал. Например:

> function spellSmallNumber($num, $female) {


> $result = array();



Должно быть

function spellSmallNumber($num, $female)
{
--->$result = array();

Без отступов тяжело читать код.

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

Искать форматтеры можно по "php beautify", хотя часть из них кривые. Вот этот работает, если повозиться с настройками: http://phpbeautifier.com/beautify.php

> $hundOne = $lastTwo % 10;


Название неудачное, лучше просто lastDigit или units.

> $units = floor($lastTwo / 10) * 10;


Десятки - это tens

> if ($female == 1 or $female == 2) {


Тут по задумке передается не последняя цифра (она уже есть в числе), а 1 если используется женский род (для тысяч) или 0 для мужского. Неазвисимо от того, какое число.

Так, алгоритм примерно правильный, но код читать невозможно. Надо отформатировать правильно. Во втором посте треда вроде написано, как форматировать код.
877 1152027
>>49596

Насчет хранения истории - сложный вопрос. Давай рассмотрим варианты:

1) хранить историю бронирований только в Room

Плюс: данные не дублируются, значит не может быть противоречий
Плюс: работает инкапсуляция, Room знает, когда она занята или свободна
Минус: если мы хотим получить историю по клиенту, мы должны обойти все комнаты. Также, а что делать при удалении комнаты? Куда денется история?
Минус: чтобы получить данные по отелю за сутки, надо обойти все комнаты.
Минус: гость не знает, где он был и когда

"обойти все комнаты" - само по себе не такая уж проблема. Проблема, что делать, когда мы захотим удалить комнату? Наверно, придется делать soft-delete - то есть помечать комнату закрытой, но не удалять ее.

2) дублировать историю в Room и Guest

Плюс: теперь у Гостя появилась "память".

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

Также, хранение истории в 2 местах не повлечет ли дублирование кода?

3) хранить историю в Hotel (или в HistoryLog, который хранится внутри Hotel)

Плюс: данные не дублируются
Плюс: удобно строить отчеты

Теперь у нас Room и Guest становятся классами почти без логики, а вся логика перемещается в Hotel. Немного меньше разделения обязанностей.

4) сделать класс HistoryLog, держать на него ссылку в Hotel и передавать (инжектировать) во все Room и Guest при создании

Плюс: централизованное хранение истории, при этом Room/Guest могут сами с ней работать
Минус: новые объекты Room/Guest теперь можно создавать только через Hotel, нельзя создать через new
Минус: а что, если Гость хочет остановиться в нескольких Гостиницах?

То есть попробуй выписывать разные варианты и искать их плюсы/минусы.
877 1152027
>>49596

Насчет хранения истории - сложный вопрос. Давай рассмотрим варианты:

1) хранить историю бронирований только в Room

Плюс: данные не дублируются, значит не может быть противоречий
Плюс: работает инкапсуляция, Room знает, когда она занята или свободна
Минус: если мы хотим получить историю по клиенту, мы должны обойти все комнаты. Также, а что делать при удалении комнаты? Куда денется история?
Минус: чтобы получить данные по отелю за сутки, надо обойти все комнаты.
Минус: гость не знает, где он был и когда

"обойти все комнаты" - само по себе не такая уж проблема. Проблема, что делать, когда мы захотим удалить комнату? Наверно, придется делать soft-delete - то есть помечать комнату закрытой, но не удалять ее.

2) дублировать историю в Room и Guest

Плюс: теперь у Гостя появилась "память".

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

Также, хранение истории в 2 местах не повлечет ли дублирование кода?

3) хранить историю в Hotel (или в HistoryLog, который хранится внутри Hotel)

Плюс: данные не дублируются
Плюс: удобно строить отчеты

Теперь у нас Room и Guest становятся классами почти без логики, а вся логика перемещается в Hotel. Немного меньше разделения обязанностей.

4) сделать класс HistoryLog, держать на него ссылку в Hotel и передавать (инжектировать) во все Room и Guest при создании

Плюс: централизованное хранение истории, при этом Room/Guest могут сами с ней работать
Минус: новые объекты Room/Guest теперь можно создавать только через Hotel, нельзя создать через new
Минус: а что, если Гость хочет остановиться в нескольких Гостиницах?

То есть попробуй выписывать разные варианты и искать их плюсы/минусы.
878 1152028
>>52019

Не лучше ли тут реализовать это не через store? То есть у нас есть условно говоря, клиент API. Мы в нем можем предусмотреть состояние залогиненности/незалогиненности. И пусть он об этом сообщает, что нужен логин:

var client = new ApiClient;

client.onAuthRequested(function () {
var popup = showAuthWindow();
popup.onSubmit(function (user, pass) {
// перезапускает провалившиеся запросы
client.updateCredentials(user, pass);
});
});

// делаем запрос через API
var promise = client.getSomeData();

То есть вынести это в отдельную сущность, не использовать для очереди запросов store. Зачем все в store тащить-то? Получится же God Object.

Кстати, сам ApiClient тоже можно разделить на 2 класса - класс, который умеет делать запросы и класс, который умеет повторять их при различных ошибках.

> Но есть зависимость "export function setStore(s)", причем она используется только для запуска метода store.dispatch(loginRequired(request)), можно передать только сам метод dispatch() а не store целиком.



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

А в случае с классами мы могли бы сделать класс и передавать store в конструктор. Еще можно не делать класс, а просто добавить store в аргументы функции, которым он нужен.

> Но если все приложение использует react+redux, то немного странно делать модальное окно не на основе компонента react?


Не знаю, а почему нет? В моем понимании:

store - это что-то вроде модели, хранящей состояние. Это не совсем модель из MVC с данными приложения, так как она хранит еще и состояние интерфейса (то, что иногда называют ViewModel).

окно - это view, отображающее данные из модели. Никто не запрещает сделать каждое окно отдельным view, и создавать/удалять их не через react. Я, кстати, даже не вижу проблем с тем, чтобы делать для некоторых окон свой store - а почему нет? Разделение ответственности.

А так, подход react/redux - получается, мы делаем одно мегавью, в котором внутри есть все попапы. И при любом изменении модели мы перерендерим все это мегавью и все попапы в нем.

У меня просто ощущение, что реакт задумывался, условно, для каких-то интерактивных мест на странице, например, сложных форм, каких-то редакторов. А не для того, чтобы целиком все на нем делать.
878 1152028
>>52019

Не лучше ли тут реализовать это не через store? То есть у нас есть условно говоря, клиент API. Мы в нем можем предусмотреть состояние залогиненности/незалогиненности. И пусть он об этом сообщает, что нужен логин:

var client = new ApiClient;

client.onAuthRequested(function () {
var popup = showAuthWindow();
popup.onSubmit(function (user, pass) {
// перезапускает провалившиеся запросы
client.updateCredentials(user, pass);
});
});

// делаем запрос через API
var promise = client.getSomeData();

То есть вынести это в отдельную сущность, не использовать для очереди запросов store. Зачем все в store тащить-то? Получится же God Object.

Кстати, сам ApiClient тоже можно разделить на 2 класса - класс, который умеет делать запросы и класс, который умеет повторять их при различных ошибках.

> Но есть зависимость "export function setStore(s)", причем она используется только для запуска метода store.dispatch(loginRequired(request)), можно передать только сам метод dispatch() а не store целиком.



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

А в случае с классами мы могли бы сделать класс и передавать store в конструктор. Еще можно не делать класс, а просто добавить store в аргументы функции, которым он нужен.

> Но если все приложение использует react+redux, то немного странно делать модальное окно не на основе компонента react?


Не знаю, а почему нет? В моем понимании:

store - это что-то вроде модели, хранящей состояние. Это не совсем модель из MVC с данными приложения, так как она хранит еще и состояние интерфейса (то, что иногда называют ViewModel).

окно - это view, отображающее данные из модели. Никто не запрещает сделать каждое окно отдельным view, и создавать/удалять их не через react. Я, кстати, даже не вижу проблем с тем, чтобы делать для некоторых окон свой store - а почему нет? Разделение ответственности.

А так, подход react/redux - получается, мы делаем одно мегавью, в котором внутри есть все попапы. И при любом изменении модели мы перерендерим все это мегавью и все попапы в нем.

У меня просто ощущение, что реакт задумывался, условно, для каких-то интерактивных мест на странице, например, сложных форм, каких-то редакторов. А не для того, чтобы целиком все на нем делать.
879 1152037
Поставил убунту на виртуалку. Подскажите с чего начать, что бы уметь на ней:
1. поднять сервер.
2. поднять доман на локалхосте.
3. всё это запустить и протестить.
4. Подключиться к гитхабу - залить туда репозиторий.
880 1152171
>>52037
>>52037

>1. поднять сервер.


>2. поднять доман на локалхосте.


>3. всё это запустить и протестить.


почитать интернеты, например https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-16-04

>4. Подключиться к гитхабу - залить туда репозиторий.


создать репозиторий на гитхабе, скопировать код "git add remote ..." из его интерфейса, потом на локальном хосте написать git init, git add ., git push origin master
881 1152195
Сап тред. Я слепил велосипед и он ужасен. Вторая задача по массивам. Я накидал говнокода и оно работает, но получился действительно говнокод. Вот: https://ideone.com/r5b38C
Дайте подсказку как это сделать правильно, а то я сидел, думал, но высрал только это.
882 1152214
>>52195
Используй циклы вместо 9 условий. Тебе нужно всего лишь рост каждого одноклассника сравнить с ростом Антона.
Твоя реализация такая, чисто человеческая. Представь, что у тебя не было бы заданного массива, а файл с произвольными данными об одноклассниках какого-то анона. Тут уже этот велосипед не сработает.
883 1152215
>>52028

>Не лучше ли тут реализовать это не через store? То есть у нас есть условно говоря, клиент API. Мы в нем можем предусмотреть состояние залогиненности/незалогиненности. И пусть он об этом сообщает, что нужен логин:


>


>var client = new ApiClient;


>



Тогда нужно будет соединить его с основным приложением (я предполагаю случай, когда реакт+редакс app - основное приложение, компонент базовый элемент интерфейса наследующий React класс Component):
1. Можно импортировать его как модуль в каждом компоненте, где необходимо что-то отправлять или получать от api, при этом данные полученные от ApiClient отправляются компонентом в store с помощью dispatch(somAction(data)); Компонент знает о ApiClient и его методах.
2. Сделать middleware класс, который слушает основной поток событий от компонентов, и реагирует на определенные события, запуская ApiClient.someFuction(); Middleware класс знает о ApiClient и о App (store.dispatch() и определенных Action).
3. Можно сделать компонент ApiClient, который имеет локальный state, в котором хранит свои специфические данные, например очередь запросов, и подписан на определенные изменения store, которые являются условием инициации отправки запросов, также умеет в dispatch() как и обычные компоненты. Именно так реализована библиотека Redux-Json-Api, которая позволяет отправлять и получать запросы в формате jsonapi, выковыривать из них данные и нормализовав сохранять в store
https://github.com/redux-json-api/redux-json-api

Т.е. возможность иметь отдельный ApiClient, который не знает о store это вариант 1 и 2. Я пока не могу в полной мере оценить плюсы и минусы каждого подхода хотя и пробовал оба варианта.

>>52028

>Более того, тут еще и жестко задана невозможность использовать более одного store. Они модули используют как синглтон.


Тут такая религия, store един.
с оф сайта редакс:
Redux can be described in three fundamental principles:
1.Single source of truth
The state of your whole application is stored in an object tree within a single store.

Некоторые последователи предлагают таки хранить часть данных в локальном state компонента, например информация о поле формы, валидна инфа в поле или нет.

>>52028

>> Но если все приложение использует react+redux, то немного странно делать модальное окно не на основе компонента react?


>Не знаю, а почему нет?


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

>В моем понимании:


>store - это что-то вроде модели, хранящей состояние. Это не совсем модель из MVC с данными приложения, так как она хранит еще и состояние интерфейса (то, что иногда называют ViewModel).


>


>окно - это view, отображающее данные из модели. Никто не запрещает сделать каждое окно отдельным view, и создавать/удалять их не через react. Я, кстати, даже не вижу проблем с тем, чтобы делать для некоторых окон свой store - а почему нет? Разделение ответственности.



Вообще у компонентов есть способ хранить состояние - local state. Мы можем там хранить данные относящиеся к UI.

React предлагает компоненты, классы которые позволяют делать не связанные между собой элементы интерфейса, которые могут хранить свое состояние и отрисовывать html элементы описанные с помощью JSX. Иметь свои обработчики событий в качестве методов. Бонусом, компоненты умеют в композицию, т.е. компонент форма может быть собрана из компонента поле-ввода и компонента кнопки. В дочерние элементы данные передаются по цепочке через props, который передается в конструктор компонентов.

Rudux нужен для того, чтобы создать единое хранилище состояния всего приложения. Store - это хранилище. Изменение в нем происходит единственным способом: с помощью reducer, это функции, которые принимают в качестве аргументов объекты action и предыдущую версию store. Action это объекты контейнеры, имеющие определенные типы и содержащие данные. Все участники вечеринки могут получить доступ к функции store.dispatch(someAction), после запуска которого someAction попадет в цепочку редьюсеров для обработки. А компоненты могут "подписаться" на изменение определенных данных в store и получать их каждый раз, когда они изменятся. Т.е. данные поступают в store только с помощью store.dispatch(someAction), а из store в компоненты через props, каждый раз, когда изменяется store.

>А так, подход react/redux - получается, мы делаем одно мегавью, в котором внутри есть все попапы. И при любом изменении модели мы перерендерим все это мегавью и все попапы в нем.


DOM не обязательно перерисовывается при изменении store, т.к. данные могут не затрагивать сам интерфейс, а только их внутреннее хранилище local state или же просто не один из компонентов не подписан на изменение этих данных.
883 1152215
>>52028

>Не лучше ли тут реализовать это не через store? То есть у нас есть условно говоря, клиент API. Мы в нем можем предусмотреть состояние залогиненности/незалогиненности. И пусть он об этом сообщает, что нужен логин:


>


>var client = new ApiClient;


>



Тогда нужно будет соединить его с основным приложением (я предполагаю случай, когда реакт+редакс app - основное приложение, компонент базовый элемент интерфейса наследующий React класс Component):
1. Можно импортировать его как модуль в каждом компоненте, где необходимо что-то отправлять или получать от api, при этом данные полученные от ApiClient отправляются компонентом в store с помощью dispatch(somAction(data)); Компонент знает о ApiClient и его методах.
2. Сделать middleware класс, который слушает основной поток событий от компонентов, и реагирует на определенные события, запуская ApiClient.someFuction(); Middleware класс знает о ApiClient и о App (store.dispatch() и определенных Action).
3. Можно сделать компонент ApiClient, который имеет локальный state, в котором хранит свои специфические данные, например очередь запросов, и подписан на определенные изменения store, которые являются условием инициации отправки запросов, также умеет в dispatch() как и обычные компоненты. Именно так реализована библиотека Redux-Json-Api, которая позволяет отправлять и получать запросы в формате jsonapi, выковыривать из них данные и нормализовав сохранять в store
https://github.com/redux-json-api/redux-json-api

Т.е. возможность иметь отдельный ApiClient, который не знает о store это вариант 1 и 2. Я пока не могу в полной мере оценить плюсы и минусы каждого подхода хотя и пробовал оба варианта.

>>52028

>Более того, тут еще и жестко задана невозможность использовать более одного store. Они модули используют как синглтон.


Тут такая религия, store един.
с оф сайта редакс:
Redux can be described in three fundamental principles:
1.Single source of truth
The state of your whole application is stored in an object tree within a single store.

Некоторые последователи предлагают таки хранить часть данных в локальном state компонента, например информация о поле формы, валидна инфа в поле или нет.

>>52028

>> Но если все приложение использует react+redux, то немного странно делать модальное окно не на основе компонента react?


>Не знаю, а почему нет?


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

>В моем понимании:


>store - это что-то вроде модели, хранящей состояние. Это не совсем модель из MVC с данными приложения, так как она хранит еще и состояние интерфейса (то, что иногда называют ViewModel).


>


>окно - это view, отображающее данные из модели. Никто не запрещает сделать каждое окно отдельным view, и создавать/удалять их не через react. Я, кстати, даже не вижу проблем с тем, чтобы делать для некоторых окон свой store - а почему нет? Разделение ответственности.



Вообще у компонентов есть способ хранить состояние - local state. Мы можем там хранить данные относящиеся к UI.

React предлагает компоненты, классы которые позволяют делать не связанные между собой элементы интерфейса, которые могут хранить свое состояние и отрисовывать html элементы описанные с помощью JSX. Иметь свои обработчики событий в качестве методов. Бонусом, компоненты умеют в композицию, т.е. компонент форма может быть собрана из компонента поле-ввода и компонента кнопки. В дочерние элементы данные передаются по цепочке через props, который передается в конструктор компонентов.

Rudux нужен для того, чтобы создать единое хранилище состояния всего приложения. Store - это хранилище. Изменение в нем происходит единственным способом: с помощью reducer, это функции, которые принимают в качестве аргументов объекты action и предыдущую версию store. Action это объекты контейнеры, имеющие определенные типы и содержащие данные. Все участники вечеринки могут получить доступ к функции store.dispatch(someAction), после запуска которого someAction попадет в цепочку редьюсеров для обработки. А компоненты могут "подписаться" на изменение определенных данных в store и получать их каждый раз, когда они изменятся. Т.е. данные поступают в store только с помощью store.dispatch(someAction), а из store в компоненты через props, каждый раз, когда изменяется store.

>А так, подход react/redux - получается, мы делаем одно мегавью, в котором внутри есть все попапы. И при любом изменении модели мы перерендерим все это мегавью и все попапы в нем.


DOM не обязательно перерисовывается при изменении store, т.к. данные могут не затрагивать сам интерфейс, а только их внутреннее хранилище local state или же просто не один из компонентов не подписан на изменение этих данных.
884 1152223
>>52214
Вот так? https://ideone.com/TIKGLG
Вроде бы получилось. Спасибо! Но возможно это снова говнокод
885 1152227
>>52223
Нормально. Двигайся дальше.
886 1152239
>>52227
Хорошо, спасибо за помощь
https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist3/ 887 1152248
>>51740
>>37298

Надо бы добавить ридми. Прочитай комментарии к задаче, там это написано: https://github.com/codedokode/pasta/blob/master/student-list.md#Публикация-проекта - там же есть ссылка на пример README.

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

Желательно убрать код, который не используется. Вот зачем нужен этот файл например? https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist3/blob/master/tests/Feature/ExampleTest.php

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

Также, у тебя там прописана сборка JS-файлов, подключение Vue. Но он нигде не используется. Зачем тогда это добавлять? Из-за этого труднее найти, где именно твой код, а где стандартные заготовки.

Дальше, мне не нравится, что в composer.json прописан "name": "laravel/laravel". Как будто бы это не твое приложение, а официальный репозиторий фреймворка Laravel. По моему, это вводит в заблуждение. Поле name предназначено в первую очередь для добавляемых в репозиторий packagist библиотек, а в твоем случае оно вообще не нужно.

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

https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist3/blob/master/app/Http/Controllers/Table/TableController.php#L22

Разве это правильно, что в одном случае передается переменная в шаблон, а в другом - нет?

> return view('table', ['orderBy' => $request['orderBy'], 'users' => $users, 'search' => $searchWord]);


> return view('table', ['users' => $users, 'orderBy' => $request['orderBy']]);



Также, не стоило копировать 2 раза эти строки

> $orderBy = $this->validateOrderByParam($request['orderBy']);


> $users = $this->getUsers($request, $orderBy);



https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist3/blob/master/app/Http/Controllers/Table/TableController.php#L47

Получение данных по идее должно быть в модели, а не в контроллере. Ты тут пишешь типичный "толстый контроллер".

Ты используешь в форме регистрации PUT, но ведь браузеры не поддерживают этот метод и там будет использована POST-форма с скрытым полем, а на стороне Ларавел будет сымитировано поступление PUT-запроса. Не переусложнение ли?

https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist3/blob/master/app/Http/Controllers/Profile/ProfileController.php#L22

По условиям задачи требовалось разрешить пробелы, дефисы и апострофы в именах.

> 'birth_year' => ['required', 'string', 'regex:@^199[0-9]|200[0-5]$@iu'],


Люди старше 28 лет - не допускаются?

Далее, я попробовал запустить у себя проект с помощью встроенного в PHP веб-сервера - он показывает страницу "Whoops, looks like something went wrong" (2 раза), но подробности ошибки нигде не выводятся - ни на странице, ни в консоли (выяснилось, что надо создать .env, но я не понимаю, почему по умолчанию подробности ошибки не пишутся в консоль - как это отлаживать?).

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

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

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

Если при поиске ничего не найдено, то надо бы выводить соответствующую надпись, а не шапку от пустой таблицы.

> protected function validator(array $data)


Имена функций обычно начинаются с глагола, сделайЧтоТо()

> `birth_year` int(11) NOT NULL


В таблице можно было бы использовать тип YEAR.

Насчет этой таблицы https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist3/blob/master/database/migrations/2014_10_12_100000_create_password_resets_table.php - разве токен сброса пароля не должен привязываться к пользователю?

Насчет форм - я вижу, ты используешь бутстрап. Так почему бы не использовать стандартные стили бустрапа для форм? http://getbootstrap.com/docs/3.3/css/#forms

Так, конечно, при использовании Ларавел тут получается очень мало твоего кода (так-то это хорошо, но у нас ведь задача научиться). На мощном фреймворке лучше было бы делать задачу вроде TestHub, где все сложнее. Ну или попробовать сделать безпарольную авторизацию, как описано в задаче.
https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist3/ 887 1152248
>>51740
>>37298

Надо бы добавить ридми. Прочитай комментарии к задаче, там это написано: https://github.com/codedokode/pasta/blob/master/student-list.md#Публикация-проекта - там же есть ссылка на пример README.

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

Желательно убрать код, который не используется. Вот зачем нужен этот файл например? https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist3/blob/master/tests/Feature/ExampleTest.php

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

Также, у тебя там прописана сборка JS-файлов, подключение Vue. Но он нигде не используется. Зачем тогда это добавлять? Из-за этого труднее найти, где именно твой код, а где стандартные заготовки.

Дальше, мне не нравится, что в composer.json прописан "name": "laravel/laravel". Как будто бы это не твое приложение, а официальный репозиторий фреймворка Laravel. По моему, это вводит в заблуждение. Поле name предназначено в первую очередь для добавляемых в репозиторий packagist библиотек, а в твоем случае оно вообще не нужно.

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

https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist3/blob/master/app/Http/Controllers/Table/TableController.php#L22

Разве это правильно, что в одном случае передается переменная в шаблон, а в другом - нет?

> return view('table', ['orderBy' => $request['orderBy'], 'users' => $users, 'search' => $searchWord]);


> return view('table', ['users' => $users, 'orderBy' => $request['orderBy']]);



Также, не стоило копировать 2 раза эти строки

> $orderBy = $this->validateOrderByParam($request['orderBy']);


> $users = $this->getUsers($request, $orderBy);



https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist3/blob/master/app/Http/Controllers/Table/TableController.php#L47

Получение данных по идее должно быть в модели, а не в контроллере. Ты тут пишешь типичный "толстый контроллер".

Ты используешь в форме регистрации PUT, но ведь браузеры не поддерживают этот метод и там будет использована POST-форма с скрытым полем, а на стороне Ларавел будет сымитировано поступление PUT-запроса. Не переусложнение ли?

https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist3/blob/master/app/Http/Controllers/Profile/ProfileController.php#L22

По условиям задачи требовалось разрешить пробелы, дефисы и апострофы в именах.

> 'birth_year' => ['required', 'string', 'regex:@^199[0-9]|200[0-5]$@iu'],


Люди старше 28 лет - не допускаются?

Далее, я попробовал запустить у себя проект с помощью встроенного в PHP веб-сервера - он показывает страницу "Whoops, looks like something went wrong" (2 раза), но подробности ошибки нигде не выводятся - ни на странице, ни в консоли (выяснилось, что надо создать .env, но я не понимаю, почему по умолчанию подробности ошибки не пишутся в консоль - как это отлаживать?).

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

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

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

Если при поиске ничего не найдено, то надо бы выводить соответствующую надпись, а не шапку от пустой таблицы.

> protected function validator(array $data)


Имена функций обычно начинаются с глагола, сделайЧтоТо()

> `birth_year` int(11) NOT NULL


В таблице можно было бы использовать тип YEAR.

Насчет этой таблицы https://github.com/dsgaljkeguhodgiosetuhsegjposguh/studlist3/blob/master/database/migrations/2014_10_12_100000_create_password_resets_table.php - разве токен сброса пароля не должен привязываться к пользователю?

Насчет форм - я вижу, ты используешь бутстрап. Так почему бы не использовать стандартные стили бустрапа для форм? http://getbootstrap.com/docs/3.3/css/#forms

Так, конечно, при использовании Ларавел тут получается очень мало твоего кода (так-то это хорошо, но у нас ведь задача научиться). На мощном фреймворке лучше было бы делать задачу вроде TestHub, где все сложнее. Ну или попробовать сделать безпарольную авторизацию, как описано в задаче.
888 1152249
>>52037

Тебе надо освоить:

- основы командной строки, можно начать отсюда https://github.com/codedokode/pasta/blob/master/soft/cli.md
- основы линукса (почитать любой учебник для начинающих, про файловую систему, про права, про пользователей, про основные команды вроде ls или rm)
- используемый в твоем дистрибутиве пакетный менеджер (apt-get)

Тебе надо настроить виртуалку так, чтобы к программам в ней можно было подсоединяться с основной системы. Для этого придется добавить второй сетевой интерфейс. Тут это описано: https://gist.github.com/codedokode/420c8c12a1edae25f0ec (то, что про Дебиан - можешь не читать, хотя Убунта и сделана на его основе).

Чтобы "поднять домен на локалхосте", тебе достаточно в файл hosts на основной системе приписать любое доменное имя и IP-адрес виртуалки.

Чтобы "поднять сервер" в виртуалке, надо установить и настроить (отредактировать конфиги) там нужные программы (Апач + PHP либо можно исопльзовать встроенный в PHP сервер, как описано тут https://github.com/codedokode/pasta/blob/master/soft/web-server.md ).

У меня есть инфа про установку Апача, но она ориентирована на винду и не все там будет актуально: https://github.com/codedokode/pasta/blob/master/soft/apache-install.md

Итак, нужно:

- настроить второй интерфейс на виртуалке
- прописать домнен в hosts
- установить, настроить и запустить в виртуалке веб-сервер (Apache, nginx или встроенный в PHP)

После этого из браузера можно будет зайти на сайт.

Чтобы залить существующий репозиторий на гитхаб, надо сделать слудующие шаги:

- создать на гитхабе пустой репозиторий без всего
- локально добавить новый remote (git remote add origin ..), указав URL, который тебе выдаст гитхаб на первом шаге
- сделать git push origin HEAD

Подробне про работу с гитом есть учебник на русском https://git-scm.com/book/ru/v2 и глава в нем https://git-scm.com/book/ru/v2/Основы-Git-Работа-с-удалёнными-репозиториями
888 1152249
>>52037

Тебе надо освоить:

- основы командной строки, можно начать отсюда https://github.com/codedokode/pasta/blob/master/soft/cli.md
- основы линукса (почитать любой учебник для начинающих, про файловую систему, про права, про пользователей, про основные команды вроде ls или rm)
- используемый в твоем дистрибутиве пакетный менеджер (apt-get)

Тебе надо настроить виртуалку так, чтобы к программам в ней можно было подсоединяться с основной системы. Для этого придется добавить второй сетевой интерфейс. Тут это описано: https://gist.github.com/codedokode/420c8c12a1edae25f0ec (то, что про Дебиан - можешь не читать, хотя Убунта и сделана на его основе).

Чтобы "поднять домен на локалхосте", тебе достаточно в файл hosts на основной системе приписать любое доменное имя и IP-адрес виртуалки.

Чтобы "поднять сервер" в виртуалке, надо установить и настроить (отредактировать конфиги) там нужные программы (Апач + PHP либо можно исопльзовать встроенный в PHP сервер, как описано тут https://github.com/codedokode/pasta/blob/master/soft/web-server.md ).

У меня есть инфа про установку Апача, но она ориентирована на винду и не все там будет актуально: https://github.com/codedokode/pasta/blob/master/soft/apache-install.md

Итак, нужно:

- настроить второй интерфейс на виртуалке
- прописать домнен в hosts
- установить, настроить и запустить в виртуалке веб-сервер (Apache, nginx или встроенный в PHP)

После этого из браузера можно будет зайти на сайт.

Чтобы залить существующий репозиторий на гитхаб, надо сделать слудующие шаги:

- создать на гитхабе пустой репозиторий без всего
- локально добавить новый remote (git remote add origin ..), указав URL, который тебе выдаст гитхаб на первом шаге
- сделать git push origin HEAD

Подробне про работу с гитом есть учебник на русском https://git-scm.com/book/ru/v2 и глава в нем https://git-scm.com/book/ru/v2/Основы-Git-Работа-с-удалёнными-репозиториями
889 1152251
>>52195

Да, твое решение неудачное, так как надо на каждого ученика писать блок в if. Нужно использовать цикл по массиву таким образом:

- завести переменную и сохранить в нее 0
- взять по очереди каждого ученика, поместить его имя в $name, а рост в $height (это делает команда foreach)
- если рост текущего ученика больше роста школьника, то увеличить переменную на 1
- когда цикл закончится, в переменной будет ответ

>>52215

Вообще, мне не очень нравится идея использовать реакт для основы приложения. Как я понимаю, там придется хранить все данные приложения в сторе в виде одного гигантского объекта, при любом изменении создавать копию этого объекта (так как иммутабельность), перерендеривать все вью и это будет наверно не очень быстро работать. Хотя, тут надо тестировать. Сделал бы кто-нибудь задачу про SPA на реакте...

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

> Тогда нужно будет соединить его с основным приложением


По идее обращения к API должны идти в action creator. Как тут описано например: https://github.com/reactjs/redux/issues/291#issuecomment-122829159

> Можно импортировать его как модуль в каждом компоненте, где необходимо что-то отправлять или получать от api, при этом данные полученные от ApiClient отправляются компонентом в store с помощью dispatch(somAction(data));


А с какой стати компоненты должны работать с АПИ? Компоненты же просто отображают переданные им сверху (взятые из стора и пропущенные через редюсер) данные?

> Можно сделать компонент ApiClient, который имеет локальный state,


Зачем работу с АПИ делать компонентом Реакта? Реакт это просто View, библиотека для отображения данных.

> Тут такая религия, store един.


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

> С помощью react мы можем сделать модальное окно, используя кнопки и поля ввода, для которых мы уже создали компоненты. Если даже это и не удобно, то во всяком случае соблюдается единый стиль описания html элементов.



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

> DOM не обязательно перерисовывается при изменении store,


Я не про DOM. А про компоненты реакта, которые имеют метод render() и генерируют объекты виртуального DOM. Представь что у тебя чат, слева список из 100 контактов (каждый как компонент), справа - 100 сообщений. Плюс еще скрытые компоненты разных попапов. То есть куча компонентов реакта. При выполнении любого действия со стором все это дерево компонентов обходится, вызывается метод render, генерируется огромный виртуальный DOM, сравнивается с предыдущей версией? Или нет?

Сделал бы кто-нибудь что-нибудь сложное на реакте с кучей форм и таблиц, можно было бы потестить.

Как я понимаю из https://reactjs.org/docs/optimizing-performance.html#avoid-reconciliation оптимизацию надо включать вручную - либо наследуюясь от PureComponent, либо вручную определяя, изменится ли представление компонента.

> Even though React only updates the changed DOM nodes, re-rendering still takes some time. In many cases it’s not a problem, but if the slowdown is noticeable, you can speed all of this up by overriding the lifecycle function shouldComponentUpdate,...



> In most cases, instead of writing shouldComponentUpdate() by hand, you can inherit from React.PureComponent. It is equivalent to implementing shouldComponentUpdate() with a shallow comparison of current and previous props and state.



Я бы еще обратил внимание на "shallow comparison" - это доабвляет свои подвохи, которые там описаны ниже: https://reactjs.org/docs/optimizing-performance.html#the-power-of-not-mutating-data
889 1152251
>>52195

Да, твое решение неудачное, так как надо на каждого ученика писать блок в if. Нужно использовать цикл по массиву таким образом:

- завести переменную и сохранить в нее 0
- взять по очереди каждого ученика, поместить его имя в $name, а рост в $height (это делает команда foreach)
- если рост текущего ученика больше роста школьника, то увеличить переменную на 1
- когда цикл закончится, в переменной будет ответ

>>52215

Вообще, мне не очень нравится идея использовать реакт для основы приложения. Как я понимаю, там придется хранить все данные приложения в сторе в виде одного гигантского объекта, при любом изменении создавать копию этого объекта (так как иммутабельность), перерендеривать все вью и это будет наверно не очень быстро работать. Хотя, тут надо тестировать. Сделал бы кто-нибудь задачу про SPA на реакте...

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

> Тогда нужно будет соединить его с основным приложением


По идее обращения к API должны идти в action creator. Как тут описано например: https://github.com/reactjs/redux/issues/291#issuecomment-122829159

> Можно импортировать его как модуль в каждом компоненте, где необходимо что-то отправлять или получать от api, при этом данные полученные от ApiClient отправляются компонентом в store с помощью dispatch(somAction(data));


А с какой стати компоненты должны работать с АПИ? Компоненты же просто отображают переданные им сверху (взятые из стора и пропущенные через редюсер) данные?

> Можно сделать компонент ApiClient, который имеет локальный state,


Зачем работу с АПИ делать компонентом Реакта? Реакт это просто View, библиотека для отображения данных.

> Тут такая религия, store един.


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

> С помощью react мы можем сделать модальное окно, используя кнопки и поля ввода, для которых мы уже создали компоненты. Если даже это и не удобно, то во всяком случае соблюдается единый стиль описания html элементов.



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

> DOM не обязательно перерисовывается при изменении store,


Я не про DOM. А про компоненты реакта, которые имеют метод render() и генерируют объекты виртуального DOM. Представь что у тебя чат, слева список из 100 контактов (каждый как компонент), справа - 100 сообщений. Плюс еще скрытые компоненты разных попапов. То есть куча компонентов реакта. При выполнении любого действия со стором все это дерево компонентов обходится, вызывается метод render, генерируется огромный виртуальный DOM, сравнивается с предыдущей версией? Или нет?

Сделал бы кто-нибудь что-нибудь сложное на реакте с кучей форм и таблиц, можно было бы потестить.

Как я понимаю из https://reactjs.org/docs/optimizing-performance.html#avoid-reconciliation оптимизацию надо включать вручную - либо наследуюясь от PureComponent, либо вручную определяя, изменится ли представление компонента.

> Even though React only updates the changed DOM nodes, re-rendering still takes some time. In many cases it’s not a problem, but if the slowdown is noticeable, you can speed all of this up by overriding the lifecycle function shouldComponentUpdate,...



> In most cases, instead of writing shouldComponentUpdate() by hand, you can inherit from React.PureComponent. It is equivalent to implementing shouldComponentUpdate() with a shallow comparison of current and previous props and state.



Я бы еще обратил внимание на "shallow comparison" - это доабвляет свои подвохи, которые там описаны ниже: https://reactjs.org/docs/optimizing-performance.html#the-power-of-not-mutating-data
890 1152279
Переходите пожалуйста в новый тред: >>1152267 (OP)

Этот тред закрыт.

Если я кому-то не ответил, напомните о себе в новом треде.
891 1152411
Пачаны, такая ошибка, делаю регистрацию на сайте, но почему то проверка if (!$result) не срабоатывает, все время получается: MessageSend (1, 'Пользователь с таким E-mail адресом уже существует!');

$result = $pdo->query("SELECT mail FROM users WHERE mail='$mail'");
if (!$result){
$reg = $pdo->query("INSERT INTO users VALUES('$name','$mail','$password','0')");
}else {
MessageSend (1, 'Пользователь с таким E-mail адресом уже существует!');
}

Что не так делаю?
892 1152462
>>52411

В новый тред пожалуйста >>1152267 (OP)
893 1155858
>>51716
у меня почему-то всё работало
Тред утонул или удален.
Это копия, сохраненная 25 марта 2018 года.

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

Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
« /pr/В начало тредаВеб-версияНастройки
/a//b//mu//s//vg/Все доски