Этого треда уже нет.
Это копия, сохраненная 5 августа 2019 года.

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

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

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

Это тред и для начинающих. Слово "классы" у тебя ассоциируется только со школой, а в аттестате тройка по математике? Ты наш человек.

Предыдущий тред был тут: >>1380485 (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/
- какой-то древний, устаревший, но большой и на русском справочник по веб-разработке, посоветованный аноном: https://starcat.dp.ua/doc/wdh/

Оформляй код аккуратно!!! — например пропусти через 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.png56 Кб, 500x644
Как оформлять код 2 1415605
Код нужно писать не как попало, а аккуратно и по правилам. Почему? Потому, что на неакуратно написанный код не хочется даже смотреть. Если каждый будет оформлять код как хочет, будет бардак.

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

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

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

- переменные и функции пишутся с маленькой буквы, подчеркивание не используется, используется camelCase, пример: $x, $numberOfPeople, printResults()
- Название функции начинается с глагола, в стиле «сделайЧтоТо»
- не знаешь английский? Не беда, в 21 веке есть решение этой проблемы. Не пиши транслитом, открой лучше Гугл Транслейт и найди название для переменной там
- в именах классов используется 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 1415606
Вроде я проверил практически все посты в прошлом треде, и ответил на все вопросы, так что если вы что-то спрашивали, зайдите в старый тред >>1380485 (OP) и проверьте. А если я пропустил, напомните о себе тут.

Заодно я бы хотел разобрать одну интересную задачу из прошлого треда. Есть такая известная задача на ООП про скидки, кто мои задачи про ООП решал, думаю, без проблем справится. Вот тут вот задача: >>1395825 а тут решение анона: https://github.com/nokitakaze/test-programming-task-am-items/

Думаю, прошло много времени, так что прокомментирую решение:

> Правило №4 "стоимость выбранного продукта уменьшается на 5%". Что такое "выбранный продукт"? Покупатель произвольно пальцем тыкнул в любой продукт, и у него цена уменьшилась?



Это товар A из правила.

> Если одновременно выбраны А


Вот он и "выбранный".

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

https://github.com/nokitakaze/test-programming-task-am-items/blob/master/src/Item.php

Тут странный отступ в 4 пробела. Он не нужен.

> protected $_type;


Не надо использовать подчеркивание в именах свойств. Это было в PHP4.

> @var ItemType[]|ItemType[][]|null


> protected $_only_includes = null;



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

И вообще, тут ты имхо переусложнил код. Ты пытался сделать так, чтобы у правил было как можно больше общего кода, чтобы достаточно было передать для разных правил разные массивы, но это лишь привело к переусложнению логики. То есть, думаю, что из базового класса Rule можно вообще убрать эти поля exclude/inlcude.

Тебе не надо было в базовом классе делать поля exclude/include. Они не применимы ко всем видам скидок, и значит, им незачем быть в базовом классе. Также, не стоит полагаться на идею "класс-наследник должен переопределить этот массив", так как она никак не задокументирована и не проверяется. Если ты хочешь что-то требовать от класса-наследника, то используй абстрактные методы.

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

Также, посмотри на объем кода в https://github.com/nokitakaze/test-programming-task-am-items/blob/master/src/Rules/TotalCostSelectedItemsRule.php и сравни с тем, как это правило описано в одном предложении в задаче. Этот код стоит хотя бы разбить на методы с понятными названиями, сейчас он вообще не читаем.

Ну например, один из вариантов - это сделать так:

// Сортируем товары по типу
foreach ($types as $type) {
$itemsByType[$typeName] = $this->pickItemsByType($items, $type);
}

// Определяем число групп
$itemsCount = array_map('count', $itemsByType);
$pairsCount = min($itemsCount);

// Проходимся по группам товаров и даем скидку за каждую
for ($i = 0; $i < $pairsCount; $i++) {
$group = $this->selectGroup($itemsByType, $i);
$this->addDiscountForPair($result, $pair);
}

Вот, основная логика кода занимает небольшой объем и гораздо читабельнее. У тебя же код плохо читабелен, а разделение на функции (calculateIteration) не помогает его понять.

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

И еще, ты сделал метод Rule#calculate(), который принимает массив товаров и за один проход ищет все скидки. Но можно было еще сделать по-другому: он принимает массив товаров и возвращает первую найденную скидку. Соответственно, мы вызываем его в цикле, пока все скидки этого типа не найдутся. Плюс в том, что это упрощает код правила. Нам не нужно искать все скидки, достаточно найти одну. Для правила 1, например, код будет совсем простой:

function applyDiscount(array $items)
{
$group = [];
foreach ($this->types as $type) {
$item = $this->findItemByType($items, $type);
if (!$item) {
return;
}
$group[] = $item;
}

// Применить скидку к $group
return new Discount(....);
}

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

https://github.com/nokitakaze/test-programming-task-am-items/blob/master/src/Rules/RuleGroup.php

В этом классе, наверно, логично было сделать метод вроде applyGroup() или как-то так. А то класс не сильно отличается от просто массива.

https://github.com/nokitakaze/test-programming-task-am-items/blob/master/src/Rules/RuleSet.php

Не очень понятно, зачем этот класс.

https://github.com/nokitakaze/test-programming-task-am-items/blob/master/test/CalculatorTest.php

Тест сложный. Его тяжело прочесть, и понять, а правильный он или нет? В случае падения - непонятно, что именно не так. Обычно тесты пишут для проверки отдельных требований. В твоем случае, можно сделать такие тесты, начиная с тестирования отдельных скидок:

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

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

И не надо в одном тесте тестировать разные объекты (testprimitives). Надо было сделать 2 отдельных теста.
3 1415606
Вроде я проверил практически все посты в прошлом треде, и ответил на все вопросы, так что если вы что-то спрашивали, зайдите в старый тред >>1380485 (OP) и проверьте. А если я пропустил, напомните о себе тут.

Заодно я бы хотел разобрать одну интересную задачу из прошлого треда. Есть такая известная задача на ООП про скидки, кто мои задачи про ООП решал, думаю, без проблем справится. Вот тут вот задача: >>1395825 а тут решение анона: https://github.com/nokitakaze/test-programming-task-am-items/

Думаю, прошло много времени, так что прокомментирую решение:

> Правило №4 "стоимость выбранного продукта уменьшается на 5%". Что такое "выбранный продукт"? Покупатель произвольно пальцем тыкнул в любой продукт, и у него цена уменьшилась?



Это товар A из правила.

> Если одновременно выбраны А


Вот он и "выбранный".

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

https://github.com/nokitakaze/test-programming-task-am-items/blob/master/src/Item.php

Тут странный отступ в 4 пробела. Он не нужен.

> protected $_type;


Не надо использовать подчеркивание в именах свойств. Это было в PHP4.

> @var ItemType[]|ItemType[][]|null


> protected $_only_includes = null;



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

И вообще, тут ты имхо переусложнил код. Ты пытался сделать так, чтобы у правил было как можно больше общего кода, чтобы достаточно было передать для разных правил разные массивы, но это лишь привело к переусложнению логики. То есть, думаю, что из базового класса Rule можно вообще убрать эти поля exclude/inlcude.

Тебе не надо было в базовом классе делать поля exclude/include. Они не применимы ко всем видам скидок, и значит, им незачем быть в базовом классе. Также, не стоит полагаться на идею "класс-наследник должен переопределить этот массив", так как она никак не задокументирована и не проверяется. Если ты хочешь что-то требовать от класса-наследника, то используй абстрактные методы.

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

Также, посмотри на объем кода в https://github.com/nokitakaze/test-programming-task-am-items/blob/master/src/Rules/TotalCostSelectedItemsRule.php и сравни с тем, как это правило описано в одном предложении в задаче. Этот код стоит хотя бы разбить на методы с понятными названиями, сейчас он вообще не читаем.

Ну например, один из вариантов - это сделать так:

// Сортируем товары по типу
foreach ($types as $type) {
$itemsByType[$typeName] = $this->pickItemsByType($items, $type);
}

// Определяем число групп
$itemsCount = array_map('count', $itemsByType);
$pairsCount = min($itemsCount);

// Проходимся по группам товаров и даем скидку за каждую
for ($i = 0; $i < $pairsCount; $i++) {
$group = $this->selectGroup($itemsByType, $i);
$this->addDiscountForPair($result, $pair);
}

Вот, основная логика кода занимает небольшой объем и гораздо читабельнее. У тебя же код плохо читабелен, а разделение на функции (calculateIteration) не помогает его понять.

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

И еще, ты сделал метод Rule#calculate(), который принимает массив товаров и за один проход ищет все скидки. Но можно было еще сделать по-другому: он принимает массив товаров и возвращает первую найденную скидку. Соответственно, мы вызываем его в цикле, пока все скидки этого типа не найдутся. Плюс в том, что это упрощает код правила. Нам не нужно искать все скидки, достаточно найти одну. Для правила 1, например, код будет совсем простой:

function applyDiscount(array $items)
{
$group = [];
foreach ($this->types as $type) {
$item = $this->findItemByType($items, $type);
if (!$item) {
return;
}
$group[] = $item;
}

// Применить скидку к $group
return new Discount(....);
}

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

https://github.com/nokitakaze/test-programming-task-am-items/blob/master/src/Rules/RuleGroup.php

В этом классе, наверно, логично было сделать метод вроде applyGroup() или как-то так. А то класс не сильно отличается от просто массива.

https://github.com/nokitakaze/test-programming-task-am-items/blob/master/src/Rules/RuleSet.php

Не очень понятно, зачем этот класс.

https://github.com/nokitakaze/test-programming-task-am-items/blob/master/test/CalculatorTest.php

Тест сложный. Его тяжело прочесть, и понять, а правильный он или нет? В случае падения - непонятно, что именно не так. Обычно тесты пишут для проверки отдельных требований. В твоем случае, можно сделать такие тесты, начиная с тестирования отдельных скидок:

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

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

И не надо в одном тесте тестировать разные объекты (testprimitives). Надо было сделать 2 отдельных теста.
4 1415616
>>15605

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


Это же упоминается только применительно к методам.
5 1415617
>>15604 (OP)

>Почему PHP? Потому что вакансий море, и учить легко.


Ситуация на рынке не изменилась? Javascript или python в этом вопросе по-прежнему не конкуренты php?
6 1415618
>>15616

Верно. Но в Симфони так пишут, и ничего плохого, если те, кто не выбрал стиль, возьмут это за основу.
7 1415622
>>15605

>PSR-2


>4.3. Методы


>Открывающую фигурную скобку НЕОБХОДИМО располагать на отдельной строке


Насколько часто это соблюдается на практике? Я бы не хотел так писать, например.
8 1415625
>>15622
скажем так, если я вижу, что кто-то в методе написал открывающую скобку на одной строке с сигнатурой, то он либо тупой поскольку не знает стандартов либо долбоеб который не хочет принимать общепринятые условия и в упрек всем пишет "так как ему нравится".

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

>Насколько часто это соблюдается на практике?

10 1415632
>>15622

Я пишу на новой строке. Просто пиши как в Симфони, и проблем не будет.
11 1415649
>>15627
Вместо задавания глупых вопросов сходи на гитхаб и посмотри топовые либы - как они написаны.
12 1415660
>>15649

>как они написаны


Очень хуёво написаны. Я не хочу делать также, отсюда вопрос: если допустить, что я не буду делать топовые либы для всеобщего пользования, насколько критичным будет игнорирование данного пункта стандартов? Иными словами, в отдельно взятых командах могут быть "свои" стандарты, как мне докладывали. Вопрос в том, насколько часто они идут вразрез с PSR* и насколько вообще будут доёбываться до его несоблюдения.
13 1415664
>>15660

>Очень хуёво написаны.


Свой код покажи.
14 1415665
>>15664
Ты понял, что я имел в виду.
15 1415666
>>15660
Алсо, я бы тебя в команду не брал - ты какой-то слишком тупорогий не понимаешь элементарных вещей.
16 1415667
>>15665
Я не уверен, что у тебя есть вообще какой-то опыт в программировании. Своё мнение можешь в одно место засунуть.
17 1415669
>>15667
Что ты хочешь-то от меня?
Я задал вопрос, если ты не намерен на него отвечать - просто иди нахуй.
18 1415670
>>15669
Ясно. Зелень ебаная.
19 1415685
>>15660

Давай посмотрим объективно: какая ценность в том, что ты пишешь код в другом стиле? Никакой, просто тебе так больше нравится. Это не аргумент, в любой команде предпочтут использовать PSR вместо потакания чьим-то личным вкусам. В open source проекте это приведет к тому, что люди будут задавать вопросы по поводу нестандартного стиля и слать pull request в стиле PSR.

Самым простым и адекватным решением будет не выпендриваться и перейти на PSR. Это не так сложно, как кажется.
20 1415686
>>15666

Не надо переходить на оскорбления. Он к тебе в команду и не напрашивался.
21 1415689
ОП, меня пропустил. Помоги, пожалуйста:
>>1415145
>>1415175
22 1415690
>>15685
в опенсорс проекте просто пошел нахуй если твой код не в том кодстайле что и проект
23 1415692
>>15685
А на практике никто не особенно не докапывается до кодстайла потому что есть строки и они как правило горят, если ты будешь коллеге закрывать PR потому что у него скобки не так стоят, когда у него прод лежит и ему надо срочно запушить ты навлечешь на себя много нелюбви. Потому PRS крайне желателен, но не всегда обязателен.
24 1415700
>>15686
А я твоих советов не спрашивал. Иди нахуй.
25 1415703
>>15685

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


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

> В open source проекте


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

>>15692
Спасибо, буду иметь в виду и класть хуй на стандарты.
26 1415705
>>15703

>Спасибо, буду иметь в виду и класть хуй на стандарты.



Просто нажимаешь ctrl+alt+l и не имеешь проблем и никому не ебешь мозги
27 1415711
Что надо делать по PSR если у меня не помещаются параметры в одну строку? Сейчас я их разбиваю построчно.
Это норма?
28 1415714
>>15711
Это холиварный вопрос, потому что у подовляющего большинства уже широкоформатные мониторы, а не квадратные.

Во вторых, если у тебя в методе слишком много параметров то повод задуматься о том что ты что-то не так спроектировал.
29 1415717
>>15714

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


Что поделать, если пехапе не позволяет делать именованные аргументы?
30 1415720
>>15714

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


К чему эта реплика вообще?

>если у тебя в методе слишком много параметров


Штуки 3, просто названия длинные.
31 1415722
>>15717

>Что поделать, если пехапе не позволяет делать именованные аргументы?



1. Идти программировать на питоне.
2. Засунуть все аргументы в какой-то объект и передавать его.
3. Передавать ассоциативный массив как аргумент
32 1415725
>>15720

>К чему эта реплика вообще?


К тому что это ограничение по длине строки возникло от того что раньше не у всех на монитор эти строки влазили, было неудобно
33 1415728
>>15725
Лол, нет.
Длинные строки читаются хуже чем короткие.
34 1415729
>>15722

>Передавать ассоциативный массив как аргумент


Слишком много скобочек(["и" => "кавычек"]);
35 1415732
>>15729
да еще и потом внутри метода устанешь проверять есть ли такой элемент в массиве
36 1415733
>>15689

Ты, возможно, неправильно формируешь ссылки и подставляешь в них параметры. Прочти урок про URL и проверь, соответствует ли твой код тому, что там написано и не может ли быть проблема в этом: https://github.com/codedokode/pasta/blob/master/network/urls.md

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

Далее, если это не поможет, то сдампь (echo) получающийся URL, и запости, токен при этом, конечно, надо скрыть. Посмотрим на URL.

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

- утилитой curl (не php расширением) в командной строке
- программами с GUI вроде postman для отправки запросов

Мне больше нравится командная строка. Через эти программы ты можешь отправить запрос на сервер и увидеть, что приходит в ответ. Сделай это и тоже напиши.
38 1415751
>>15742
Благодарю.
39 1415769
>>15733
Уже написал пост и понял, какой я идиот. Всего-то требовалось 3 дня всматриваться к код и забыть про очевидные вещи. У меня один!! пробел не был url-закодирован. Но почему этот пробел не вызывал ошибок в десятке случаев, а тут вызвал? Это единственное, что мне не ясно. Будь это ошибка везде сразу, я бы быстро нашел, в чём дело.

Тогда другие вопросы задам. Можно отсылать файл multipart/form-data, используя file_get_contents? Или что-то еще, загружающее файл из ссылки в оперативную память и отсылающую её в телеграм оттуда.
40 1415806
>>15769

Заметь, что в мануале написано: https://www.php.net/manual/ru/function.file-get-contents.php

> Замечание:


> Если вы открываете URI, содержащий спецсимволы, такие как пробел, вам нужно закодировать URI при помощи urlencode().



Надеюсь, что ты освоил теперь кодирование спецсимволов.

Что касается отправки файла. У file_get_contents есть контекст, и в нем можно указывать опции HTTP-запроса. Смотри пример №4 в мануале: https://www.php.net/manual/ru/function.file-get-contents.php

Тут есть документация по опциям HTTP-контекста: https://www.php.net/manual/ru/context.http.php

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

Я бы советовал освоить нормальную библиотеку вроде Guzzle, где отправка файла делается проще. Ну или расширение curl, хотя Guzzle по моему удобнее.
41 1415823
Сап аноны!

Сейчас читаю основы регулярок и там попалась задача с выбором корректных номеров. Вроде бы справился, но немного на говнокодил в регулярке и опустился до копирования и спама.
https://ideone.com/b58D3Q
Как можно написать эту регулярку красивее?

(Сори за кровь из глаз)
42 1415831
>>15806

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


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

>У file_get_contents есть контекст


Да, я уже указал там ssl и прокси.

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


Не думаю. Добавил в контекст Content-Type: audio/mpeg, но файл всё еще не отправляется. Кусок:
'http' => array(
'header' => array("Proxy-Authorization: Basic $auth", 'Content-Type: audio/mpeg'),
Прокси работают, я проверил, открыв с file_get_contents yandex.ru/internet.

>Ну или расширение curl, хотя Guzzle по моему удобнее.


А как это провернуть curl'ом? Мне нужно отправить не ссылку, а файл, при этом не загружая его на сервер, потому что работа с файлами запрещена. Вот и думаю, как загрузить из оперативки.
43 1415839
>>15606
ОП ты знаешь яву?
44 1415845
>>15831

Ты зря пренебрегаешь теорией и не изучаешь HTTP. Ты опять неправильно кодируешь тело запроса. Почитай про тип multipart/form-data, раз решил его использовать:

- http://citforum.ru/internet/html40/interact/forms.html#h-17.13.4.2
- https://learn.javascript.ru/xhr-forms#kodirovka-multipart-form-data

Я думаю, что Guzzle будет освоить проще.
45 1415878
>>15845
Я просто не понимаю, что вообще требуется. Мне не от чего отталкиваться. Нужно увидеть правильный код, чтобы знать, где ошибки нет и где могут они быть. Я обычно так и учусь, от этого отталкиваюсь. Приходится учиться на своих ошибках, но зато запоминается лучше. А теория без этого непонятна, я прочитал 2 твои статьи и они мне ничего не дали.

Вот нужно мне получить файл в переменную $song, чтобы сделать:
$url = "https://api.telegram.org/bot$botapi/sendAudio";
$header = array('Content-Type:multipart/form-data');
$post = array(
'chat_id' => $chat_id,
'audio' => $song
);

curl_get_contents($url, $proxy, 0, $header, $post); //простая функция с curl

И как мне поможет Guzzle, curl или file_get_contents?

>Ты опять неправильно кодируешь тело запроса.


Разве? Это в контексте для file_get_contents, и... А, массивом оно не передается? Сделал так:
'header' => "Proxy-Authorization: Basic $auth\r\n" . "Content-Type: audio/mpeg",
Только я всё еще не могу отправить файл. Я могу отправить его, если просто скачаю в папку, или отправить его по ссылке. Но решить задачу в том виде, в котором она есть, уже не могу.
46 1415887

>Ты опять неправильно кодируешь тело запроса.


А, всё. Я отправляю запрос с заголовком ответа сервера. Прости, я тупой.
47 1415910
Ещё я только понял, что получаю содержимое файла и плевать, что использовать - Guzzle, curl или file_get_contents. Нужно бы отдохнуть, чтобы так не тупить, но я хочу закончить.
48 1415920
Я правильно понял, что мне нужно содержимое самостоятельно закодировать в multipart/form-data? Понять бы теперь, как это сделать.
49 1415930
>>15920
Бля, мужик, чё у тебя за проблема запрос организовать с нужными параметрами? Второй день написать не можешь.
Подтягивай матчасть значит.
50 1415987
Хочу писать - начинаю писать - сразу не хочу. В чем моя проблема? =)
51 1415989
>>15987

>начинаю писать - сразу не хочу


Если писать неприятно - проверься на простатит.
52 1415991
>>15987
У меня наоборот обычно - начинать не хочу, а в себя прихожу через пару часов как минимум.
53 1415995
>>15989
ударение на второй слог
54 1415998
>>15987
Добро пожаловать в клуб!
55 1416125
>>15604 (OP)

>поздравляю тебя с отсутствием мозгов!


Иди нах, умник
56 1416161
>>15605
Зачем нужны четыре пробела, если есть таубляция? Ладно бы отбивалось одним-двумя пробелами, но визуально-то одно и то же!
58 1416173
>>16169
А нахуя ты таб по 4 раза жмакал, долбоеб
1 таб = 4 пробелам визуально.
59 1416225
>>16169
Ширину табуляции в любой IDE настроить можно. Ставь хоть с пробел.
Мне вот таб легче нажать, чем как обезьянка пробел дрочить по 4 раза на строку, а то и больше.
60 1416344
>>16225
Ну так по секрету, все так и делают, никто не дрочит пробел.
61 1416375
>>16344
А что я постоянно эти вопросы встречаю везде?
62 1416408
>>16161
В какой-то момент выбора между табами и пробелами вылезли художники-педерасты и начали пронзительно верещать, что они хотят что бы один и тот же код повсюду выглядел одинаково, в то время как табы по разному отображаются в различных IDE/редакторах. К сожалению, им не успели насрать на лицо и поэтому блядские пробелы теперь стандарт.
63 1416422
>>16408

>табы по разному отображаются в различных IDE/редакторах


Какой-то хуёвый аргумент - они отображаются как настроено.
Что за инвалиды не могут сделать себе как нравится: хоть 1 отступ, хоть 8, если такой любитель? С пробелом такие штуки не получится вытворить.
64 1416424
>>16422
А ещё IDE обычно с табуляцией немного код подравнивает, в силу своего ума. Пробелы тут тоже сосут.
65 1416436
>>16375
Потому что ты сидишь на борде для детей.
66 1416443
>>16422

>Какой-то хуёвый аргумент - они отображаются как настроено.


Вот именно. А пачке педиков было неприятно, что код, который они выравнивали в соответствии со своими художественными вкусами, у кого-то будет выглядеть по другому.
67 1416458
>>16443
Ещё с табами можно динамически отображать вложенность операторов просто меняя ширину отступа, но не меняя при этом исходников.
68 1416558
>>16443
Хуйня может получтся если табы с пробелами смешивать. Если ты отбиваешь отступы табами - ты не хочешь чтобы IDE меняло их на пробелы. Соответственно не подравнивай код пробелами иначе у другой макаки может хуита получится у которой ширина таба другая
69 1416562
Кроме того табодолбоебы не учитывают что в коде не только идентация для блоков нужна но и иногда приходитсяи строки переносить и аргументы нетодов и пары клч => занение у массивов и другие конструкции для читабельности. Бляди начинают лупить табы с пробелами. А если у меня таб == 2 пробела
70 1416567
Ребят, извиняюсь за тупой вопрос, но что требуется знать на подобных вакансиях
https://spb.hh.ru/vacancy/31725993
https://spb.hh.ru/vacancy/31636756
кроме собственно языков? Ведь полюбому там необходимы фреймворки, тестирование, package manager, дебаггер, разные БД, потом еще по фронту React, jquery, адаптивная верстка.
71 1416569
Скажите пожалуйста, сколько времени займет изучение основ PHP так чтобы на стажера хватило? Ну чисто по времени
72 1416570
>>16567
Позвони им. Если они связываются со стажерами - значит у них дохуя свободного времени.
73 1416575
>>16569
На стажера одного пхп не хватит. Лучше иметь общую эрудированность в ИТ, чтобы самостоятельно искать информацию и решать задачи. Задачи тебе посильные найдут а вот нянчится и объяснять тебе никто не будет. Хоть ты и стажер
74 1416583
>>16575
Ну я понимаю, просто на изучение всех тонкостей PHP уйдет больше всего времени, как мне кажется. А настроить сервер и подключить к нему базу данных можно за пару дней
75 1416590
>>16583
На ПЧП у тебя уйдет ровно столько времени сколько потребуется у данного работодателя, какой попадется. Так что если знаешь что апач это программа которая запускает интерпритатор пхп и что пхп выполняется на сервере. Что запросы передаются байтами по сети по протоколу хттп. То иди уже стажерь
76 1416594
>>15627

>Насколько часто это соблюдается на практике?


кем? В любой нормальной фирме с нормальными программистами придерживаются стандартов.

Если ты кодишь для себя и никто с твоим кодом работать не будет кроме тебя, то пиши как хочешь, а в противном случае придерживайся стандартов.
77 1416599
>>16590
Круто. Порог вхождения низкий, стажировки в наличии. Не то что в этом гнусном фронтенде, откуда я пришел (не получилось вкатиться). Ну ничего, зато пригодятся знания html, css, js.
78 1416604
>>16599
Порог низкий - потолок тоже низкий. Смотри не ушибись.
79 1416615
>>16604
Хорошо сказано.

мимопроходил
80 1416624
>>16590
И что, этого хватит?
81 1416626
>>16624
Зависит от того насколько низко ты готов опуститься.
82 1416628
>>16594

>Если ты кодишь для себя


Я сначала так и хотел, когда начинал. Теперь только по рекомендациям и пишу - там многие мелочи за меня продумали. Совсем ленивый стал.
83 1416634
>>16626
Да я любой работе буду рад
84 1416638
>>16634
Тебя какой-то хуй троллит.
Тебе тестовое вышлют, которое ты провалишь скорее всего. Вряд ли они мимокроков набирают - уж язык знать хорошо должен.
85 1416662
>>16638
А если пройду? Это же только допуск к собесу
86 1416682
>>16662
Думаешь ты один такой умный? Придётся конкурировать с теми, кто уже хоть что-то знает.
87 1416733
>>16408
>>16422

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

Ну и я не понимаю: если тебе хочется поменять величину отступов (странное желание, ну ладно), что тебе мешает делать это с пробелами? Напиши плагин к редактору, который будет при выводе заменять каждые N пробелов на M. И все будет настраиваться без всяких табов.

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

То же самое можно элементарно делать в пробелами. напиши плагин к своему убогому редактору, который будет вместо N пробелов подряд выводить M.
89 1416742
Вы из какого года вылезли, все споры на тему табы-пробелы уже давно решены с помощью стандарта PSR2 и инструмента PHP-CS-Fixer, который автоматически форматирует код согласно общепринятому стандарту: https://www.php-fig.org/psr/psr-2/#1-overview
Этому стандарту следуют все ведущие фреймворки вроде Symfony и Laravel, поэтому для единобразия вы тоже обязаны ему следовать, а не лезть со своим уставом в чужой монастырь, иначе будет бардак.
IDE поддерживают PHP-CS-Fixer, так что вы можете одним хоткеем форматировать код по стандарту. Обсуждать тут нечего.
90 1416768
>>16733
>>16735

>напиши плагин


Ты надеюсь понимаешь как это ебануто звучит? Вместо целевой разработки я должен заниматься переделкой IDE.
Толсто в общем.
91 1416769
>>16733

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


Уже есть такой плагин - табуляция.
92 1416902
С Хероку кто-нибудь работал?

>Dyno memory:


>Different dyno sizes offer different amounts of maximum RAM:


>free, hobby and standard-1x have 512 MB



>Dyno memory and restarts:


>If the memory size of your dyno keeps growing until it reaches two times its quota (for a standard-1x dyno, 512 MB x 2 = 1 GB), the dyno manager will restart your dyno with an R15 error.



И у меня при этом вылетает ошибка:

>PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 41959424 bytes)


Как увеличить лимит с 128 МБ до максимума?
93 1416920
>>16902
https://devcenter.heroku.com/articles/php-concurrency
Нашел вот это. Так и не понял, а выше 128 поднять никак нельзя?
94 1416928
>>16920
Всё, разобрался.
.user.ini, вроде, не работает, но ini_set("memory_limit", "1024M") - вполне.
95 1416951
>>16768

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

Меня пробелы полностью устраивают. Вот мне делать нечего, вместо того, чтобы думать над программой, думать, где я должен табы, а где пробелы ставить.
96 1416953
>>16768

Ну и насколько я знаю, элита /pr/ использует очень гибко конфигурируемые редакторы, под которые можно писать макросы на элитном языке со скобочками, для них такой плагин сделать, наверно, дело десяти минут.
97 1417055
Парни, есть странный вопрос. Как из php скрипта запросами можно на лету кардинально изменять структуру(!) таблицы в бд, если не считать ALTER TABLE.?
98 1417057
>>17055
Создать новую таблицу и импортировать туда инфу со старой, потом удалить старую и переименовать новую.
99 1417123
>>15604 (OP)
Замечательная шапка, ОП, ты молодец!

мимопроходил
100 1417348
Объясните, зачем php разработчику углубленное знание джаваскрипта, если он не фулстек? Почему так в шапке написано?
101 1417413
>>17348
Всмысле углубленное. Там простые задачи, чтобы ты мог хоть что-то сделать
102 1417434
>>17413
ну, этим же фронтендер должен заниматься?
103 1417476
>>17434
Ну не хочешь не учи
104 1417479
>>17057
Ну вообщем да, без копии бд никак не получается, целый день пытался чот измудрить. Если кому нибудь придет что в голову отпишите плз, я мониторю тред.
105 1417583
Наверное вопрос не по теме треда, но всё равно спрошу. У меня был сервер на котором лампово вертелся блог WP и форум phpBB (каждый на своём домене) всё это было на php5 разделенное по своим "блокам" chroot+fpm
Сейчас обновил всё до php7.2 и получается очень странная херота, что в некотором проценте случаев php процесс ВП пытается прочитать файлы из системы форума, а форум иногда выдаёт 404 ошибку из-за отсутствия wp-config.php, то есть как-будто их chroot смешиваются, или процессы уходят не туда. При этом все конфиги уже трижды переписаны и в nginx и в php всё по эталонным инструкциям, да и поиск не выдаёт - что у кого-то были подобные проблемы. Что делать?
106 1417736
Привет котаны. Я нуб, ток осваиваю PHP.
Что имею\умею - имеется содранный и чуть переделанный MVC фреймворк. Представление реализовано стандартно - html возвращаю шаблонами с разметкой. В принципе я это все понимаю в "принципе", ага.
Сейчас в учебных целях я на свой недофреймворк натягиваю бутстрап-шаблон, в шаблоне соответственно всякие поля для отправки почты и менюшки и прочее. Все это реализовано с помощью джейквери.
Так уж получилось что поверхностно знаю reactjs что то уровня todo могу сделать.
Вот что прошу подсказать:
Я читал о том, что в стандартную страницу можно вставлять отдельные компоненты react, и мне хочется не джейквери использовать в отдельных случаях, а попробовать воткнуть реакт-компонент. Тупо отдельную форму отправки почты.
Как это сделать? С помощью вэб-пака я собираю бандл реакта, в котором допустим код одного компонента, и вставляю его куда нужно в моем шаблоне? Но это я понимаю на столько в общем, что нихуя не понимаю.
У кого нибудь есть подобный опыт? Опыт простенького скрещивания реакта с пхп?
107 1417753
>>17736
О, Реакт. Моя любимая тема.
Была дом, и в доме срали в подвале. Управдома это заебало и что вы думаете он сделал? Может быть, он натыкал камер в подвале? Или он поставил биотуалет близко к подъезду? Нет, конечно. Он приклеил на подвал табличку Туалет! Вот это React-way.
Когда я увидел ёбаный JSX и охуительные функции render(), мои волосы встали нахуй дыбом. Я сам несколько раз лепил html в js, но я никогда не считал это чем-то хорошим. Я до последнего не мог поверить, что этот кусок кала - признанный на весь мир фреймворк.
108 1417761
>>17736
в простейшем случае ты его просто затребываешь инлайн прямо на штмл странице как жиквери https://reactjs.org/docs/add-react-to-a-website.html#add-react-in-one-minute

но если хочешь spa то надо https://facebook.github.io/create-react-app/

>>17753
пиши без классов, с хуками так сейчас все и пишут т.к. сет стейт не нужна

алсо

>Я сам несколько раз лепил html в js, но я никогда не считал это чем-то хорошим.


у тебя есть выбор или джс в штмл или штмл в джс, не вижу существенной разницы
109 1417773
>>17761

>не вижу существенной разницы


А она есть. В случае, когда у тебя нет Реакта, тебе приходится в html время от времени скармливать готовым объектам <?=json_encode($array); ?> и всё. Реакт же сплетает в братских объятиях логику и представление.
Я сталкивался с Реактом на 5 проектах, и каждый раз меня не покидало ощущение, что я сделаю аналогичное говно на нативке страниц на 20, достаточное для конкретного проекта, и при этом избавлюсь от тонны проблем.
Vue вернул мне веру в человечество, это именно то, чем должен быть фронт фреймворк.
110 1417789
>>17736

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

Ну например, типичный пример приложения - это бесконечная лента новостей с категориями, комментариями, лайками, работающая (насколько хватает возможностей) в оффлайн-режиме при временном пропадании интернета.
111 1417816
>>17761

>>в простейшем случае ты его просто затребываешь инлайн прямо на штмл


Да, именно это хочу. Спасибо!
SPA пока чето не хочу.
>>17753
Ну, тут теорема эскобара.
>>17789
Не, именно хочу компонент воткнуть. Естествоиспытательский интерес.

А вообще в принципе есть разница на каком языке бекенд для SPA написан? пхп/нода/питон?
Читал что траблы с асинхронностью есть у пхп. Но честно говоря нихуя не понял. Ноду я знаю немного, и логику работы цикла событий понимаю. А пхп как в данном случае работает?
112 1417821
>>17816

>А вообще в принципе есть разница на каком языке бекенд для SPA написан?


нет, нету
на ноде пишут т.к. можно все прямо в одной папке проекта писать - и сервер и клиентскую часть, кроме того она довольно быстрая, быстрее питона, пхп и руби
113 1417823
>>17816

А зачем тебе асинхронность? Это только усложняет написание кода. Плюс, у PHP, в отличие от Node.JS, гораздо лучше реализована буква S (stateless) из REST, и в нем ниже вероятность утечек памяти.
114 1417826
вообще да, из-за асинхронности нода сложнее
но она из-за нее же и быстрее
115 1417831
>>17826

Это очень сильно зависит от ситуации. Да, есть ситуации вроде проблемы 10K, где асинхронность может помочь, но если у тебя приложение просто делает селект из БД и обрабатывает данные, то работать оно будет одинаково, просто в асинхронном коде все будет сложнее и будет куча ненужных в синхронном коде промисов.
116 1417931
>>16567

> Аноним 14/06/19 Птн 20:42:35 №141656770


>


Не ходи в qsoft, там заставят код на листочке писать, а потом посадят на битрикс. Будешь потом плакать и суицидом все закончится.
117 1418037
Скажите, какой примерно минимальный проект нужно сделать, чтобы вкатиться? Чтобы и на гитхабе не стыдно показать и опыта полезного дало
118 1418043
>>18037
Рандом. Нужно тупо ходить по собеседованиям пока не прокнет.
119 1418053
>>18037

У нас в шапке есть проект TestHub - это наверно немного с запасом, как мне кажется, неплохой проект для начинающего, который может показать его/её навыки.
120 1418057
>>17816
>>17821
>>17823

Котаны, на волне интереса я решил снова поковырять ноду, сорр что тут спрашиваю, но в js тредах спрашивать про бекенд чет не лежит душа. Когда я изучал ноду, я инвалидно юзал express, абсолютно не понимая зачем нужны мидллвейры. Но я не понимаю и сейчас.
Вот допустим, у меня php MVC фреймворк. Роутинг там классический - регуляркой парсится url, и вызываются соответствующие контроллеры и экшены. Где в данном случае могут быть применены мидлвэйры в нодовском понимании?
121 1418058
>>18057

Middleware обычно работает с запросом/ответом на уровне протокола HTTP, типичные применения:

- логгирование, статистика
- сжатие передаваемых данных
- шифрование/расшифровка кук
- кеширование на уровне HTTP протокола
- ограничение числа запросов, отсев ботов

Поищи список middleware к нужному фреймворку и посмотри, что там есть.
122 1418072
Пи Эйч Пи-и-и-и.
123 1418082
>>18072
Почему очень много уважаемых и шарящих в этой теме людей на полном серьезе произносят PHP как ПЭ ХА ПЭ?
Это какой-то мем или им просто похуй?
124 1418085
>>15604 (OP)
На самом деле, сейчас, во время, когда существует бешеное количество информации, от которой Сократ сошел бы с ума, лол, главная проблема - 95% инфы - просто лажа, и нужно искать среди терабайтов данных действительно стоящий материал. А это все из-за того, что каждый мудак, который умеет находить последовательность чисел фибоначчи, считает себя супер-пупер гением, и решает запилить обучающий, мать его, контент. Вот и выходит, что интернет - огромная помойка, сайты - лажа, инфа - блевотина бездарей. И чтобы среди этого обезьянника встать на путь становления человеком, нужно понять, что невозможно выучить все, только лишь улучшая понимание каждого топика ежедневно, запоминая и анализируя теорию, практикуя навый код, решая появляющиеся проблемы, мы можем развиваться. Поэтому, ребята, просто удалите все, что не открывали в течении последнего месяца, оно вам не нужно, задайте вопрос себе: "Чего я хочу? Кто я сейчас и что могу?, возьмите одну тему и изучайте ее. Это же структурный подход, пользуйтесь им. Удачи. Кто еще говорил, что это наука, и она не может быть простой и понятной? Кто говорит, что программировать легко - бездари, лжецы, продажники, и прочая челядь, которая срет в уши. Самое молодое направление в науке, как оно может быть простым?
125 1418149
>>18082
Можно говорить ЭР НЭ ЭР
126 1418150
>>18149
лнр
127 1418177
Еще раз хочу сказать спасибо ОПу и всем пищущим, вы заняты богоугодным делом
128 1418278
Мда, я думал джаваскрипт это дерьмовый язык. Теперь я изучаю пхп и понимаю, что такое настоящий дерьмовый язык. А джаваскрипт просто запутанный.
Надеюсь эти недостатки как-то решаются, с помощью фрейворков или еще чего, или просто с ними не сталкиваешься по работе. А то я не знаю как я буду с этим работать
129 1418304
>>18278
Я тебе как программист html заявляю
<?php echo"<div>да ты охуил чтоли!</div>" ?>
130 1418313
>>18304
<div><?= 'Да ты охуел, чтоли?!' ?></div>
131 1418314
>>18313
а ты хорош
132 1418390
>>18278
Все так.
И да, ца у этого пыхыпыговна соответствующая - тупое, совершенно безмозглое быдло.
Семенящий дебил по кличке ОП >>18177 - например.
133 1418468
>>18278
Нормальный язык PHP. И что крайне важно - заебенно подходит под свою задачу. Комьюнити годное. И доки отличные. В принципе для вэба среднего масштаба руки лучше ничего нет.
Я сейчас с нодой решил поебаться, но так как подзабыл JS ебусь с прототипами, а после буду ебаться с evemtEmmiter что бы понять что откуда в этом блядстве наследуется.
134 1418469
>>18468
Классы в пхп гораздо симпатичнее, и это нормальные классы, с нормальной инкапсуляцией.
135 1418541
Анончик помоги, не выполняется запрос. В php вторую неделю.
Работаю php+apache+mysql +phpmyadmin
Сейчас еще кину скрин формы в index.php..
Два дня ебусь, гугл не помог. Молю, с меня нефть
Screenshot 2019-06-18 at 22.23.17.png67 Кб, 989x215
136 1418543
>>18541
форму переменной в запросе '{$login}' по-другому тоже писал '$login' дело не в нем.
form.
137 1418545
>>18541

Для начала, исправь уязвимости в своем коде: SQL инъекцию и хранение паролей в открытом виде:

- https://github.com/codedokode/pasta/blob/master/security/sql-injection.md
- https://github.com/codedokode/pasta/blob/master/security/password-hashing.md

Далее, у тебя есть код if ($connection == 0). Открой мануал по mysql_connect и прочитай, что она возвращает. Там должно быть сравнение не с нулем. Используя var_dump(), выведи, что возвращает функция mysqli_connect,

Далее, при использовании mysqli ты должен проверять результат вызова каждой функции, что она не вернула например null или false (что именно, написано в мануале по этой функции). Ты должен ставить if с проверкой после каждого вызова mysqli-функции. В твоем случае, нет if после
mysqli_query.
138 1418547
>>18541

Ой, вижу, что от инъекции у тебя защита есть. Но хранение паролей все равно стоит переделать.
139 1418551
>>18541

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

error_reporting = E_ALL

вместо того, что там написано, чтобы не скрывать никакие ошибки.
140 1418587
>>18545
>>18547
>>18551
Короче прикинь, я понял ошибку.
Оказывается в запросе , к примеру (INSERT INTO `users` (`id`, `login`, `password`) VALUES ('55', 'fdf', 'fdf'));
у users, id, login, password ДОЛЖНЫ СТОЯТЬ другие ковычки ```
А в остальном обычные ''
Воот, как пофиксить эту ебалу? Что бы везде одинаковые ставить стандартные одинарные ковычки?
Может это потому что я на маке?
141 1418589
>>18545
Мое лицо из-за таких вот ошибок:
https://youtu.be/aJFrfE2uzY4
142 1418616
>>18541
У тебя опечатка в слове $conection енжой йор динамическая типизация
143 1418641
>>18547

>Ой, вижу


>>18587

>Короче прикинь


Пиздец два педика.
144 1418683
>>18541
переходи на PDO
145 1418693
>>18587

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

http://www.mysql.ru/docs/man/Legal_names.html
146 1418715
>>18641
Ща бы доебываться до слов..
147 1418899
>>18683
А чем оно лучше API mysqli?
148 1418904
>>18899
PDO более универсален - с разными базами можно работать.
149 1418907
Начинаю изучать PHP. Прочитал, что сейчас MySQL - неактуально и стоит переходить на PDO. Тру?
150 1418938
>>18904
А какие могут пригодиться кроме mysql
151 1418944
>>18907
>>18938
постргресс
152 1418967
Вкатываюсь в пхп. Прочитал шапку фул. Нашел 2 книги, но не сказал бы, что они прям для новичков (их описание говорит тоже об этом). Посоветуйте что-то объемное, охватывающее большинство ключевых моментов, но при этом понятное
153 1418995
>>18938
Любые другие.
154 1418997
>>18967

>Прочитал шапку


>Нашел 2 книги


Ты в библиотеку вкатываешься или в разработку? Толку от чтения без практики?
155 1419144
>>18967
Я бы вообще посоветовал на ютубе посмотреть туторы, для базиса.
В книге все слишком подробно описана каждая вещь поэтому чтоб в целом узнать структуру придется прочесть 500+ страниц
156 1419145
>>18997
Нужно больше книжек богу книжек
157 1419153
>>18967

>Посоветуйте что-то объемное, охватывающее большинство ключевых моментов, но при этом понятное


Мне понравилась местная задачка со студентами - практически все аспекты веб-разработки там усвоить придётся. Лучше всяких книжек.
158 1419154
>>18967
Как вообще можно учить язык без выполнения какой-то задачи я хз.
159 1419207
Route::view в ларе отвечает за указание на файл со страничкой?
160 1419407
Аноны, есть тут кто то кто на Node.js пишет? Я увлекся немного.
Хочу что то аналогичное моему php-фреймворку запилить - то есть роутер парсит url, и вызывает соответствующие контроллеры и экшены.
В сети все туторы на express, там это все несколько иначе. Впрочем обработчик запроса в express поддерживает регулярки. Но в JS нет аналога preg_match. В JS нет автозагрузки классов хотя может она не нужна? Ведь класс загружается однажды, и висит в памяти, так?
Сейчас хочу что то типа MVC фреймворка на ноде сделать. Что бы подгружались классы и вызывались экшены.
Не в JS тред пишу по очевидным причинам - они там учатся css динамически менять.

А так, глубже копнув ноду - всеже как же удобен пхп для своих задач. В ноде что бы данные из post вытащить - нужно поебаться.
161 1419442
>>19153
Да, хорошая задачка. А можете порекомендовать какой-нибудь видеоурок, короткий, но дающий все базовые навыки веб разработки? Можно без фронта
162 1419443
>>19407

>В JS нет автозагрузки классов


Так язык был придуман специально для динамической смены css. Зачем ему это?
Хочешь современных фич - используй тайп скрипт.
163 1419455
>>19442
Нет такого урока, да и быть не может. Поначалу полезно всё подряд смотреть, пока сам не подберёшь себе нужный формат и курс.
Screenshot 2019-06-20 at 19.53.49.png198 Кб, 1221x741
164 1419523
Почему ошибки в php такие некорректные?
Пишет ,что скобка лишняя:
Parse error: syntax error, unexpected ';' in /Users/akismac/Sites/bar/includes/registration.inc.php on line 19

А по факту все ок
165 1419540
>>19523
Не лишняя а неожиданная, значит что то не дописано раньше.
Ты одну ) потерял в 17 строке.
166 1419546
>>19523
Какой милый код, анон
Смотрю и глаза радуются
167 1419552
>>19523
что за тема подсветки синтаксиса?
168 1419562
>>19552
Стандартная тема Саблайма.

>>19546
Чего в нём милого? Обычный джунский код.
169 1419564
>>19562
спасибо
170 1419576
>>19562

>Обычный джунский код.


Это ты так думаешь

>Чего в нём милого?


У тебя просто нет чувства прекрасного
171 1419581
>>19576

>Это ты так думаешь


Ну да - я, не ты же. С чего бы мне твои мысли высказывать?

>У тебя просто нет чувства прекрасного


Ты красивее просто ничего не видел.
172 1419582
>>19581

>Ты красивее просто ничего не видел.


Нет, просто я умею находить прекрасное и красивое в мелочах, вроде твоего "обычного джунского кода".
173 1419587
>>19582
В каких ещё мелочах? Там даже программирования нет, как явления. Ты просто дёргаешь стандартный функционал - ни обстракций не завезли, ни знаний технологии. Это даже не джун, а скрипт-кидди.
Ещё и семёнишь.
174 1419588
>>19407

> Но в JS нет аналога preg_match


Есть. Либо /regex/.test(string) либо string.match(/regex/)

> В JS нет автозагрузки классов


В JS нет, в ноде есть модули, которые можно экспортировать и импортировать, а в новой ноде с флагом experimental-modules можно использовать ES6 модули: https://nodejs.org/api/esm.html#esm_code_import_code_statements

Не понимаю, что ты там велосипедить собрался. Поддерживаю чужой проект на ноде третий месяц после нескольких лет Symfony/Doctrine, ощущения как будто пересадили с болида Формулы 1 на одноколёсный велосипед:
- Sequelize вместо нормальной ORM: нет автоматической генерации миграций, на foreign key предыдущие разрабы положили болт, потому что самим лень проставлять, а Sequelize не умеет их добавлять автоматически (Doctrine умеет)
- Нет способа быстро получить CRUD API, для Symfony есть API Platform, который ставится одной командой и позволяет несколькими аннотациями описать CRUD API для сущностей со всеми типами связей, фильтры, пагинацию, поиск по частичному совпадению
- Всё на JS (не TypeScript), автокомплит и go to definition в половине случаев не работают, куча нигде не описанных структур разного уровня вложенности (даже в PHP сейчас принято заворачивать такое в объекты с геттерами, чтобы хоть где-то в коде были описаны такие структуры)
- Про DI контейнер никто не слышал, поэтому норма когда в каждом консольном скрипте копипаста на 100 строк из ручной конфигурации. По этой же причине везде static методы, люди просто не знали как по-другому

Итого: Если нужно, чтобы проект не утонул под тяжестью багов и велосипедов спустя пару лет - нужно брать фреймворки, которые диктуют архитектуру и в которых многие проблемы уже решены, чтобы программисты проявляли меньше творчества. Если бы проект изначально писали мы, то взяли бы PHP и Symfony.
175 1419598
>>19540
спасиб
176 1419601
>>19587

> ни обстракций не завезли


Почему все "кодеры" 21 века ,любят напыщенные абстракции и считают это понтом? Причем в больших колличествам.
Вас что всех в универе по одинаковым системам образования прогоняли? Представь себе, раньше вообще небыло ООП, люди писали функциональщину. Ооп просто мода, часто ее пихают туда где от нее нет никакого смысла.
177 1419602
>>19601

>функциональщину.


процедурщину,историк
178 1419608
>>19601

>любят напыщенные абстракции и считают это понтом?


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

>раньше вообще небыло ООП


Раньше программы меньше были, и компьютеры больше.

>Ооп просто мода


Это ты сказал?

>пихают туда где от нее нет никакого смысла


Надо тебя спрашивать куда чего пихать?
179 1419622
>>19588
А почему не Laravel?
GitHub 180 1419631
Как оформить свой блядский гитхаб, чтоб он был не всратым портфолио?

У меня там акк с 2014 года. И я срал туда всей хуйней и по работе и свои либы и куча начатых и не законченых проектов и олдовый говнокод - куча говна.

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

Надо удалять все говно и оставить только годноту? Но я ж там с 2014 и вся история потрется((( Завести новый для портфолио? Или забить хуй и расположить новые годные проджекты?
181 1419634
>>19608

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


А чем ооп спасет? Там же тоже надо знать какие у тебя функции в классе, какие нужны параметры для инициализации
182 1419637
>>19631
А разве там нельзя скрывать репозитории?
Вообще хз - будь я на месте работодателя, то смотрел бы последний код, а не то, что ты 5 лет назад писал?
183 1419638
Нихуя Себе У Меня Случился Бесконечный Цикл
Браузер В Полном Зависоне
Я Тоже В Нем И К Тому Же Я В Ахуе
Ушел Греть Голову На Улице

Пиздос
184 1419661
>>19638
ЗАЕБИСЬ!!!!!!!!!!!!!!!!! У МЕНЯ ВСЕ ПОЛУЧИЛОСЬ УРААААААААААААААААААА
ОН БОЛЬШЕ НЕ БЕСКОНЕЧНЫЙ
185 1419697
>>19523

У тебя неправильно формируются ссылки для редиректа, а именно, не происходит корректной обработки спецсимволов при подстановке в них параметров. Советую почитать урок и исправить: https://github.com/codedokode/pasta/blob/master/network/urls.md

Также, есть более удобный алгоритм обработки форм, позволяющий исключить лишние редиректы: https://github.com/codedokode/pasta/blob/master/forms.md
186 1419700
>>19631

Во-первых, заполни информацию о себе. Во-вторых, там вроде есть pinned repositories, которые можно закрепить вверху списка. В-третьих, весь твой гитхаб изучать все равно никто не будет, так как на это нет времени.
187 1419702
>>19697
Спасибо
188 1419703
>>15604 (OP)

>У нас есть свои уроки по основам PHP, они собраны и выложены по адресу http://codedokode.github.io/phpbook


Кто интересно это все писал
189 1419704
>>19703
Ноунейм какой-то
190 1419705
>>15604 (OP)

> с формами, MVC, git, composer, JS,


А зачем php вообще нужен если учить JS? разве Дс не может полностью заменить php?
191 1419706
>>19705
Ловите зумерка.
192 1419709
>>19706
Ну расскажи, в чем я неправ
193 1419711
>>19634
Объекты более гибкие чем функции. Их понимать проще, описывать и сочетать. Тупо нагляднее получается.
194 1419712
>>19703
На Боброчане наверняка запилили. В их стиле.
195 1419713
>>19705

>разве Дс не может полностью заменить php


Ассемблер может заменить и то и другое.
Вкатывайся в ассемблер.
А лучше вообще сразу байт-код ебаш паяльником.
196 1419759
https://pikabu.ru/page/interview/jobseeker/?t=backend2

Пизда блять, я себя дауном чувствую
197 1419816
>>19588

>>Не понимаю, что ты там велосипедить собрался.


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

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

Скажи, у тебя есть примеры простого приложения на ноде с MVC паттерном? Потому что пока что в express все похоже на сильно модифицированное if..else, пусть и с вызовом контроллера.
198 1419817
>>19713

>байт-код


>не машинный


Виртуальным паяльником?
199 1419854
>>19713
Очень смешно, я ведь серьезно спросил
200 1419861
>>19854
Ты хуйню спросил. Ответили тебе ровно тем же - пиши на ассемблере, ведь он и пхп и жс заменить может. Что тебе не понятно?
201 1419866
пхп не нужен
202 1419867
>>19866
Не пхп, а ПИ ЭЙЧ ПИ.
203 1419888
>>19866
Всё, аноны, сворачиваемся - анон сказал, что пхп не нужен. Закрываем лавочку.
204 1419894
>>19888
для новых проектов
205 1419895
>>19894

>пук


Ясно.
206 1419896
>>19894
двачую этого
207 1419898
>>19894

>кудахтахтах

208 1419902
как в ларавеле заполнить таблицу данными?
209 1419909
Хочу погрузиться в жавускрипт с головой, но у меня всё желание отбивает местная фронтентд-гопота. Создаётся ощущение, что ЦА этого языка - токсичные школьники и прочий залётный ИТ-скам на хайпе.
Это неправильно всё конечно, но интерес здорово убивает.
210 1419910
>>19902
блять чел реально помощи просит, он еще молод и глуп и не видал таких залуп, ептя..ну ответить че переломишься?Себя сначала вспомни как ты начинал, или ты прям с пеленок супер пупер кодером был? ага вставил дискетку в лоб с надписью ООЛ и все охереный сец
211 1419911
>>19910
ты не ошибся постом?
212 1419912
>>19911
нет
213 1419918
>>19910
Гуглить учись.
214 1419919
>>19918
ты хауди хо пересмотрел что ли? лечись
215 1419923
>>19919
Тебе тут никто ничего расжёвывать не будет, пионер. Тем более такому наглому говну как ты.
Если ты этого ждал, то можешь выкатиться из треда вместе со своим говноблоггером.
216 1419924
>>19923
наглое говно это ты и твой дружок хауди хо, которые на малейшую просьбу о помощи обкладывают хуями и посылают в гугл
но вообще пардон, меня настолько взбесили эти слова нашет "нафиг не спрашивай у меня, матерого программера, вон, гуглить учись" что я автоматом выдал на гора, сам не понял как это у меня получилось..мдя, а в школе вроде 4 по дойчу стояла, а тут прям как чистый берлинец выдал, сам в шоке.
217 1419926
>>19924

>посылают в гугл


Первое, что учиться любой айтишник, будь то хоть хелпдеском, хоть админом, хоть кодером - ходить в гугл.
Иди в гугл и не задавай тупых вопросов в ИТТ треде.
218 1419928
>>19924
У Ларавеля отличная документация. Ты от треда чего вообще хочешь? Сходи и сам почитай.
219 1419929
>>19928
я бы не сказал,что его док охуенно подходит новичку
220 1419933
>>19929
Значит тебе ещё рано такие вещи трогать.
О том тебе и говорять - расжёвывать никто не будет. Самому к этому идти надо.
15328630530290.png234 Кб, 512x512
221 1419934
>>19933

>Это тред и для начинающих

222 1419936
>>19934
Ларавель не для начинающих.
Учи шапку треда - по ней тебе ответят.
223 1419937
>>19936
ты мне предлагаешь начать с говно слима,там доки вообще пиздец
224 1419939
>>19937
Откуда тебе знать какая там документация, если ты в ней не разбираешься?
Учи матчасть и не выёбывайся.
225 1419940
>>19939
ебать у тебя ЧСВ
226 1419942
>>19940
Сообщество кодеров вообще очень токсичное.
227 1419948
>>19940
Ты не вкатишься.
228 1419949
>>19940
Пришёл васян - расскажите ему быстро как работать с базами на Ларе. Сам не знает нихуя и учить не хочет. Бросается говном в очевидные советы.
Ну ты и дно, дружок.
229 1419951
>>19949
Петрович, ты?
14813168187240.jpg50 Кб, 500x500
230 1419953
няши,с чего такой бугурт?нужно быть добрее и поставить неофита на путь истинный...человеку нужно помоч...
231 1419954
>>19953

>нужно быть добрее


>человеку нужно помоч


Кому?
Мне не нужно.
Тебе нужно - ты и помогай.
232 1419963
>>19954
пхп плохо знаю,не мое направление
233 1419964
>>19963

>пхп плохо знаю


Малаца, все правильно делаешь.
234 1419985
Поэтому я предлагаю банить школьников - пускай в ридонли посидят. Иначе бессмысленный срач разводят.
235 1419987
>>19985
Это не развод срача, это повышение скорости постинга.
Чекай, наш тред в топе.
236 1419993
>>19985

>я предлагаю банить школьников


Лучше ебать - а они и не против :3
237 1420003
так все таки,читать раздел сидинг?
238 1420189
Что с тредом случилось? Зачем вы этому жирному говну отвечаете?
239 1420190
>>15604 (OP)
ОП, просмотри список студентов пожалуйста
https://github.com/Leorne/student-list
240 1420204
>>19816

> Еще мне импонирует что нода - это отдельное приложение, которое существует в памяти, а пхп это просто последовательность скриптов.



Одной ноды для реального приложения недостаточно. Обычно запросы принимает какой-нибудь веб-сервер вроде nginx и проксирует на ноду. Через nginx настраивается HTTPs, отдача статики, сжатие, кеширование. Я ещё настраивал ограничения для разных стран по IP на основе GeoIP. Сама нода запускается через какой-нибудь process manager вроде PM2, чтобы контролировать количество запущенных процессов, перезапускать приложение если какие-то процессы отъедают много памяти. При локальной разработке PM2 удобно использовать для автоматического перезапуска приложения после изменений в файлах. Не будешь же ты после каждого изменения в коде перезапускать сервер? В PHP всё это не нужно, из-за его stateless модели.
В итоге связка Node + Nginx + PM2 не особо удобнее PHP + Nginx + PHP-FPM. В PHP тоже есть встроенный веб-сервер для разработки: https://www.php.net/manual/en/features.commandline.webserver.php

> примеры простого приложения на ноде с MVC паттерном


Будет тоже самое, что и на PHP: https://github.com/codedokode/pasta/blob/master/arch/mvc.md#пример-mvc-приложения
241 1420252
Сап, пэхапешники. Делаю курсач. Вопрос такой: есть база данных, в ней таблица с изображениями это требование курсача, как и использование ms sql. Грузятся они туда норм, через пхп, а выгружаются - нет, только частично. https://pastebin.com/NfyXVwxs - скрипт выдачи изображения. Пикрил структура базы и размер изображений при выгрузке через php и node.js (под нодой все хорошо). Это какое-то ограничение mssql_fetch_row? Почему это не гуглится?
242 1420261
>>20252
Разве хранят файлы в базе? Не проще их на диск складывать, а в базу только имена посылать?
243 1420262
>>20261
Я понимаю, что это не лучшая практика.

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


А на словах препод сказал, что хранить надо изображения
244 1420265
>>20262
Где курсы-то проходишь? Бесплатно надеюсь?
245 1420266
>>20262

>препод сказал, что хранить надо изображения


База Данных оптимизирована на работу с данными, а файловая система сервера, внезапно, на работу с файлами.
Ты неправильно инструменты используешь, отсюда и твои проблемы.
246 1420267
>>20265
Вышка в регионе, бюджет, 2 курс
247 1420268
>>20266
Так это вообще реально обойти или проще ограничить максимальный размер файла миллионом байт и забить?
248 1420270
>>20268
Хз я с таким извращением не встречался. Ищи в доках.
249 1420271
>>20267
Преподов, наверное, набирали как положено - что с вышкой был, и на зарплату 15 тысяч.
250 1420282
>>20190
Очень красивый, стройный код

мимопроходил
251 1420298
>>15604 (OP)
Изящнейшее решение задачи про таблицу умножения.
Покажу своим друганам - они обзавидуются.
252 1420300
>>20252
Крч, мало ли кому интересно. Почему есть ограничение в миллион байт я так и не нашел и решил проблему разбиением картинки на части и отправкой по частям через хранимую процедуру.
253 1420359
>>20252
У меня была похожая проблема с системой скуд, не мог целиком вытянуть из её базы картинки.
Что именно я тогда сделал не помню, но скорее всего тебе подойдет то что я нашел по первой ссылке на SO в гугле по запросу "mssql partial image":
mssql_query('SET TEXTSIZE 10000000'); // число в байтах нужно подбирать под твой ожидаемый размер картинок, который так или иначе должен быть ограничен твоими скриптами

И да тебе верно подсказывают что так делать _не_правильно_
254 1420372
>>20300

>мало ли кому интересно


Мне любопытно было.
255 1420374
Саблайм — неплохой редактор, чтобы открыть любой код на любом языке и просмотреть его, мб немного подправить и даже неплохой инструмент для верстки, но вот когда необходимо сделать реальный проект...необходимы инструменты несколько другого уровня. В теории, можно использовать блокнот/саблайм для написания кода на java, но это станет в конечном итоге адом)
Среда разработки — это...среда) Название говорит само за себя. В ней есть все, что нужно + большие возможности кастомизации. Среда сама проверяет твой код, говорит замечания по кодстайлу (можно создать самому или скачать какой-то стандарт), говорит замечания по избыточности, деплоит на сервер, имеет отладчик и дебагер, удобную визуализацию систем контроля версий...и очень много другого в одной программе с единой четкой логикой) Приходить к среде нужно тогда, когда начинаешь понимать, что хочется чего-то большего. Если саблайм кажется идеальным, то пока что не стоит его менять, как мне кажется. Это должно прийти со временем.
Все сказанное выше — чисто ИМХО и может быть ошибочным)
256 1420375
>>20374
Надо ещё учесть, что профессиональные инструменты не бесплатны. Разве что студентам дают, но толку от этого, да и студенты у нас, вон, файлы целиком из базы тянут. С таким обучением никакая среда не спасёт.
Остальные - не студенты и нужно ебаться с кряками-мокрописьками.
Лучше уже фришные ИДЕ тогда.
257 1420377
>>20375
Молоток тоже денег стоит. Давайте будем гвозди забивать фришным булыжником!
orig.jpg45 Кб, 736x736
258 1420379
>>20375

>Надо ещё учесть, что профессиональные инструменты не бесплатны.

259 1420383
>>20375

>Надо ещё учесть, что профессиональные инструменты не бесплатны.


В чем твоя проблема?
260 1420456
>>20190
Очень слабое ООП. Объекты ради объектов, процедурщина на статических классах. Больше по теме читай.

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

Форматирование кода - где есть, где слетело.

Схалтурил по архитектуре неслабо - многое проигнорировал. На выходе приложение скорее напоминающее Вордпресс, чем хоть какой-то фреймворк.
261 1420459
>>20298

Писать HTML внутри echo очень неудобно. Советую освоить операторы с двоеточием и маркер <?=. Почитай урок https://github.com/codedokode/pasta/blob/master/php/templates.md и может быть это поможет тебе сделать код еще аккуратнее.
15073279724903.png405 Кб, 604x453
262 1420461
>>20459
Спасибо, пошел читать.
263 1420510
>>20459
Да ты что советуешь-то? Инлайн пхп депрекейтед. Почитай стандарты. Шаблонизаторы и только. Инлайн код залупа полная.
264 1420513
>>20510

>Инлайн пхп депрекейтед


Пруфца бы.
265 1420524
>>20513
Читай psr-2.
266 1420528
>>20524
Найс тролишь, братиш
267 1420532
>>20528
В чём троллинг? Конструкция <?= применима если только в шаблонизаторе. Стандарт явно использовать только <?php и <? теги.
268 1420535
Написал функции count и array_values.
Вроде все выполняется, но меня смущает, что я воткнул в первый цикл какую-то левую переменную $k, чтобы foreach работал. Наверняка есть какой-то хитрый способ обойтись без нее.
ЧЯДНТ?
https://ideone.com/NHXec4
269 1420569
>>20532
Если бы там еще что-то подобное было написано.
270 1420603
>>20524
Выдержку приведи со сслыкой.
А пока - безпруфный вскукарек.
271 1420633
>>20535
$data[] = $k = $v;

Нахуя?
272 1420682
>>20510

Это и есть встроенный в PHP шаблонизатор. Ты бы на исходный код посмотрел. Для вывода таблицы умножения не требуется устанавливать фреймворк.
273 1420692
>>20456

>процедурщина на статических классах


Понял

>Объекты ради объектов


Вообще не понял. Я вроде пытался обьекты лишние не плодить

>Но как-то перебор их писать в очевидных местах


Пытался упросить ревью кода, чтобы анонов не напрягать особо.

>Схалтурил по архитектуре неслабо - многое проигнорировал.


В чем схалтурил? Я почитал на гите, хабре статьи, посмотрел урок на ютюбе. Сделал как написано, разделил на Модель, Вид, Контроллер. У каждой страницы своя модель, свой контроллер и html шаблон. Так же есть роутер и фронт контроллер. Что еще реализовать то нужно было?
274 1420751
>>20633
Хуй знает.
Пойду думать, как это исправить.
275 1420769
>>20535
>>20633
>>20751
Лол. Долго до меня доходило. А надо было всего лишь еще раз прочитать описание функции.
https://ideone.com/7cGGIj
276 1420799
>>20682
Но ведь для вывода таблицы умножения и инлайн рнр код не нужно использовать.

Инлайн рнр бэд практис. Запомните это. Где-то в своих проектах для себя вы безусловно вольны использовать, что вашей душе угодно.
277 1420803
>>20799

> Инлайн рнр бэд практис. Запомните это.


Звучит аргументировано.
278 1420804
>>20803
Я выше писал уже. Читайте psr-2. Там всё сказано.
279 1420805
>>20804
Это вчера было найс троллингом. Сегодня это просто тупость.
280 1420806
>>20805
Ok. Я умываю руки.
281 1420886
>>20804

>Читайте psr-2


Ты сам его не читал.
282 1420892
за что это отвечает?Route::resource()
283 1421010
>>20769
foreach ($arr as $k => $v)

$k ты не используешь, так что можно оставить просто

foreach ($arr as $v)

Поправьте если ошибаюсь
284 1421018
>>20535

>Написал функции count и array_values


Зачем?
285 1421022
>>21010
Ну да, ты прав, ответ тот же самый получился. Спасибо.
https://ideone.com/t5YRa7

>>21018
Чтобы научиться писать собственные функции. Прохожу слитый курс от WebForMySelf.
imagine.jpg40 Кб, 368x604
286 1421178
$kek = 'Привет, мир!';
echo strlen($kek) / 2;
287 1421190
>>21178
Для кирилицы надо использовать mb_strlen
yoba.png191 Кб, 512x512
288 1421257
>>21190
Первый пошел.
289 1421536
Так, ну-ка быстро взяли меня работать за еду! Реще блеать!
mcrYwpbliZM.jpg127 Кб, 768x576
290 1421620
Анончик спасай. Завтра иду на собес, где можно коротко и ясно почитать про ООП, чтоб сумечь отбиться по вопросам ООП.
Знаю, только что это классы ,с помошю которых можно строить структурированные данные , внутри которых всякие плюшки, функции. А потом это все передавать как объект. Знаю ,что это удобно, знаю синтаксис (не оч хорошо).
Ну или своими словами скажите, плиз. С меня тонны нефти (красивые картиночки)
291 1421621
>>21620
И вот такие еще вопросы

-общее понимание шаблонов проектирования
-общее понимание типов архитектур программных решений (десктоп, клиент-сервер, многозвенные)
Я конечно понимаю суть этих вопросов, но мне кажется что будут задавать формальные вопросы с названиями таких шаблонов. А я не читал книжек по типу "паттерны проэктирования"
292 1421720
Скажите, почему считается, что у php низкий потолок? Зарплаты у сеньоров примерно такие же, как и у других языков.
293 1421728
>>21720
Наверное из-за индусов. Стало дофига кодеров маленького и среднего уровня. Они естественно стали меньше получать.
А сеньеров никогда небыло много, они в любом языке стоят дорого
294 1421741
в 2019г пхп применяется для стартапов?
295 1421746
>>21741
Что за сратапы? Он применяется только криворукими заднеприводными ("backend") обезьянами для своих говносайтиков.
sage 296 1421751
>>21746
Говноед, ты?
297 1421825
>>21746
сайты сложнее бложика
298 1421957
Для фриланса (в стиле "я, я, можно я, можно я сделаю Вам это за 100 рублей или вообще бесплатно?!" или удалёнки (несбыточная мечта) в 2k19 году пэхэпэ с его традиционными причиндалами оптимальный вариант или стоит рассмотреть другие варианты?
299 1421976
>>21621

>-общее понимание шаблонов проектирования


Их только при хорошем понимании самого ООП можно разбирать. И вообще - смотри в википедии.

--общее понимание типов архитектур программных решений (десктоп, клиент-сервер, многозвенные)
Губу закатай.

>будут задавать формальные вопросы


Нет, не формальные - тебя на знание стека будут проверять.
300 1421979
>>21746
>>21957
Здорово наверное быть унылым говном и вбрасывать толстоту там, где каждый знает больше тебя?
301 1421982
>>21979

>пыхыпыговноеды


>каждый знает


Лучшая шутка месяца, однозначно.
302 1422037
кроме легаси и говно визиток,его где нибудь еще используют?
303 1422038
>>21976

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


т.е?
304 1422042
305 1422052
>>22042
хуй на
306 1422096
<?php
echo intval(11, 8); //11
echo intval('11', 8); //9

Ананасий, объясни мне, пожалуйста, почему так происходит?

В обоих случаях ведь база 8, почему со строкой оно корректно себя ведёт, а в случае c числом принимает базу за 10?

При чём, это ведь не ошибка даже, в мануале так и есть!
307 1422102
>>22096

>в мануале так и есть!


Мануал надо целиком читать

>The base parameter has no effect unless the var parameter is a string.

308 1422103
>>22102
Да, Антон, спасибо, я просто привык, что после примеров уже нет смысла скроллить.
309 1422155
>>22102

>The base parameter has no effect unless the var parameter is a string.


АХАХАХАХАХАХА
Вот это, блядь, дизайн интерфейса!
Вот это, блядь, архитектура!
Ух, бля!
311 1422266
>>22179
У меня вполне серьезный вопрос:
а как обосновывается использование пхп в новом проекте?
Я могу понять, что если есть легаси, то никуда ты не денешься.
Но, вот, пожалте, надо сделать новую ебу. И принимается решение - будем делать на пхп.
Как это решение обосновывается?
Или теперь начальник-смузихлеб не ебет себе мозги такими вопросами, а просто отстегивает бабло?
312 1422280
>>22266
Стоимость. В вебе обычно подразумевается какая никакая поддержка проекта. Нужно вносить какие-то изменения, правки. Пхпешники стоят мало и их как говна. В любой момент можно задешево кого-то найти на проект. А если сделать на чем-то другом то можно натолкнуться на ситуацию когда придется отстегивать кучу бабла на дорогого специалиста. Любой разбирающийся в ситуации заказчик будет заказывать разроботку на пхп чтобы потом не ебаться с поиском специалистов для доработки/поддержки.

>>22096
Тут не совсем очевидный нюанс, который я не знаю как нормально объяснить. Смотри, когда у тебя есть число - 11 например - это число всегда будет одинацатью в любой системе исчисления. Но оно может по разному записываться. Одинадцать это всегда одинадцать, но оно по разному записано. Когда ты передаешь в функцию число - функция возвращает тебе это число - потому что одинадцать это всегда одинадцать. Но когда ты передаешь запись числа - тут уже зависит от переданой системы счисления. '11' это запись числа 3 в двоичной, запись девятки в восмеричной и т.п.
313 1422293
>>22280

>В вебе обычно подразумевается какая никакая поддержка проекта


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

Но спасибо за ответ.
314 1422315
>>22293
а чем это отличается от разраб на питоне?
315 1422335
>>22315
Например всем
316 1422458
>>22293
ну пажалуйста, ну выбери пхп!
317 1422471
>>22335
То есть все разработчики на Питоне разрабатывают одинаково хорошо? И там нельзя принципиально сделать через жопу?
318 1422477
>>20692
Бамп
Оп, пожалуйста
319 1422497
>>22471

>разработчики на Питоне разрабатывают одинаково хорошо?


На фоне пыхыпыдебилов (тебя) - именно так.
Впрочем, на таком фоне это несложно, хаха.
320 1422563

>Питонодебил кукарекает


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


>живтоне с разметкой пробелами кудахтает


Дальнейшее развитие нашего диалога будет заключаться в твоих кукареках НЕНУЖНА.

>>>1422266


Ну дай подумать.....
У тебя есть мощный инструмент для веб - разработки, проверенный временем, с кучей готовых и отлаженных библиотек на любой вкус, с развитым сообществом. Может быть, использовать его?
Эхо от сосания хуев долбоебами, которые повелись на Ruby, до сих пор слышно в интернете.
321 1422564
>>22563

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


Поподробней
322 1422567
аноны, подскажите пожалуйста по регулярке, где надо телефоны угадывать (https://regex101.com/r/qF7vT8/3)

я понимаю, что сначала может идти плюс или пробел (а может и не идти), потом цифра восемь или семь:

^[+\s][87]

а как мне написать "дальше идут десять цифр и возможные скобки, минусы и пробелы"?

^[+\s]
[87][0-9]{10}

как мне в последнюю часть к цифрам добавить "сколько угодно скобок, пробелов и минусов"?
323 1422568
>>22567
звездочка пропала
1.jpg28 Кб, 620x244
324 1422569
>>22567
вот так выглядит
325 1422578
>>22567

>[+\s]звезда


это съест любую комбинацию из пробельных и плюсов, типа " ++ +++++ +++ ", оно тебе надо?
326 1422588
>>22471
Зачем ты вообще на него внимание обращаешь? Пора бы привыкнуть, что регулярно тут дауны всякие залетают. Просто игнорируй их.
327 1422592
>>22477
Тебе же указали куда воевать, чего ещё хочешь? Репетиторов нам сюда не завезли. А жаль.
Learn-ruby-on-rails-in-bangalore1.png150 Кб, 800x500
328 1422601

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


всегда есть выбор
329 1422604
Знающий анон, а подскажи вопрос по регуляркам:
почему я не могу, например, банально сперва вырезать строковыми функциями все пробелы, скобки, минусы и тире, и после этого уже работать чисто с цифрами? Понятно, что урок с регулярками создан чтобы научиться в нем разбираться, но как дело на практике обстоит? В крупных организациях имеется ввиду. Есть хоть какой то прирост производительности/скорости загрузки, если поставить перед регуляркой строковую функцию с авто-заменой str_replace? Конкретные цифры. Без снобизма и демагогии аля "ну отцы так делали и нам завещали".
330 1422615
>>22604

>но как дело на практике обстоит?


Обычно регулярками не пользуются. Но какой из тебя программист, если ты шаблон строки накидать не можешь? Сегодня ты регулярки пропустил, а завтра половину ООП не осилил и забил, и не можешь найти работу, потому, что все отлично видят твой уровень.
331 1422621
>>22615
Понял, спасибо
332 1422623
>>22615

>Обычно регулярками не пользуются.


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

>этот тред с этими безмозглыми быдлодебилами (тобой)


>с развитым сообществом


Шутку понял.
Смешно.
334 1422638
>>22623
Ну как бы да - на разных проектах по разному может быть.
Правда, говорят, что они медленные и плохо читаются, поэтому лучше не увлекаться.
335 1422668
>>22638

>говорят, что они медленные


Насколько помню наоборот.
336 1422669
>>22629

>этот тред с этими безмозглыми быдлодебилами


>Спизданул даун с дипломом программиста перфокарт, сосат всем.

изображение.png499 Кб, 600x800
337 1422678
>>22669

>дипломом


>перфокарт


Унижаемый за тупость и в итоге вылетевший студентик ну совсем не палится.
time.jpg7 Кб, 245x64
338 1422711
>>22668
Пикрелейтед средняя разница на 100к сторках, на медленной машине.
Код тут https://ideone.com/CPVWDU
339 1422768
Пыханы, расскажите, в сторону какого алгоритма копать или как бы вы решили такую задачу:
Есть список компаний, нужно из всех названий сформировать группы компаний по похожести. Группы, где совпадают 3/4/5 и тд. слов из названия. Сначала я получу массив, где каждое значение это будет массив слов из названия компаний. Как потом эти массивы слов компоновать по пересечению значений?
340 1422773
>>22768
Гуглишь расстояние левенштейна и кластерный анализ. Строишь матрицу растояний между названиями и потом обрабатываешь каким-то методом кластеризации. Если тебе нужно именно по совпадающим словам то вместо растояний используешь количество не совпадающих слов в названиях, или что-то типа того.
341 1423012
Как пройти assert?

class JobSeeker {
public static function questClassSearch(): bool {
return someFunc(function (string $c): void {
someFunc(self::class, $c);
});
}
}

$s = new JobSeeker();
assert(
!class_exists('Foo')
&& !class_exists('Bar\Foo')
&& true === JobSeeker::questClassSearch()
&& class_exists('Foo')
&& class_exists('Bar\Foo')
);

Что должно быть на месте someFunc?
342 1423025
>>22768
Если тебе пофигу на оптимизацию, то алгоритм может быть следующим

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

Google => company1, company2
Google2 => company1, company2, company3
Google3 => company1, company2, company3
Google4 => company1, company2, company3
Google5 => company1, company2, company3, company4, company5

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

google_google2 => company1, company2
google4_google5 => company1, company2, company4, company5

И так далее, while пока длина ключа не будет совпадать c количеством слов в самом большом названии
343 1423069
>>22768
Получаешь массив из названий компаний.
Из него получаешь словарь из отдельных слов каждой компании, подсчитывая сколько встречается каждое слово.
У тебя получится словарь вида "слово:количество совпадений".
Сортируешь его по количеству совпадений в убывающем порядке.
Используя этот словарь распределяешь компании из первого массива по группам.
344 1423625
А почему в php принято переносить скобку в объявлении функции на новую строку, а во всех нормальных языках нет?
345 1423651
>>23625
Это стиль старых пердунов - "the one true brace style". Пошел из С. А так как пхп на С написан то наверное перетек и в сам пхп. Его еще в ядре линкса используют, например, так как тоже на С пишется.
346 1423736
>>23625

>а во всех нормальных языках нет?


Для меня читаемость кода выше с скобкой в новой строке
347 1423913
>>23736
Удвою. Хорошо видно объявление и последующий блок кода.
348 1423952
>>23736
Утрою.
349 1423999
>>23625

>а во всех нормальных языках нет


Зато в нормальных языках и функции и замыкания одинаково выглядят, а в ПХП объявление - с новой скобкой, замыкание - без.
350 1424068
>>23736
Очень дело вкуса. Для меня это говно просто проеб вертикальной строчки на хуйню.
351 1424091
>>23999
В нормальных языках и в php замыкания обозначают разные сущности.
352 1424191
возьмите работать, за любые деньги, с ооп знаком чет на симфони делал ну пж постараюсь быть полезным
353 1424206
когда речь идет про вкат в треде пхп советуют идти в джс, приходишь к ним кидают обратно сюда
354 1424217
>>24206
никто себе конкурентов не хочет. такие вкатывальщики сначала вопросы на дваче задают, а потом приходят к тебе на работу и начинают доёбывать вопросами уже в рабочее время.
355 1424295
>>24206
Окай. Иди нахуй.
Ты нигде не нужен.
356 1424319
>>23625
Кстати я уже начал встречать js таким же образом оформленный, именно в недавних компонентах/сниппетах
image.png176 Кб, 500x500
357 1424539
>>24206
Ты тупой.
358 1424560
>>24539
нет, не тупой
15086599129350.jpg389 Кб, 1000x1499
359 1424567
github.com/ta-tikoma/phpins
решил написать свой валидатор кода. раскритикуйте, на толкните на что нибудь умное?
- почему не phpmd - потому что слишком долгое время обработки.
360 1424584
>>24560
Ну тупенький значит.
Не от большого ума ты задаёшь незнакомым людям вопросы - на что въебать тебе последующие 5-10 лет.
361 1424610
>>24567
моар фоток.
362 1424670
учил php, через месяц уже получил работу лол
363 1424674
>>24670
Что выучил за месяц, что спрашивали? Какая зарплата?
364 1424718
>>24567

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

Ты разбираешь исходный код регулярками тут: https://github.com/ta-tikoma/phpins/blob/master/app/Validators/IDefinedThisVariable.php

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

// function x() {}
$s = 'function x() {}';

Также, твоя регулярка некорректно определяет границы заголовка функций, например:

function[^\(]+\(([^)]+)\)

Тут не учтено, что определение функции может содержать вложенные скобки:

function x($a = array())

Также, у тебя нет поддержки синтаксиса декомпозиции массивов:

[$a, $b] = [1, 2];

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

preg_match("/x/", "x", $m);

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

if ($a == f($b)) {
echo $x; // yes
}

превратится в: 'if', '(', '$a', '==', 'f', '(', '$b', ')', ')', '{', 'echo', '$x', ';', '}'

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

Для проведения лексического анализа в PHP есть готовые функции: https://php.net/manual/ru/book.tokenizer.php

Затем производится синтаксический анализ. Он берет список лексем и используя набор правил, воссоздает синтаксическое дерево (AST) исходного кода. Набор правил называется грамматикой, и он описывает все возможные конструкции, которые могут встретиться в коде. Грамматика описывает, как из неделимых кусочков (их еще называют терминалами) собираются сложные конструкции, а из них - еще более сложные.

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

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

конструкция if - это: токен if, за ним круглая скобка, за ней выражение, за ним круглая скобка, за ней фигурная, за ней команды, за ней закрывающая фигурная.

или, если записать это правило в Расширенной форме Бэкуса — Наура (EBNF):

if_construct = 'if', '(', expression, ')', '{', 'sentences', '}'

Здесь expression и sentences - это отсылки к правилам, описывающим из чего состоит выражение и набор команд. Выражение можно описать как-то так:

# От порядка записей зависит приоритет операторов
expression = function_call | multiplication | sum | comparison | variable-like | literal
function_call = indentifier, '(', [ parameter, { ",", parameter } ], ')'
multipication = expression, ( '*' | '/' ), expression
sum = expression, ( '+' | '-' ), expression
comparison = expression, ( '<', '>', '==', '===', '!=', '!==', '<=', '>=' ), expression
variable-like = array_element | variable
literal = string | number | boolean_constant

Вообще, конечно, правила PHP чуть сложнее, и они позволяют пропускать фигурные скобки, а также допускают операторы elseif/else, так что запись можно усложнить:

if_construct = 'if', '(', expression, ')', body, { 'elseif', '(', expression, ')', body }, [ 'else', body ]
body = '{', many_sentences, '}' | one_sentence

Если тебе не очень понятен синтаксис EBNF, то погугли. Кроме EBNF, есть еще другие формы записи грамматик: ABNF, BNF. Они есть в википедии. Но общая суть в том, что они описывают сборку сложных конструкций языка из более простых. Программа состоит из определений и команд, определения состоят из более мелких частей, и так до неделимых частей - терминалов.

Парсер, используя правила грамматики, разбирает исходный код и воссоздает синтаксическое дерево (дерево - это структура, состоящая из узлов, и у каждого узла могут быть дочерние узлы, и есть один главный корень, с которого начинается дерево). Корнем дерева тут будет "Программа". Внутри нее будут определения классов, функций, и блоки кода. Внутри функции будет список ее аргументов, и тело функции. Тело будет содержать команды, они могут содержать выражения и вложенные блоки кода, и так далее. Дерево будет выглядеть так:

Программа:
- Определение функции
-- Имя: f1
-- Аргументы:
--- Аргумент
---- Имя: $a
---- Тайп-хинт: int
---- Значение по умолчанию:
----- Константа класса: SomeClass::SOME_CONSTANT
-- Тело:
--- Приваивание:
---- Переменная: $a
---- Значение: 1

Парсер, который занимается синтаксическим разбором, писать не надо - есть готовые генераторы парсеров, которым достаточно дать грамматику языка на вход: PHP-Yacc, PHP-peg, Lemon-PHP.

То есть, тебе достаточно описать грамматику PHP и ты сможешь парсить исходный код в дерево AST. После чего ты уже можешь легко обходить его, искать там узлы определенного типа (например: функции) и внутри них анализировать использование переменных. Правда, описать грамматику PHP довольно сложно. Где взять полный набор правил? Они есть в исходном коде PHP:

https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y

Разработчики PHP использовали сишный генератор парсеров Bison и описали грамматику в нужной ему форме. Полистай файл, и ты увидишь там описание грамматики.

Также, разработчики Facebook пытались составить спецификацию PHP, но похоже, забросили ее: https://github.com/php/php-langspec/blob/a610388d637b67294925d3b1dbbc0a54b7d94428/spec/php-spec-draft.md

Но хорошая новость состоит в том, что и это делать не надо. Есть готовый парсер кода PHP: https://github.com/nikic/PHP-Parser

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

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

if (...) {
$a = 1;
}

$a = f($a);
echo $a;

Тут переменная $a может быть не определена, и это ошибка. А если мы напишем так:

if (...) {
$a = 1;

} else {
return;
}

$a = f($a);
echo $a;

То ошибки уже нет. Для анализа потока выполнения можно использовать преобразование кода в SSA-форму ( https://ru.wikipedia.org/wiki/SSA ). SSA = static single assignment - это когда значение переменной присваивается только в одной команде, а если в коде это делается несколько раз, то мы делаем несколько копий переменной, добавляя суффиксы ($a_1, $a_2 и тд).

Например, код:

$a = 1;
$a ++;
echo $a;

превращается в:

$a_1 = 1;
$a_2 = $a_1 + 1;
echo $a_2;

Если же переменная определяется внутри цикла или if, то мы используем конструкцию "Ф-функция", которая говорит о том, что переменная может получить одно из нескольких значений:

if (...) {
$a = 1;
} else {
$a = 2;
}

echo $a;

превращается в:

$a_1 = 1;
$a_2 = 2;
$a_3 = Ф($a_1, $a_2);
echo $a_3;

Ну и наконец, вот еще пример цикла:

$a = 1;
while ($a < 10) {
$a ++;
}

echo $a;

Он превратится в:

$a_1 = 1;
$a_2 = Ф($a_1, $a_2) + 1;
echo $a_2;

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

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

В общем. советую почитать и погуглить про:

- лексический анализ
- синтаксический анализ
- AST (abstract syntax tree)
- форма представления кода SSA
- формы записи грамматик BNF/ABNF/EBNF
- https://github.com/nikic/PHP-Parser

На первый взгляд это может выглядеть сложно, но работать с кодом в такой форме будет удобнее. Я когда-то пробовал написать простой анализатор кода для поиска ошибок, как раз на основе синтаксического анализа: https://github.com/codedokode/source-analyzer Там правда тоже есть регулярки, но есть и использование AST: https://github.com/codedokode/source-analyzer/blob/master/src/Common/TypeHintMissingChecker.php

Вообще, если бы ты мог написать преобразователь AST в SSA, это могло бы стать полезной отдельной библиотекой для анализа кода.

Если есть вопросы - задавай.
364 1424718
>>24567

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

Ты разбираешь исходный код регулярками тут: https://github.com/ta-tikoma/phpins/blob/master/app/Validators/IDefinedThisVariable.php

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

// function x() {}
$s = 'function x() {}';

Также, твоя регулярка некорректно определяет границы заголовка функций, например:

function[^\(]+\(([^)]+)\)

Тут не учтено, что определение функции может содержать вложенные скобки:

function x($a = array())

Также, у тебя нет поддержки синтаксиса декомпозиции массивов:

[$a, $b] = [1, 2];

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

preg_match("/x/", "x", $m);

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

if ($a == f($b)) {
echo $x; // yes
}

превратится в: 'if', '(', '$a', '==', 'f', '(', '$b', ')', ')', '{', 'echo', '$x', ';', '}'

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

Для проведения лексического анализа в PHP есть готовые функции: https://php.net/manual/ru/book.tokenizer.php

Затем производится синтаксический анализ. Он берет список лексем и используя набор правил, воссоздает синтаксическое дерево (AST) исходного кода. Набор правил называется грамматикой, и он описывает все возможные конструкции, которые могут встретиться в коде. Грамматика описывает, как из неделимых кусочков (их еще называют терминалами) собираются сложные конструкции, а из них - еще более сложные.

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

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

конструкция if - это: токен if, за ним круглая скобка, за ней выражение, за ним круглая скобка, за ней фигурная, за ней команды, за ней закрывающая фигурная.

или, если записать это правило в Расширенной форме Бэкуса — Наура (EBNF):

if_construct = 'if', '(', expression, ')', '{', 'sentences', '}'

Здесь expression и sentences - это отсылки к правилам, описывающим из чего состоит выражение и набор команд. Выражение можно описать как-то так:

# От порядка записей зависит приоритет операторов
expression = function_call | multiplication | sum | comparison | variable-like | literal
function_call = indentifier, '(', [ parameter, { ",", parameter } ], ')'
multipication = expression, ( '*' | '/' ), expression
sum = expression, ( '+' | '-' ), expression
comparison = expression, ( '<', '>', '==', '===', '!=', '!==', '<=', '>=' ), expression
variable-like = array_element | variable
literal = string | number | boolean_constant

Вообще, конечно, правила PHP чуть сложнее, и они позволяют пропускать фигурные скобки, а также допускают операторы elseif/else, так что запись можно усложнить:

if_construct = 'if', '(', expression, ')', body, { 'elseif', '(', expression, ')', body }, [ 'else', body ]
body = '{', many_sentences, '}' | one_sentence

Если тебе не очень понятен синтаксис EBNF, то погугли. Кроме EBNF, есть еще другие формы записи грамматик: ABNF, BNF. Они есть в википедии. Но общая суть в том, что они описывают сборку сложных конструкций языка из более простых. Программа состоит из определений и команд, определения состоят из более мелких частей, и так до неделимых частей - терминалов.

Парсер, используя правила грамматики, разбирает исходный код и воссоздает синтаксическое дерево (дерево - это структура, состоящая из узлов, и у каждого узла могут быть дочерние узлы, и есть один главный корень, с которого начинается дерево). Корнем дерева тут будет "Программа". Внутри нее будут определения классов, функций, и блоки кода. Внутри функции будет список ее аргументов, и тело функции. Тело будет содержать команды, они могут содержать выражения и вложенные блоки кода, и так далее. Дерево будет выглядеть так:

Программа:
- Определение функции
-- Имя: f1
-- Аргументы:
--- Аргумент
---- Имя: $a
---- Тайп-хинт: int
---- Значение по умолчанию:
----- Константа класса: SomeClass::SOME_CONSTANT
-- Тело:
--- Приваивание:
---- Переменная: $a
---- Значение: 1

Парсер, который занимается синтаксическим разбором, писать не надо - есть готовые генераторы парсеров, которым достаточно дать грамматику языка на вход: PHP-Yacc, PHP-peg, Lemon-PHP.

То есть, тебе достаточно описать грамматику PHP и ты сможешь парсить исходный код в дерево AST. После чего ты уже можешь легко обходить его, искать там узлы определенного типа (например: функции) и внутри них анализировать использование переменных. Правда, описать грамматику PHP довольно сложно. Где взять полный набор правил? Они есть в исходном коде PHP:

https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y

Разработчики PHP использовали сишный генератор парсеров Bison и описали грамматику в нужной ему форме. Полистай файл, и ты увидишь там описание грамматики.

Также, разработчики Facebook пытались составить спецификацию PHP, но похоже, забросили ее: https://github.com/php/php-langspec/blob/a610388d637b67294925d3b1dbbc0a54b7d94428/spec/php-spec-draft.md

Но хорошая новость состоит в том, что и это делать не надо. Есть готовый парсер кода PHP: https://github.com/nikic/PHP-Parser

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

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

if (...) {
$a = 1;
}

$a = f($a);
echo $a;

Тут переменная $a может быть не определена, и это ошибка. А если мы напишем так:

if (...) {
$a = 1;

} else {
return;
}

$a = f($a);
echo $a;

То ошибки уже нет. Для анализа потока выполнения можно использовать преобразование кода в SSA-форму ( https://ru.wikipedia.org/wiki/SSA ). SSA = static single assignment - это когда значение переменной присваивается только в одной команде, а если в коде это делается несколько раз, то мы делаем несколько копий переменной, добавляя суффиксы ($a_1, $a_2 и тд).

Например, код:

$a = 1;
$a ++;
echo $a;

превращается в:

$a_1 = 1;
$a_2 = $a_1 + 1;
echo $a_2;

Если же переменная определяется внутри цикла или if, то мы используем конструкцию "Ф-функция", которая говорит о том, что переменная может получить одно из нескольких значений:

if (...) {
$a = 1;
} else {
$a = 2;
}

echo $a;

превращается в:

$a_1 = 1;
$a_2 = 2;
$a_3 = Ф($a_1, $a_2);
echo $a_3;

Ну и наконец, вот еще пример цикла:

$a = 1;
while ($a < 10) {
$a ++;
}

echo $a;

Он превратится в:

$a_1 = 1;
$a_2 = Ф($a_1, $a_2) + 1;
echo $a_2;

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

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

В общем. советую почитать и погуглить про:

- лексический анализ
- синтаксический анализ
- AST (abstract syntax tree)
- форма представления кода SSA
- формы записи грамматик BNF/ABNF/EBNF
- https://github.com/nikic/PHP-Parser

На первый взгляд это может выглядеть сложно, но работать с кодом в такой форме будет удобнее. Я когда-то пробовал написать простой анализатор кода для поиска ошибок, как раз на основе синтаксического анализа: https://github.com/codedokode/source-analyzer Там правда тоже есть регулярки, но есть и использование AST: https://github.com/codedokode/source-analyzer/blob/master/src/Common/TypeHintMissingChecker.php

Вообще, если бы ты мог написать преобразователь AST в SSA, это могло бы стать полезной отдельной библиотекой для анализа кода.

Если есть вопросы - задавай.
365 1424791
>>24718
спасибо за столь подробный ответ.

>Это неправильно. Например, твой разборщик кода "увидит" функцию, даже если она закомментирована или находится внутри строкового литерала:


>


>// function x() {}


>$s = 'function x() {}';



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

> сишный генератор парсеров Bison


помню раньше тоже им баловался

> Есть готовый парсер кода PHP: https://github.com/nikic/PHP-Parser



в процессе подбора инструментов так же встречал эту библиотеку, но отмел её наверное из-за лени разбираться а оправдал себя тем что на регулярках быстрее отработает(введу их небольшого количества), но вероятно ты прав и стоит вернуться к ней. Основной целью ставил для себя именно быстроту выполнения - да бы при сохранении файла(а возможно и в процессе его написания) мгновенно видеть результат.
Хотел ввести и di чтоб ввести возможность автоподгрузки валидаторов как сторонних пакетов. но все суммарно упиралось в мысли на сколько мне это урежет скорость.
366 1424833
какой портрет пхп программиста?
367 1424837
>>24833
Рандомный как в дешевом хостеле
368 1424975
тест
369 1425006
>>24670
>>24610
>>24833
>>24975
Школодебил, ты?
Да, ты.
15411864672170.jpg83 Кб, 917x636
370 1425010
Как правильно интегрировать гитхаб с композером? Я загрузил туда либу, а композер говорит - не знаю таких. Делал compozer init на проекте.
371 1425018
>>25006
не знаю кто такой школодебил, но ответил на мои 2 сообщения
372 1425019
>>25018
Это ты, дебил мелкобуквенный.
Впрочем что от пхпдауна взять.
373 1425021
>>25019
нас тут двое кажется, я на c/c++ работаю ваще
374 1425024
>>25021

>я на c/c++ работаю


Вовсе нет, фантазер, ты слишком тупой.
375 1425028
>>25010
Проще всего создать ssh ключ и в composer.json

"repositories": [
{
"type": "git",
"url": "gitANUSgithu4OzbPUNCTUMcom:<nikname>/<projectname>.git"
}
],

"require": {
"<nikname>/<projectname>": "dev-master"
}
376 1425033
>>25028
Понял.
15372248589621.jpg68 Кб, 789x960
377 1425036
>>25028
Спасибо.
378 1425054
>>15604 (OP)
Кто-нибудь пояснит что конкретно делают эти точки, про них ничего нету в гайде, а без них код не выполняется??

> ТОЧКА $x $x ТОЧКА "\n\


<?php
for ($x=1; $x<=10; $x++ ){
echo "$x
$x=".$x*$x."\n";
}
380 1425059
>>25055
Спасибо, почитаю.
381 1425229
>>25220 (Del)
Там регуляркой ещё валидировать можно.
IMG3755.JPG35 Кб, 228x277
382 1425239
В году так 2011-2013 был хороший (на мой взгляд) сайт с уроками по азам PHP, там ещё девочки из Унылого учителя на бекграунде были и проект позиционировался как "от двачера для двачеров".
Там ещё была задача - написать генерацию броска игральной кости.
Он мёртв?
383 1425242
/test/
384 1425293
>>25239
Давай читать шапку вместе:

>С чего начать



У нас есть свои уроки по основам PHP, они собраны и выложены по адресу http://codedokode.github.io/phpbook (вас отредиректит на другой домен, не читайте, не сохраняйте, не запоминайте его, он временный). Это учебник для изучающих с нуля, то есть если ты вообще ничего не знаешь...
385 1425331
Пацаны мы лохи
386 1425387
Знающий аноня поясни пожалуйста:
делаю уроки про регулярки, конкретно - про исправление ошибок в предложении: поставить пробелы после запятых, точек, восклицательных знаков. Это все сделал через обычный preg_replace и ассоциативный массив правил. Но уперся в следующее "поменять маленькие буквы, с которых начинается предложение, на большие". Скажи, анон, я могу это сделать через чистый preg_replace? Получается только через preg_replace_callback, потому что надо возвращать mb_strtoupper.
Как мне сказать обычному preg_replacу "Подними пожалуйста $1 в верхний регистр"?
387 1425403
>>25387

Через preg_replace нельзя.
388 1425405
>>25331
почему?
389 1425416
>>25403
Спасибо
390 1425530
Апач внезапно перестал понимать свой .htaccess.
Вчера ещё всё нормально работало, на хостинге тоже всё отлично, а на локальной машине - хттп еррор 500. Ни копию с хостинга не берёт, ни старую свою.

Ну что за параша?
391 1425609
>>25530
Убедись что ошибка именно там, а не в коком-то скрипте (заменяй их на пустые файлы где возможно).
392 1425631
>>25609
Я на чистую софт переустановил и всё заработало как надо. Хз что это было.
393 1425828
>>25631
Короче, я затёр свои неймспейсы в конфиге композера пока пушил и разбирался.
Я идиот.
394 1426111
>>25836 (Del)
Давааай
395 1426113
40к ЗП в рашке, для человека с 2годами опыта работы и овер 5 годами запиливания сайтиков для себя. Это зашквар? Стоит ли увольняться?
396 1426116
>>26113
ну ищи другое место работы
397 1426137
>>26116
Сколько норма?
398 1426142
>>26137
На сколько возьмут.
399 1426149
>>26113
Анону без опыта работы, с парой самопильных проектов "для себя" и хорошим знанием laravel/doctrine паттернов, предлагали от 55 до 65 в Питере.
400 1426388
>>26149
oh shit
401 1426444
function fn ($param = "default", $two = "2") {
echo $param;
echo $two;
}

fn("???");

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

В JS вроде как есть undefined, если его передать в качестве аргумента, то используется дефолтный. А как быть в PHP, если функция с двумя аргументами и я хочу указать второй, а у первого использовать дефолтное значение?

Ставить дефолтом null и самостоятельно городить if (is_null())?
402 1426449
>>26444
Если неясно выразился, уточню. Что мне нужно написать, чтобы вывелось default3? Конечно же, вариант fn("default", "3"); не предлагать. Неужели единственный вариант

if (is_null($param)) {$param = "default"}

и передавать null?
403 1426465
>>26449
$param = $param ?? 'default' ?
404 1426467
>>26449
А, блядь, ну так ты всё правильно сделал.

public function __construct($display_errors = 1, $error_reporting = E_ALL) {
$this->display_errors = $display_errors;
$this->error_reporting = $error_reporting;
}

Если я в конструктор нихуя не передам - создастся с этими значениями по умолчанию. Просто нихуя не делай и всё
405 1426471
>>26149
Я из мухосрани. Но работаю удаленно. Хз в питере я бы ниже 80 даже не рассматривал наверное. Даже 80 - дно, это так перебиться
406 1426485
>>26449
Проверять на null не самая лучшая мысль т.к. нуль это по своему тоже значение.
Может быть ситуация где дефолтное значение нуль, а пользователь твоего апи хочет давать не нуль а именно положиться на дефолтный вариант.

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

Другой вариант использовать dto + builder (опционально fluid interface) в качестве аргумента твоей функции, обязательные параметры требуешь в конструкторе, необязательные чекать через isSet (внутри dto придется хранить флаги).

В качестве финальной альтернативы пересмотри свой подход и подумай действительно ли тебе необходим подобный опциональный аргумент не в хвосте их списка (как ты понимаешь в хвосте можно иметь настоящие опциональные аргументы). Возможно, твой подход к построению апи не самый прозрачный и пользоваться им будет неудобно.
407 1426498
>>26449
fn(); //default3
fn(, '23'); //23

не еби мозги ни себе ни людям
408 1426568
>>26498

>fn(, '23'); //23



А не пиздите ли вы часом, молодой человек? Моя IDE говорит, что в этой строке ошибка и , не может идти после нихуя.
409 1426591
>>26485
Не обязательно использовать null. Можно условиться, что "FUCKIN_DEFAULT_VALUE" - магическое слово для подстановки дефолтного значения. Хоть класс под это дело сделать можно. Просто мне кажется это странным: в js я могу сделать fn(undefined, undefined, true, false). В PHP - нет.

Суть там в следующем. Есть класс c1, в нём метод c1m с 4 параметрами: tA, tB, f1, f2. Этот метод не имеет абсолютно никакого смысла без указания tA и tB, поэтому им заданы стандартные значения прямо в методе c1m.

При этом, есть класс c0. Сейчас положение дел таково, что c0 будто "родительский" (РЕЧЬ НЕ О НАСЛЕДОВАНИИ) класс для c1. Если говорить прямо: c0 - список сообщений, c1 - непосредственно сообщение.

То есть, внутри c0 находится массив с кучей объектов класса c1.

При этом, c0 имеет метод, который дёргает у каждого объекта c1 метод c1m. И весьма ожидаема ситуация, в которой пользователь захочет изменить значение tB, но оставить дефолтное tA. Спрашивается, как быть?

Я могу перенести объявление стандартных значений из метода c1m в класс c0. Тогда я смогу сделать так: c1m (a1, a2, a3, a4). Изначально в a1 лежит дефолтное значение tA, в a2 tB и т. д. Соответственно, если кто-то хочет заменить tB, достаточно просто изменить a2, а a1 оставить как было.

Но мне не кажется это хорошей идеей. Ведь, повторюсь, метод c1m не имеет смысла без указания tA и tB. Значит если так случится, что c1->c1m попробуют вызвать откуда либо кроме c0 - дефолтных параметров не будет.

Сейчас я остановился на дублировании. То есть:

1. Дефолтные tA, tB, f1, f2 указаны в объявлении c1m
2. В c0 заданы a1, a2, a3, a4 с теми же самыми дефолтными значениями, c1m вызывается как c1m(a1, a2, a3, a4). Соответственно, если мы хотим изменить tB, а остальное оставить дефолтом - меняем свойство a2 в классе c0.

Но это явно кривое решение. Ведь мы не в самом деле используем дефолтные значения, а просто дублируем их.
410 1426617
>>26444

Обычно необязательные аргументы просто указывают в конце. Какого-то специального способа нету.
411 1426621
>>26591

Опции в PHP обычно делают через массив:

function x($a, $b, array $options = [])

В твоем случае это именно опции.
412 1426706
Котаны, суть поясните за smtp сервер. Есть у меня сайт, хочу почту отправлять. Я компосером загрузил phpMailer - это и есть smtp - сервер? С него могу миллионы в день писем отправлять Элону Маску Ольге Бузовой?
413 1426711
>>26149
Складывается ощущение что ЗП больше зависит от того на сколько программист подскакивает кабанчиком, а не от скилла в известных пределах.
414 1426716
>>26711

Звучит как оправдание. А не в том ли проблема, что некоторые программисты слишком увлекаются изобретением архитектур и лишним прилизыванием кода вместо быстрого выполнения задач бизнеса?
415 1426751
>>26640 (Del)
Поэтому бэк интереснее.
416 1426855
>>26706
PHPMailer - библиотека для PHP, которая умеет отправлять письма как через SMTP, так и через mail(). Например, у меня в одном проекте было так: создаётся объект PHPMailer, в него выставляются все настройки, кроме метода отправки. А дальше ставится email, если не отправилось - SMTP (чтобы лишний раз не грузить SMTP сервер, но и слишком полагаться на mail() тоже не стоит).

SMTP - протокол для передачи почты. Соответственно, SMTP-сервер - почтовый сервер, который поддерживает SMTP (ни разу не встречал публичный сервер, который не поддерживал бы).

Дефолтные почтовики (yandex, gmail, mail) имеют свои SMTP-сервера. То есть, для отправки почты через свой скрипт ты можешь завести почту на яндексе и слать письма через их SMTP-сервер. Единственное что: иногда они выёбываются и закрывают доступ свежерегам, но это легко решается. Просто пишешь в поддержку письмо, дескать так и так, я использую эту почту для отправки заказов с сайта на свой ящик (или что там у тебя), розбаньте.

Разумеется, бесплатные сервера имеют кучу ограничений. Если у тебя дай бог сотня писем в день - ты с ними не столкнёшься. Но если собираешься строчить по 10 писем в минуту, то, скорее всего, тебя попросят.

Повторюсь, SMTP - протокол. Этот же самый протокол используется в почтовых клиентах. То есть, яндекс не видит особой разницы между PHPMailer и thunderbird (ну, конечно, может вычислить по ip/заголовкам и т. д, но сейчас речь не об этом).

Еще для отправки писем есть такие писечки https://www.mailgun.com/pricing
417 1426856
>>26855
Чёт не дописалось немного. Писечка эта бесплатна, если меньше 10k писем и меньше 100 получателей в месяц вроде как.
418 1426895
>>26855
Для себя подведу итог : smtp - протокол.
PHPMailer - реализация этого стандарта - то есть самодостаточный smtp-сервер, с него могу отправлять тыщи писем Бузовой.
Но так же я могу воспользоваться публичными серверами или же smtp - серверами, которые ставятся как отдельное ПО на мой сервер, но мне это не нужно, потому что есть у меня PHPMailer.
Я все правильно понял?
Это я сам для себя разжевываю что бы понимать .
419 1426973
>>26895
Начнём с того, что я сам не весь из себя знаток данного вопроса, поэтому в деталях могу что-то напутать. Но всё же

>smtp - протокол


Верно. Даже в википедии об этом написано.

>PHPMailer - реализация этого стандарта


Можно сказать и так, но

>то есть самодостаточный smtp-сервер


НЕТ.

Приведу простую аналогию. Твой браузер работает по протоколу HTTP. Можно сказать, что в браузер - реализация HTTP (ну, по крайней мере, браузер умеет его читать и понимать). Значит ли это, что твой хром - веб-сервер? Нет.

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

Если у тебя шаред-хостинг, то там, как правило, всё уже настроено и ты можешь отправлять письма через функцию mail. Насчёт неё я подробностей не знаю: в linux она дёргает sendmail, как в windows работает хз.

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

Вообще, почта - тема относительно сложная. Настроить веб-сервер - элементарно, а вот правильно настроить почтовый сервер - так еще задача. Поэтому либо используй mail(), если есть возможность, либо чужой SMTP. Ну, либо гугл в зубы и учись настраивать-админстрировать почтовые сервера.
420 1426974
>>26895
Даже в описании либы написано:

>Integrated SMTP support - send without a local mail server

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

С 4к и 40к вроде работает нормально, но если ставить 1к, как в примере, то всё идёт по пизде.
Так же последний месяц не считает, а дублирует.

ссылка https://ideone.com/04Pa5z
Хо решения правильный или я совсем хуйню сделал?
422 1427086
Тут такое дело, получал по студенческой лицухе phpstorm и не только, регал почтовый адрес в сакраменто колледж, на данный момент эту хрень прикрыли со стороны jetbrains, как теперь получить через студенческую лицензию подписку, кто знает?
423 1427114
>>26985
Анон, я сам новичок, но ты все правильно и красиво сделал. Единственно что - у тебя нижняя проверка, где

>если баланс отрицательный - хватит считать


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

>Подсказка: код, который дан как образец, содержит намеренно внесенные ошибки.



вот например
https://pastebin.com/gRj4H8MX
424 1427125
>>26974

>>Integrated SMTP support - send without a local mail server



То есть PHPmailer самостоятельно может формировать согласно протоколу smtp и отправлять письма, но если винда ( в ней с помощью mail() нельзя отправить по дефолту) и нет локального smtp -сервера то отправить не сможет. Либо цепляться к smtp -серверу (локальному или в сети), и уже сервер отправляет/принимает письма.
Так?
14212597293923.jpg19 Кб, 388x399
425 1427142
Нахуя вы изучаете похапэ? Работы нихуя нет. Никому эта копрофилия в 2к19 не нужна. Пишут на чем угодно, только не на пхп. И причем уже года 4 как.
На дот нете, на жабе, на жоэс, даже на питоне че-то там пишут, но пых мертв.
Работы нет
426 1427145
>>27142
но ведь 70% веба на пых-пыхе
427 1427148
>>27145
Ты бы вакансиями пруфнул
428 1427161
>>27160 (Del)

>выпук безработной маньки

429 1427166
>>27142
прям как руби
430 1427170
>>27166

>руби


Последний раз слышал про эти засохшие сопли в 2014
431 1427172
>>27170
а он жив
432 1427173
>>27172
Ага, прям как цой или кобол
433 1427176
>>27086
Крякни да и все, что как маленький-то. Заработаешь копейку с помощью шторма - купишь лицензию, все по-честному. Вообще это оффтоп, соре
434 1427177
>>27173
в Швятой живее всех
435 1427179
>>27171 (Del)
Лёха, успокойся
436 1427182
>>27174 (Del)

>заебали, сил нет


Одевайся, деньги на тумбочке.
437 1427238
>>27176
Нет, крякать не буду, это гавно.
438 1427250
>>27237 (Del)
Ты старый, видимо?
439 1427258
>>27253 (Del)
До 40 лет ето юноша?
440 1427263
>>27261 (Del)
<20?
Ну тогда странно, мб просто не твоё
441 1427264
>>27237 (Del)
Я тоже не могу решить задачи, очень сложно идет.
442 1427266
>>27261 (Del)
>>27264
Два дебила - это сила.
А потом местные дурачки удивляются почему это сложилось мнение что пыхыпы для олигофренов.
Вот именно поэтому.
443 1427283
>>27267 (Del)

>Ты сходу все задачи решал?


Точно так.
Еще дебильные вопросы будут?
tupoyvopros.png62 Кб, 767x301
444 1427289
Объясните тупому, как должно выглядеть решение этой задачки, только начал а уже обосрался.
445 1427291
>>27289
Ты троллишь щас?
446 1427294
>>27289
>>27291
>>27292 (Del)
Даже не знаю кто из вас тупее.
Оба хуже.
447 1427310
>>27291
Нет, не тролю, рили не понел, что нужно сделать. Полагаю задать диапазон от 1 к 6 (задача на выпадения кубика). Но как это сделать не ебу.

>>27292 (Del)
Вашу шутку я оценил.
448 1427350
Поглядите, долбоёб мало того что в рандом не умеет - так ещё и не понимает как сага работает, кек
449 1427362
БУМП
450 1427372
>>27142
Иди на node.js напиши.А мы посмотрим как тебя асинхронность и промисы в жопу выебут. А в рот тебя выебет модуль http.
451 1427394
за что отвечает папка модель во фреймворках?
452 1427409
>>15604 (OP)
ОП, я студентов сделал.
Взгляни пж https://github.com/pinky03/Student-List
453 1427418
>>27394
я сам на ноде с рубой пишу, но скорее всего - за работу с базами данных. Но это у нас - у королей
454 1427736
>>27409
Ёбаный пиздец.
455 1427740
>>27409
switch ($order) {
case 'id':
$result .= 'id';
break;
case 'name':
$result .= 'name';
break;
case 'surname':
$result .= 'surname';
break;
case 'group':
$result .= '`group`';
break;
case 'mail':
$result .= 'mail';
break;
case 'rate':
$result .= 'rate DESC';
break;
case 'year':
$result .= 'year';
break;
case 'city':
$result .= 'city';
break;

Или пиздец какой толстяк, или пиздец какой дебил.
или оба пункта одновременно
455 1427740
>>27409
switch ($order) {
case 'id':
$result .= 'id';
break;
case 'name':
$result .= 'name';
break;
case 'surname':
$result .= 'surname';
break;
case 'group':
$result .= '`group`';
break;
case 'mail':
$result .= 'mail';
break;
case 'rate':
$result .= 'rate DESC';
break;
case 'year':
$result .= 'year';
break;
case 'city':
$result .= 'city';
break;

Или пиздец какой толстяк, или пиздец какой дебил.
или оба пункта одновременно
456 1427745
https://itproger.com/news/44

Лол, обосрался, пока читал. Смахивает на какой-то жирный троллинг
457 1427754
>>27745
Все правильно написано хотя и несколько инфантильно
Что не так?
458 1427783
>>27745
Это не троллинг. Это статьи для дегенератов-вкатывальщиков. Которые ничерта кроме курсов и не делали толкового. И не сделают.
Я нуб, и "знаю" как php так и node, и на мой взгляд понимание общей структуры и деталей вэб-разработки как таковой,стандартов, паттернов и т.д важнее чем технология. Потому что написать нормальный, правильный интернет-магазин это гораздо больше чем знать пхп/питон/нода.
nodejs асинхронен, ой блядь ужас, невероятная сложность. Я промифицировать модуль fs за вечер научился, и теперь не ебусь с колбеками. И при этом зачем тебе морочиться с этим все, если на пхп ты реализуешь тот же самое приложение, но проще? Зачем заказчику продукт на более сложной и реже используемой технологии, если более простая справляется и так отлично?

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

Так что все эти сопли - это для людей которые думают что "вкатываются", а на самом деле хуи пинают. Это от инфантильности индустрии. Впрочем это все помирает, программирование как профессия - стареет естественным образом. Через десять лет в профессии будет толпа людей за 40, с опытом работы в 20-25 лет, и они и будут делать индустрию.
459 1427796
>>27783
мне не нравиться пых,он уродлив костылен
460 1427807
>>27796
Это вкусовщина. К вопросу популярности в прикладных задачах это отношения не имеет вообще.

>>27783
П.С.
Все что я написал - это конечно мое мнение. Но дополню вот чем:
я начинал вкатываться именно с ноды, и нода сука не милосердна, ее документация не проста, сама нода не проста. Я тогда не знал sql, читал только мантры про MongoBD. И что более важно я вообще не понимал принципов построения- приложения: МVC , сессии, авторизация, регистрация, роли доступа, взаимодействие с БД - все это в кашу, непонятно где и как в ноде использовать. MVC? Где в экспресс реализовывать модели, контроллеры и представления? Я тогда не понимал вообще. И вот самое важное - обучающих материалов нормального уровня на русском по ноде крайне мало.
Ну и еще по ноде - для новичка по ноде (как и в питоне) работы - в принципе нихуя от слова вообще. На пхп можно найти ИП "Красивые-сайты" и за 15 в месяц ковыряться получая реальный опыт работы, а не маня мечтания о том как тебя с умением отдавать на ноде три странички ждут в Калифорнийских стартапах. Ведь нода - это прогресс.О да.
Короче я взялся за пхп, с ее отличной документацией, большим комьюнити и очень большим количеством всяких туторов. Даже на дваче тред по пхп адекватный. По ютубу я пошагово по строчке запили три MVC фреймворка, от простых к посложнее, по ходу пьесы разобравшись с использованием классов и ООП. Изучил sql. И по итогу имею вполне представление о разработке. Самостоятельно с ноля могу запилить что то типа блога/не сложного магазина. Ток в пхп я получил полное представление о том как должно выглядеть вэб-приложение. И сейчас вернулся параллельно к ноде, уже с более серьезным пониманием что и как делать. Реально полсе пхп мне с нодой гораздо проще стало.
В этом контексте у пхп очень серьезное преимущество.
461 1427825
>>27740
Обычная фильтрация строки по белому списку чтобы в базу ничего лишнего не попало.
462 1427826
>>27807
работа есть потому что нужно поддержтвать все то дерьмо,которое накодили в эпоху становления и развития веба
463 1427965
>>27825

> обычная


ринку ноль три, ты?
464 1427979
когда создадут замену пхп?
465 1428042
Ребят, как развернуть iis в ide phpstorm?
Снимок экрана от 2019-07-04 22-34-59.png36 Кб, 549x614
466 1428084
Здорово бродяги! Подскажите кто знает, как распарсить такой xml как на пике. Надо получить только currency и rate
467 1428171
>>27745
Это и есть жирный троллинг для вкатывальщиков.
468 1428336
>>27736
>>27740
Я художник и так вижу. А вы - зашореные посредственности, если не увидели моего идейного посыла
case-кюн
469 1428425
Я походу ваще тупой. Не могу решить второй урок с этими кубиками, хз че ему надо
<?php

error_reporting(-1);

$anonDice1 = mt_rand(1,6);
$anonDice2 = mt_rand(1,6);

$compDice1 = mt_rand(1,6);
$compDice2 = mt_rand(1,6);

echo "U Anonche vypalo ($anonDice1) and ($anonDice2) \nU compa vypalo ($compDice1) and ($compDice2)\n";

$anonSum = ($anonDice1 + $anonDice2);
$compSum = ($compDice1 + $compDice2);

if (($anonDice1 == $anonDice2) && ($compDice1 == $compDice2)) {
echo "Dva Dabla - Zaebis tema!\n";
exit();
}

if ($anonSum > $compSum) {
echo "Anon pobedil ebana!\n";

} else($anonSum < $compSum) {
echo "Plastmasoviy mir pobedil!\n";
exit();
}

Подскажите, а то не хочется перескакивать не поняв...
469 1428425
Я походу ваще тупой. Не могу решить второй урок с этими кубиками, хз че ему надо
<?php

error_reporting(-1);

$anonDice1 = mt_rand(1,6);
$anonDice2 = mt_rand(1,6);

$compDice1 = mt_rand(1,6);
$compDice2 = mt_rand(1,6);

echo "U Anonche vypalo ($anonDice1) and ($anonDice2) \nU compa vypalo ($compDice1) and ($compDice2)\n";

$anonSum = ($anonDice1 + $anonDice2);
$compSum = ($compDice1 + $compDice2);

if (($anonDice1 == $anonDice2) && ($compDice1 == $compDice2)) {
echo "Dva Dabla - Zaebis tema!\n";
exit();
}

if ($anonSum > $compSum) {
echo "Anon pobedil ebana!\n";

} else($anonSum < $compSum) {
echo "Plastmasoviy mir pobedil!\n";
exit();
}

Подскажите, а то не хочется перескакивать не поняв...
470 1428429
>>28425
В последним if/else ошибка. потерял if.
https://www.php.net/manual/ru/control-structures.elseif.php

+ нужно добавить условие для ничьей. когда выбросили одинаково.
471 1428430
472 1428435
>>28429
всё равно чет не понял... но тебе спасибо
473 1428448
>>28435
if ($anonSum > $compSum) {
echo "Anon pobedil ebana!\n";
} elseif ($anonSum < $compSum) {
echo "Plastmasoviy mir pobedil!\n";
} else ($anonSum == $compSum) {
echo "Pobedila druzhba!\n"
exit();
}

ну чет опять не то, пздц
474 1428459
>>28448
Может быть if (condition) и elseif (condition)
else (condition) в языке нет.
ты пишешь else ($anonSum == $compSum) и происходит ошибка. пиши просто else {echo "blabla"; exit();}
475 1428465
>>28448
В последнем echo нет точки с запятой. Ну это так, просто заметил =)
476 1428801
>>28459
да, дописал elseif в последнем условии и заработало. Но я пздц долго сидел думал и ток перед сном допёр. За ответ всё равно спасибо, надеюсь больше так не буду тупить..
477 1428825
>>28084
Я чо-то нихуя не понял,, мне еще долго ждать ответ???????????!!!
478 1428827
ничего лучше пхп нет и не придумают
479 1428855
for ($i=1; $i<10; $i++) {
echo "{$i} * {$i} = \n";
}
480 1428856
>>28855
После получаса мучений снова выхожу на связь. Как после равно вставить результат произведения (квадрат). Отдельной переменной не смог, хз как, куда... Кто обладает помогите
481 1428873
>>28856
Всё норм, ребят. Понадобилось просто ещё пол часика. Извините за засирание треда, просто у кого ещё спросить кроме вас
482 1428903
>>28873
Всегда пожалуйста XD
483 1428948
Есть всякие вакансии для вката типа "php стажер". Список требований там стандартный: php, mysql, js, html, css, иногда jQuery. Понятно, что идеальные знания не требуются, но всё-таки какой примерно уровень ожидается? Нужно ли зазубрить весь мануал php? Потребуется ли навык адаптивной верстки? Насколько нужно уметь в js?
Каких задачек из шапки может хватить для знаний?
Не хотелось бы проебать единственную стажировку в городе, поэтому не могу пока самому проверить.
484 1428954
>>28948

>php, mysql, js, html, css, иногда jQuery


А если вдруг это все нужно, то ты тогда это все выучишь за один день - неделю и успеешь не проебать единственную стажировку в городе?
485 1428988
>>28954
Я в любом случае это все учу потихоньку, просто мне нужно знать, в какой момент мне вкатываться кабанчиком.
486 1429079
>>28903
вот задача про кредит. окей, как в примере делаю долг в минус уходит и как бы збсь. А как сделать чтобы не платил больше чем надо за последний месяц? Я написал такую херню:
http://ideone.com/c2OUMk#stdin
В какую сторону думать?
06-07-1915-46-45.png12 Кб, 392x226
487 1429084
Поясните за колбэки и контекст

class c1 {
public function __construct () {
$obj = new c2();
$obj->fn = function () use ($obj) {
var_dump ($obj);
}
($obj->fn)()
}
}

class c2 {
public $fn;
}

Можно ли как-нибудь добиться того, чтобы вместо var_dump($obj) я мог написать var_dump($this)? То есть, я хочу в коде анонимной функции использовать $this таким образом, чтобы это $this указывало на $this экземпляра класса с2, а не c1.

Или так не бывает? Конечно, чисто функционально меня и сейчас всё устраивает ($this, $obj - какая разница), но мне просто кажется несколько всратым и странным то, что я таким образом могу из кода, который вроде как пишется для класса c2, обращаться к приватным свойствам c1.

Дублирую код скрином для читабельности.

Или, может, я вообще не в ту сторону думаю?

Задача в следующем, есть два класса: c1 и c2. В рамках c1 мне необходимо задать код метода c2. c2 - класс, на основе которого будет сделано штук 10 объектов, каждый из которых имеет одинаковые свойства, но у каждого из этих объектов совершенно разный код в методе должен быть написан. Чтобы не наследовать 10 классов, решил воспользоваться колбэками. Но эта непонятка с $this напрягает немного.
488 1429141
>>29084
Объявляй его статическим $obj->fn = static function () use ($obj) {};
489 1429142
>>29084
Бредово выглядит и звучит.

>($obj->fn)()


Ты из жаваскрипта к нам? Тут так не пишут.
490 1429176
>>29142
Может тогда расскажешь, как пишут, а не выёбываться будешь?
491 1429181
>>29176
Тебя самого не смущает тот факт, что ты даже внятно объяснить не можешь - за каким хуем у тебя один объект реализует функционал другого? А как ты писать это примешься, так вообще хоть вешайся.

Колбэки у него блядь. Иди азы читай, макака.
492 1429189
>>29084
Первый раз вижу ЖС-код написанный на ПХП. Оно вообще работает? Живое?
Охуеть.
493 1429487
>>29181

Не можешь нормально, аргументированно ответить - лучше ничего не пиши.

>>29084

> Можно ли как-нибудь добиться того, чтобы вместо var_dump($obj) я мог написать var_dump($this)? То есть, я хочу в коде анонимной функции использовать $this таким образом, чтобы это $this указывало на $this экземпляра класса с2, а не c1



Замыкание в PHP - это объект класса Closure, а у него есть метод bind(). Но твой подход в общем неправильный. Если тебе надо обратиться к $obj, то ты можешь просто передать его в замыкание, и обращаться напрямую, а не придумывать костыли.

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



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

> Задача в следующем, есть два класса: c1 и c2. В рамках c1 мне необходимо задать код метода c2. c2 - класс, на основе которого будет сделано штук 10 объектов, каждый из которых имеет одинаковые свойства, но у каждого из этих объектов совершенно разный код в методе должен быть написан. Чтобы не наследовать 10 классов, решил воспользоваться колбэками.



Это неправильный подход, который ухудшает чтение и поддержку кода. Либо делай 10 классов, если по смыслу это разные классы, либо сделай один класс со свитчем. Так как я не знаю суть задачи, то не могу подсказать. Но сама идея, что класс c1 решает, какой метод должен быть в классе c2 - неправильная.

Вот более адекватные примеры использования коллбеков. Допустим, у нас есть класс, представляющий коллекцию объектов, и мы хотим искать их по произвольному условию. Тут подойдет коллбек, который получает на вход сущность и возвращает true/false, подходит ли она под условие:

$londoners = $userList->select(function ($u) { return $u->getCity() == 'London'; });

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

$pinCodeValidator = new CallbackValidator(function ($value) {
return preg_match("/^\d{4}$/", $value);
});

$isValid = $pinCodeValidator->validate($code);

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

Так как такая ситуация встречается довольно часто, для неё придумано другое решение: анонимные классы: https://www.php.net/manual/ru/language.oop5.anonymous.php . Оно позволяет сделать более строгий контроль типов. Перепишем валидатор выше на анонимный класс. Сначала сделаем базовый класс валидатора и пометим его как абстрактный (недоделанный), так как он неработоспособен без нашей функции:

abstract class Validator {
abstract public function validate(string $value): bool;
// .. другие поля и методы
}

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

$pinCodeValidator = new class extends Validator {
public function validate(string $value): bool
{
return preg_match("/^\d{4}$/", $value);
}
}

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

Не можешь нормально, аргументированно ответить - лучше ничего не пиши.

>>29084

> Можно ли как-нибудь добиться того, чтобы вместо var_dump($obj) я мог написать var_dump($this)? То есть, я хочу в коде анонимной функции использовать $this таким образом, чтобы это $this указывало на $this экземпляра класса с2, а не c1



Замыкание в PHP - это объект класса Closure, а у него есть метод bind(). Но твой подход в общем неправильный. Если тебе надо обратиться к $obj, то ты можешь просто передать его в замыкание, и обращаться напрямую, а не придумывать костыли.

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



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

> Задача в следующем, есть два класса: c1 и c2. В рамках c1 мне необходимо задать код метода c2. c2 - класс, на основе которого будет сделано штук 10 объектов, каждый из которых имеет одинаковые свойства, но у каждого из этих объектов совершенно разный код в методе должен быть написан. Чтобы не наследовать 10 классов, решил воспользоваться колбэками.



Это неправильный подход, который ухудшает чтение и поддержку кода. Либо делай 10 классов, если по смыслу это разные классы, либо сделай один класс со свитчем. Так как я не знаю суть задачи, то не могу подсказать. Но сама идея, что класс c1 решает, какой метод должен быть в классе c2 - неправильная.

Вот более адекватные примеры использования коллбеков. Допустим, у нас есть класс, представляющий коллекцию объектов, и мы хотим искать их по произвольному условию. Тут подойдет коллбек, который получает на вход сущность и возвращает true/false, подходит ли она под условие:

$londoners = $userList->select(function ($u) { return $u->getCity() == 'London'; });

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

$pinCodeValidator = new CallbackValidator(function ($value) {
return preg_match("/^\d{4}$/", $value);
});

$isValid = $pinCodeValidator->validate($code);

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

Так как такая ситуация встречается довольно часто, для неё придумано другое решение: анонимные классы: https://www.php.net/manual/ru/language.oop5.anonymous.php . Оно позволяет сделать более строгий контроль типов. Перепишем валидатор выше на анонимный класс. Сначала сделаем базовый класс валидатора и пометим его как абстрактный (недоделанный), так как он неработоспособен без нашей функции:

abstract class Validator {
abstract public function validate(string $value): bool;
// .. другие поля и методы
}

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

$pinCodeValidator = new class extends Validator {
public function validate(string $value): bool
{
return preg_match("/^\d{4}$/", $value);
}
}

Это решение имеет плюс: мы контролируем тип функции. Не получится указать функцию с другим набором аргументов или возвращаемым типом. Также, переданная нами функция становится полноценным методом класса и имеет доступ к его полям и методам. Также, вместо абстрактного класса можно использовать интерфейс.
494 1429516
>>29487
Не надо выёбываться.
495 1429552
>>29487
Спасибо за развёрнутый ответ.

Если говорить более конкретно, то суть такая.

Этот PHP-скрипт пишется для консоли и рассчитан на то, что он будет работать в виде "демона", то есть, 24/7 крутится в фоне (пока не упадёт). Сделано это через рекурсию и sleep(). Может быть, я пидор и php для таких целей - худшее решение, но сейчас не об этом.

Обработкой всего этого дела занимается класс srv. Этот класс имеет поле $workers, которое представляет из себя массив объектов класса worker.

У всех worker'ов есть общие методы и поля: метод, который отвечает true/false на вопрос того, пришло ли время данному worker'у выполнить свой код. Поле, которое хранит время следующего планового исполнения. И т. д.

При этом, у каждого worker'а есть некий "основной метод", который выполняет определённую работу. И у каждого worker'а он свой. Кто-то обновляет сессию, кто-то получает список новых сообщений и т. д. Потому что сессию мне нужно обновлять пару раз в день, а новые сообщения дёргать раз в пару минут.

Как это я решил сейчас - описано в моём, первом посте. Класс srv создаёт объекты класса worker и каждому из них передаёт колбэк, который содержит код, который данный worker должен выполнять.

Лепить ради этого дела 10 отдельных классов мне показалось избыточным. Но как я понял из твоего поста - нужно не выёбываться и всё-таки налепить их, верно?
496 1429553
>>29552

>крутитЬся

497 1429561
>>29552
Зачем тебе рекурсия, бесконечный цикл сделай. И отнаследовать десять классов нормальная идея - ты можешь выдать каждому классу понятное имя в зависимости от того что он делает.
498 1429562
>>29561
А есть принципиальная разница между бесконечным циклом и рекурсией?
499 1429566
>>29562
Вообще нет, но рекурсия жрет больше ресурсов - так как в пхп не оптимизируется хвостовая рекурсия то с этим нихуя не поделать.
500 1429604
>>29562
Глубина рекурсии в php ограничена в раене 256. Вроде можно менять эту настройку, но я дропнул эту затею из-за подводных камней. Т.е. скрипт упадет с ошибкой через 8 часов если плодить новый вызов каждые 2 минуты.
501 1429663
>>29566
>>29604

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

Еще такой вопрос. Как я уже сказал - у меня cli-скрипт, который рассчитан на псевдобесконечную работу. Я могу как-нибудь выполнить некий код перед его завершением? Деструктор не срабатывает, если прибить скрипт через ctrl + c (SIGINT) в консоли.

Нагуглил это https://www.php.net/manual/ru/function.pcntl-signal.php , но как я понимаю, у меня нет возможности обработать все сигналы разом.

Есть какой-нибудь более надёжный и универсальный вариант?
502 1429675
>>29663

> ный и универсаль


Задумано что ты на каждый сигнал отдельно подписываться будешь.
Screenshot 2019-07-07 at 13.50.23.png42 Кб, 922x165
503 1429708
Анонче ,поясни за (?, ? , ?) откуда эти символы берут значение и заменяются ими
504 1429731
>>29708
Это prepared statement вместо того чтобы прямым текстом подставлять значение логина и т.п. они подставляются (биндятся) отдельной операций. У тебя это наверное дальше по тексту идет. Это способ борьбы с разного рода робертами-брось-таблицу (SQL Injection).
505 1429737
Есть такая структура:
<div A>
<div C></div C>
</div A>
<div B>
<div D></div D>
</div B>

Как задать в CSS свойство div D через div C? Нужно что-то типа (div A > div C) + (div B > div C)
Screenshot 2019-07-07 at 14.29.42.png167 Кб, 1059x734
506 1429738
>>29731
Понял, спасибо.
Тогда я хз в чем ошибка, у меня sqlerror
может sql запрос не верный
Вот мой код
507 1429747
Блять, для кого нахуй этот учебник из шапки написан? Для новичков?? Да ну нахуй. Я заебался, я просто нихуя не понимаю как решать эти задачи. Я решил сам всего парочку, вот добрался до массивов, подсказка "заведи переменную и положи в неё ноль" Ну и дальше чё? Как блять объяснить что мне надо от программы блять? Я прочитал все функции, мануал по массивам, видео на ютубе одно, просто пиздец потратил времени на ебучую задачу в которую надо просто написать одну строчку и всё . Как эту ебучую проверку сделать? If писать или этот foreach? Куда писать, в каком месте, скобки блять где какие? Ёбаный рот этого учебника блять...
508 1429839
>>29747
Дай ссылку на задание, я подскажу
509 1429857
Сап Аноны и ОП, посмотрите задачу про файлообменник
https://github.com/InspektorGadjet/FileSharing
Насколько все плохо ?
510 1429881
>>29737
Если не изменяет память - никак, CSS-селекторы не могут указывать "на уровень выше".
511 1429888
>>29857

>$container['uploadDirectory'] = __DIR__ . '\uploads';


>$container['copyDirectory'] = __DIR__ . '\copyes';


Кажись удобнее будет это расположить в $container['settings'], в каком-нить массиве ['directories']. Просто по логике искать такое именно в настройках надо, а не в контейнере с зависимостями.
512 1429894
>>29857
Я бы ещё вынес создание конфигурации в другой файл - не хотелось бы спалить данные подключения БД кому-нить если у хостера модуль пхп глюканёт или ещё что.
513 1429928
какие перспективы у пыха в будущем?
514 1429930
>>29552

В такой ситуации правильнее будет сделать базовый класс или интерфейс воркера, а конкретных воркеров реализовать либо как анонимные классы либо как обычные классы-наследники.
515 1429931
>>29928
Плохие. Выкатывайся срочно.
516 1429934
>>29552

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

Ну и перечитай мой пост еще раз. Я там прямо описал возможные решения твоей задачи, и любое из них лучше твоего странного решения с засовыванием коллбеков в публичное поле объекта.
517 1429958
>>29931
насколько все плохо?
518 1429960
>>29958
Зачем спрашиваешь?
519 1429973
И так продолжим рубрику "Помогите тупому".

Есть задача:

>W5.2 Некто кладет в банк 10000 р. Банк начисляет 10% годовых (то есть, каждый год на счету становится на 10% больше, чем в прошлом году). Напиши программу, считающую, через сколько лет в банке будет миллион? Сколько лет будет этому некто? Доживет ли некто до этого дня, если сегодня ему 16 лет?



Есть кусок кода, который должен посчитать количество лет:
и эта падла не работает.
<?php
error_reporting(-1);

for ($x=10000; $x==1000000; $x+=1000) {

echo "{$x} - покажи мне че нить";
}
?>
Там по хорошему, цикл должен повторится 49 раз, и как то отобразится в консоле, но нихуя, вопрос что я не так делаю?
520 1429974
>>29973

> <?php


error_reporting(-1);

for ($x=10000; $x==1000000; $x+=1000) {

echo "{$x} - покажи мне че нить";
}
?>
521 1429975
>>29973

Это частая ошибка. Там надо указать условие продолжения цикла (цикл выполняется, пока условие верно), а ты написал условие прекращения цикла.
код.png15 Кб, 781x359
522 1429976
>>29973
>>29974
Не изнасилованный код на скрине.
Аноны, за год смогу вкатиться и начать зарабатывать? 523 1430042
Хочу! Хочу вакансию и прогать. Хочу зумерский офис, ненавижу шараги с 30+-ками
524 1430045
>>29738
Bump вопросу
525 1430069
>>29839
вторая вот здесь, про рост
https://phpbooktest2.ga/l1/arrays.html
414-525 526 1430077
>>30045
>>29738

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

Потому надо сделать так:

- в режиме разработки ошибку можно выводить на экран
- в режиме продакшена ошибка должна идти строго в лог, который ты раз в сутки будешь просматривать на наличие ошибок
- выбор между режимами задается стандартной опцией display_errors в php.ini (мануал: https://www.php.net/manual/ru/errorfunc.configuration.php#ini.display-errors )

Казалось бы, нам придется сейчас писать сложный код, определяющий значение display_errors, с разными вариантами выполнения, но есть способ проще. В PHP есть готовая функция, чтобы сообщить об ошибке, и она сама выведет ее на экран или в лог - это trigger_error: https://www.php.net/manual/ru/function.trigger-error.php

Используется она так, чтобы сообщить об ошибке:

trigger_error("Cannot prepare SQL query", E_USER_ERROR);

То есть при возникновении ошибки ты должен вызывать эту функцию, передав ей подробности. Где их взять? Откроем мануал по mysqli и посмотрим, как сделано там: https://www.php.net/manual/ru/mysqli.examples-basic.php

Там есть такой код:

// О нет!! переменная connect_errno существует, а это значит, что соединение не было успешным!
if ($mysqli->connect_errno) {
// Соединение не удалось. Что нужно делать в этом случае?
// Можно отправить письмо администратору, отразить ошибку в журнале,
// информировать пользователя об ошибке на экране и т.п.
// Вам не нужно при этом раскрывать конфиденциальную информацию, поэтому
// просто попробуем так:
echo "Извините, возникла проблема на сайте";

// На реальном сайте этого делать не следует, но в качестве примера мы покажем
// как распечатывать информацию о подробностях возникшей ошибки MySQL
echo "Ошибка: Не удалась создать соединение с базой MySQL и вот почему: \n";
echo "Номер ошибки: " . $mysqli->connect_errno . "\n";
echo "Ошибка: " . $mysqli->connect_error . "\n";
}

Этот код получает информацию об ошибке при соединении. И такой код, который получает информацию об ошибке при вызове функций:

if (!$result = $mysqli->query($sql)) {
// О нет! запрос не удался.
echo "Извините, возникла проблема в работе сайта.";

// И снова: не делайте этого на реальном сайте, но в этом примере мы покажем,
// как получить информацию об ошибке:
echo "Ошибка: Наш запрос не удался и вот почему: \n";
echo "Запрос: " . $sql . "\n";
echo "Номер ошибки: " . $mysqli->errno . "\n";
echo "Ошибка: " . $mysqli->error . "\n";
exit;
}

Тебе надо сделать так же, но объединить все подробности в одну строку и заменить echo на trigger_error(). То есть отдать информацию об ошибке PHP, и он ей распорядится, а заодно остановит выполнение твоей кривой программы, пока ты ее не исправишь.

То есть после каждой функции mysqli у тебя должен стоять if, проверяющий наличие ошибки и передающий ее подробности в trigger_error(). Заодно перечитай мануал и примеры кода в нем по тем ссылкам, что я дал.

Позже, я советую изучить исключения и параметр report_mode, если его правильно настроить, то mysqli сама будет при ошибке выбрасывать исключения, которые будут выводиться на экран или идти в лог, и if'ы будут не нужны: https://www.php.net/manual/ru/mysqli-driver.report-mode.php . Но это можно сделать потом.

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

- не надо делать огромную вложенность if друг в друга. Если ты сделал exit, то программа дальше не выполняется, и блок else не нужен.
- надо проверять результат всех mysqli-функций вроде mysqli_stmt_execute() на ошибки, а ты это не делаешь
- нельзя подставлять email в ссылку напрямую, надо его экранировать как описано в моем уроке: https://github.com/codedokode/pasta/blob/master/network/urls.md (процентное кодирование)
- лучше использовать такой алгоритм работы с формами, который не требует редиректа при ошибке. Он описан тут: https://github.com/codedokode/pasta/blob/master/forms.md

Задавай вопросы, если непонятно. Если понятно - делай все, что я перечислил и читай все статьи по ссылкам.
414-525 526 1430077
>>30045
>>29738

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

Потому надо сделать так:

- в режиме разработки ошибку можно выводить на экран
- в режиме продакшена ошибка должна идти строго в лог, который ты раз в сутки будешь просматривать на наличие ошибок
- выбор между режимами задается стандартной опцией display_errors в php.ini (мануал: https://www.php.net/manual/ru/errorfunc.configuration.php#ini.display-errors )

Казалось бы, нам придется сейчас писать сложный код, определяющий значение display_errors, с разными вариантами выполнения, но есть способ проще. В PHP есть готовая функция, чтобы сообщить об ошибке, и она сама выведет ее на экран или в лог - это trigger_error: https://www.php.net/manual/ru/function.trigger-error.php

Используется она так, чтобы сообщить об ошибке:

trigger_error("Cannot prepare SQL query", E_USER_ERROR);

То есть при возникновении ошибки ты должен вызывать эту функцию, передав ей подробности. Где их взять? Откроем мануал по mysqli и посмотрим, как сделано там: https://www.php.net/manual/ru/mysqli.examples-basic.php

Там есть такой код:

// О нет!! переменная connect_errno существует, а это значит, что соединение не было успешным!
if ($mysqli->connect_errno) {
// Соединение не удалось. Что нужно делать в этом случае?
// Можно отправить письмо администратору, отразить ошибку в журнале,
// информировать пользователя об ошибке на экране и т.п.
// Вам не нужно при этом раскрывать конфиденциальную информацию, поэтому
// просто попробуем так:
echo "Извините, возникла проблема на сайте";

// На реальном сайте этого делать не следует, но в качестве примера мы покажем
// как распечатывать информацию о подробностях возникшей ошибки MySQL
echo "Ошибка: Не удалась создать соединение с базой MySQL и вот почему: \n";
echo "Номер ошибки: " . $mysqli->connect_errno . "\n";
echo "Ошибка: " . $mysqli->connect_error . "\n";
}

Этот код получает информацию об ошибке при соединении. И такой код, который получает информацию об ошибке при вызове функций:

if (!$result = $mysqli->query($sql)) {
// О нет! запрос не удался.
echo "Извините, возникла проблема в работе сайта.";

// И снова: не делайте этого на реальном сайте, но в этом примере мы покажем,
// как получить информацию об ошибке:
echo "Ошибка: Наш запрос не удался и вот почему: \n";
echo "Запрос: " . $sql . "\n";
echo "Номер ошибки: " . $mysqli->errno . "\n";
echo "Ошибка: " . $mysqli->error . "\n";
exit;
}

Тебе надо сделать так же, но объединить все подробности в одну строку и заменить echo на trigger_error(). То есть отдать информацию об ошибке PHP, и он ей распорядится, а заодно остановит выполнение твоей кривой программы, пока ты ее не исправишь.

То есть после каждой функции mysqli у тебя должен стоять if, проверяющий наличие ошибки и передающий ее подробности в trigger_error(). Заодно перечитай мануал и примеры кода в нем по тем ссылкам, что я дал.

Позже, я советую изучить исключения и параметр report_mode, если его правильно настроить, то mysqli сама будет при ошибке выбрасывать исключения, которые будут выводиться на экран или идти в лог, и if'ы будут не нужны: https://www.php.net/manual/ru/mysqli-driver.report-mode.php . Но это можно сделать потом.

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

- не надо делать огромную вложенность if друг в друга. Если ты сделал exit, то программа дальше не выполняется, и блок else не нужен.
- надо проверять результат всех mysqli-функций вроде mysqli_stmt_execute() на ошибки, а ты это не делаешь
- нельзя подставлять email в ссылку напрямую, надо его экранировать как описано в моем уроке: https://github.com/codedokode/pasta/blob/master/network/urls.md (процентное кодирование)
- лучше использовать такой алгоритм работы с формами, который не требует редиректа при ошибке. Он описан тут: https://github.com/codedokode/pasta/blob/master/forms.md

Задавай вопросы, если непонятно. Если понятно - делай все, что я перечислил и читай все статьи по ссылкам.
527 1430078
>>29747

Ок, вот алгоритм решения:

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

> Как эту ебучую проверку сделать? If писать или этот foreach?



И то, и другое. foreach будет перебирать массив, а if - делать проверку.

> Куда писать, в каком месте, скобки



Это вроде объясняется в предыдущих уроках. Если ты пропустил какие-то задачи в них, надо вернуться, перечитать и попробовать решить сначала их. Или тебе непонятен foreach?

Справшивай, если что-то непонятно.

>>29888

В настройки стоит выносить только то, что можно менять - например, пароль от БД. Расположение директорий, наверно, менять особого смысла нет. А лишние настройки раздувают конфиг и усложняют код. Я бы советовал минимизировать их количество.

>>29708

Прочитай мануал (на русском) https://www.php.net/manual/ru/mysqli.quickstart.prepared-statements.php

Затем мой урок по SQL-инъекциям: https://github.com/codedokode/pasta/blob/master/security/sql-injection.md

>>29663

Более надежным способом может быть иметь родительский скрипт, который будет убирать за ребенком при его завершении. Так как при серьезной проблеме ребенок может быть в неработающем состоянии. Ну или ловить SIGINT, если тебя интерсует только прерывание по Ctrl + C.
527 1430078
>>29747

Ок, вот алгоритм решения:

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

> Как эту ебучую проверку сделать? If писать или этот foreach?



И то, и другое. foreach будет перебирать массив, а if - делать проверку.

> Куда писать, в каком месте, скобки



Это вроде объясняется в предыдущих уроках. Если ты пропустил какие-то задачи в них, надо вернуться, перечитать и попробовать решить сначала их. Или тебе непонятен foreach?

Справшивай, если что-то непонятно.

>>29888

В настройки стоит выносить только то, что можно менять - например, пароль от БД. Расположение директорий, наверно, менять особого смысла нет. А лишние настройки раздувают конфиг и усложняют код. Я бы советовал минимизировать их количество.

>>29708

Прочитай мануал (на русском) https://www.php.net/manual/ru/mysqli.quickstart.prepared-statements.php

Затем мой урок по SQL-инъекциям: https://github.com/codedokode/pasta/blob/master/security/sql-injection.md

>>29663

Более надежным способом может быть иметь родительский скрипт, который будет убирать за ребенком при его завершении. Так как при серьезной проблеме ребенок может быть в неработающем состоянии. Ну или ловить SIGINT, если тебя интерсует только прерывание по Ctrl + C.
528 1430079
>>29079

Попробуй переписать код внутри цикла примерно так:

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

«Платим» здесь значит уменьшаем долг и увеличиваем общую сумму выплаченного.

>>28825
>>28084

А в мануале по SimpleXML ответа нет? https://www.php.net/manual/ru/simplexml.examples-basic.php

>>27825

Можно сделать чуть проще, сделать массив разрешенных значений, и проверять с помощью in_array(), что значение находится в массиве. Косые кавычки подставлять всегда, а DESC приписывать с помощью if.

>>27807

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

Что касается асинхронности, то до async/await писать на промисах работу с БД - это по-моему боль, и синхронный код тут гораздо проще подходит.

> С появлением Node и производных фреймворков, работающих асинхронно, необходимость в PHP полностью отпала.



Странно только, что она не отпала с появлением питоновского асинхронного фреймворка twisted, который появился раньше. А так, статья по ссылке - тонкий троллинг, о чем например говорит пункт про "утечки памяти" - видимо автору знакома эта проблема. Или местные "специалисты" по Ноде не поняли намек?

>>27394

Модель - это "модель" предметной сущности, как правило оформленная в виде класса. Например, ты делаешь приложение-магазин и в нем есть класс "Товар", объекты которого являются моделью реального товара в коде и имеют свойства вроде "цена", "название" и тд. Иногда на модель навешивают еще работу с БД, при использовании паттернов вроде Active Record, но это не обязательно.

>>27289

В PHP есть функция mt_rand(), которая "возвращает" случайное число. Вот пример:

echo mt_rand(1, 100); // выводит случайное число от 1 до 100

Здесь мы с помощью команды echo выводим число, которое вернула mt_rand(). Тебе же надо не сразу вывести это число, а записать в переменную. Для этого мы пишем код вроде

$x = mt_rand(....);

Оператор "равно" обозначает "взять значение справа и записать в переменную слева".
528 1430079
>>29079

Попробуй переписать код внутри цикла примерно так:

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

«Платим» здесь значит уменьшаем долг и увеличиваем общую сумму выплаченного.

>>28825
>>28084

А в мануале по SimpleXML ответа нет? https://www.php.net/manual/ru/simplexml.examples-basic.php

>>27825

Можно сделать чуть проще, сделать массив разрешенных значений, и проверять с помощью in_array(), что значение находится в массиве. Косые кавычки подставлять всегда, а DESC приписывать с помощью if.

>>27807

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

Что касается асинхронности, то до async/await писать на промисах работу с БД - это по-моему боль, и синхронный код тут гораздо проще подходит.

> С появлением Node и производных фреймворков, работающих асинхронно, необходимость в PHP полностью отпала.



Странно только, что она не отпала с появлением питоновского асинхронного фреймворка twisted, который появился раньше. А так, статья по ссылке - тонкий троллинг, о чем например говорит пункт про "утечки памяти" - видимо автору знакома эта проблема. Или местные "специалисты" по Ноде не поняли намек?

>>27394

Модель - это "модель" предметной сущности, как правило оформленная в виде класса. Например, ты делаешь приложение-магазин и в нем есть класс "Товар", объекты которого являются моделью реального товара в коде и имеют свойства вроде "цена", "название" и тд. Иногда на модель навешивают еще работу с БД, при использовании паттернов вроде Active Record, но это не обязательно.

>>27289

В PHP есть функция mt_rand(), которая "возвращает" случайное число. Вот пример:

echo mt_rand(1, 100); // выводит случайное число от 1 до 100

Здесь мы с помощью команды echo выводим число, которое вернула mt_rand(). Тебе же надо не сразу вывести это число, а записать в переменную. Для этого мы пишем код вроде

$x = mt_rand(....);

Оператор "равно" обозначает "взять значение справа и записать в переменную слева".
529 1430080
>>27289

В PHP есть функция mt_rand(), которая "возвращает" случайное число. Вот пример:

echo mt_rand(1, 100); // выводит случайное число от 1 до 100

Здесь мы с помощью команды echo выводим число, которое вернула mt_rand(). Тебе же надо не сразу вывести это число, а записать в переменную. Для этого мы пишем код вроде

$x = mt_rand(....);

Оператор "равно" обозначает "взять значение справа и записать в переменную слева".

>>27310

Диапазон указывается при вызове функции mt_rand в скобках, тут есть примеры: https://php.net/manual/ru/function.mt-rand.php

>>27125

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

Функция mail() под Windows умеет в SMTP, но видимо без шифрования: https://www.php.net/manual/ru/mail.configuration.php#ini.smtp В линуксе mail() просто вызывает программу sendmail и передает ей письмо (она добавляет письмо в очередь для локально поднятного почтового сервера).

В теории есть еще вариант, чтобы твоя программа содержала в себе "сервер", то есть при отправке письма на xANUSexamMQPplePUNCTUMcom определяла почтовый сервер домена exmple.com, соединялась с ним и отправляла письмо для пользователя x. Но я про такие библиотеки не знаю.
530 1430081
>>26985

Вообще, алгоритм примерно такой:

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

«Платим» здесь значит уменьшаем долг и увеличиваем общую сумму выплаченного.

>>426895



Не так. Отправка письма на x+0XANUSexamplePUNCTUMc=|Zom делается так: ты должен определить по DNS, кто является почтовым сервером для example.com (запись MX), подсоединиться по SMTP и передать письмо. Тот его примет и положит в почтовый ящик с названием x. Однако, там может быть куча проблем - банальнейшая, тебе могут отдать ошибку в стиле "незнакомый отправитель, повтори-ка попытку через 10 минут", а твой скрипт очевидно, ждать 10 минут не будет. Или из-за того, что у тебя IP-адрес от домашнего провайдера, письмо будет помечено как вероятный спам или вообще не принято.

Потому обычно ты поднимаешь свой почтовый сервер или арендуешь чужой, передаешь ему письмо по протоколу SMTP и дальше он уже решает все проблемы (связывается с почтовым сервером получателя, делает повторные попытки итд). Если ты хочешь поднять свой сервер, то придется настроить технологии вроде настройки DNS для твоего IP адреса. Это называется MTA, или mail relay - сервер, который пересылает письма к получателю.

SMTP - протокол отдачи письма, либо непосредсвенно от тебя к MTA, либо от одного MTA к другому. Когда-то были "открытые релеи", которые принимали письма от любого, но через них слали спам и их позакрывали. Сейчас ты должен отдавать письмо своему серверу.

Приведу пример. Допустим, ты хочешь отправить письмо на dogANUSyandexPUNCTUMr/d4u. Смотрим в DNS запись типа MX для yandex.ru: http://whois7.ru/?s=dig&q=yandex.ru&ns=ns1.yandex.ru&t=MX&nostats=1&noquestion=1

Там указано, что это сервер mx.yandex.ru. Значит, письмо надо передать ему.

PHPMailer делает две вещи:

- поддерживает протокол вроде SMTP
- поддерживает создание сложных писем с HTML, вложениями итд

Функционал полноценного почтового-сервера-доставщика (Mail Transfer Agent) он не выполняет. Он не ищет, кто отвечает за данный домен, а всегда шлет письма на один и тот же SMTP-сервер, на твой сервер, сервер отправителя. Также, он является SMTP-клиентом (тот, кто подсоединяется к серверу), а не сервером.
530 1430081
>>26985

Вообще, алгоритм примерно такой:

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

«Платим» здесь значит уменьшаем долг и увеличиваем общую сумму выплаченного.

>>426895



Не так. Отправка письма на x+0XANUSexamplePUNCTUMc=|Zom делается так: ты должен определить по DNS, кто является почтовым сервером для example.com (запись MX), подсоединиться по SMTP и передать письмо. Тот его примет и положит в почтовый ящик с названием x. Однако, там может быть куча проблем - банальнейшая, тебе могут отдать ошибку в стиле "незнакомый отправитель, повтори-ка попытку через 10 минут", а твой скрипт очевидно, ждать 10 минут не будет. Или из-за того, что у тебя IP-адрес от домашнего провайдера, письмо будет помечено как вероятный спам или вообще не принято.

Потому обычно ты поднимаешь свой почтовый сервер или арендуешь чужой, передаешь ему письмо по протоколу SMTP и дальше он уже решает все проблемы (связывается с почтовым сервером получателя, делает повторные попытки итд). Если ты хочешь поднять свой сервер, то придется настроить технологии вроде настройки DNS для твоего IP адреса. Это называется MTA, или mail relay - сервер, который пересылает письма к получателю.

SMTP - протокол отдачи письма, либо непосредсвенно от тебя к MTA, либо от одного MTA к другому. Когда-то были "открытые релеи", которые принимали письма от любого, но через них слали спам и их позакрывали. Сейчас ты должен отдавать письмо своему серверу.

Приведу пример. Допустим, ты хочешь отправить письмо на dogANUSyandexPUNCTUMr/d4u. Смотрим в DNS запись типа MX для yandex.ru: http://whois7.ru/?s=dig&q=yandex.ru&ns=ns1.yandex.ru&t=MX&nostats=1&noquestion=1

Там указано, что это сервер mx.yandex.ru. Значит, письмо надо передать ему.

PHPMailer делает две вещи:

- поддерживает протокол вроде SMTP
- поддерживает создание сложных писем с HTML, вложениями итд

Функционал полноценного почтового-сервера-доставщика (Mail Transfer Agent) он не выполняет. Он не ищет, кто отвечает за данный домен, а всегда шлет письма на один и тот же SMTP-сервер, на твой сервер, сервер отправителя. Также, он является SMTP-клиентом (тот, кто подсоединяется к серверу), а не сервером.
531 1430166
А чего не катите, катите
532 1430190
>>29973
неправильно пошёл. Я недавно решал, выше задавал такие же тупые вопросы. Ниже пролистай задачу и там будет пример кода следующей. Вот оттуда я подглядел и кой чего подправил. Щас ебусь с массивами...
533 1430204
>>30078
хули заводить? там уже по условию переменная $number с нулем идет, ну и вот единственное до чего я додумался: http://ideone.com/LtprDn
и то он мне ошибку выдаёт. Я заебался блять, я не понимаю как это писать
534 1430205
>>30204

Ты предыдущие задачи, вроде задач про кубики решал? Если нет, то надо вернуться и решить. В if пишется одно условие, а не три разных выражения. Не переставляй символы наугад, а разберись, что ты хочешь сделать.
535 1430210
>>30205
ну ебать, попробовал через for с разными условиями - тоже нихуя. Всм разберись? Переменная равна нулю, если рост больше 169, то переменная увеличивается на 1. Как я это блять с помощью if должен написать?
536 1430211
второй день ебусь с одной строчкой кода, заебись
537 1430212
>>30077
>>30078
Спасибо большое
538 1430213
>>30212
да, и от меня тебе тоже спасибо, хоть я нихуя и не понимаю и горю
539 1430215
>>30210
Обратно возврщайся по программе - ты не понимаешь что делаешь, судя по всему. Это пиздос.
Рабочий код невозможно писать наугад.
sage 540 1430236
>>30215
да ёбаный в рот...
image.png450 Кб, 604x404
541 1430244
>>30078

>лишние настройки раздувают конфиг и усложняют код


Тесты писать заебись будет потом на таком коде - всё железно прописано и хуй чего подсунешь. Можно прямо в классах писать, круто будет потом в них копаться при минимальных изменениях конфигурации.
sage 542 1430246
>>30215
http://ideone.com/LtprDn#stdin
короче смог только так. Я хуй знает, у меня уже голова раскалывается
sage 543 1430249
>>30246
а ну всё, скобочку просто не там поставил. Заебись, решил...
544 1430253
>>30244

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


А уж постороннему сисадмину\девопсу вообще по-кайфу этим заниматься будет, особенно если он языка не знает.
545 1430655
Ребята, подскажите. Третья задачка по массивам: https://phpbooktest2.ga/l1/arrays.html
в 16 строчке пишу $random= array_rand($answers);
дальше я не знаю. если сделать $answer = $random то он конечно же выведет только число. А как сделать чтобы выводил значение?
546 1430801
>>30655
array_rand возвращает случайный ключ. Вот и возьми значение по этому ключу $answers[$random]
547 1430815
>>30655
функция array_random возвращает КЛЮЧ. То-есть число перед стрелочкой. А тебе надо вывести число ПОСЛЕ стрелочки. Они связаны друг с другом. То-есть тебе надо сказать массиву, массив, напиши, пожалуйста, мне значение, которое хранится под вот этим вот ключом, записанным в переменную рандом, то-есть
echo $answers[$random];
или в твоем случае
$answer = $answers[$random];
sage 548 1430978
>>30801
>>30815
Блин, спасибо ребят. Всё работает http://ideone.com/Fmg408
Добра вам
2019-07-1015-47-22.png13 Кб, 1067x174
549 1431621
Пацаны, помогите. Ко мне в руки попал немного легаси код нашего одной штуки, которую нужно немного допилить. В пыху не могу, тем более в фреймворке, а хуйня это на cakephp насколько я понял. Короче есть форма с пика, нужно чтобы по нажатию кнопки это дело так же передавалось в телеграм. По поводу токена и апи в курсе, но с я чет совсем не понимаю как нахуй формы работают тут. За помощь скину на пивас.
550 1431841
>>31621
Проще всего будет найти какой контроллер/екшен дергается при сабмите формы и туда дописать отправку в телеграм чего нужно.
551 1431884
>>31841
Спасибо, буду искать. Я думал там челиком через вьюхи отрабатывается. Еще нормального коммьюнити по кейку нет похоже нихуя, одни бразильцы да индусы
552 1432619
Двачуны, ума не могу приложить почему команда echo в цикле не выводит ничего на екран. За пределами цикла работает норм, а в середине ноль на масу. Чо такое???
553 1432622
Двачуны, вопрос следующий. Почему команда echo помещена в середину цикла for не хочет выводить вообще ничего? имеется ввиду помещена в { } За пределами цикла, все ок. А только здесь ебала.
554 1432623
>>32619
>>32622
Кул. Я думол первое сообщение проебалось.
555 1432657
>>32622
Возможно цикл не разу не выполняется.
Код неси. Хуле гадать.
556 1432667
Ребят, кто знает, что в себя включают строчки в вакансиях типа "навыки работы с php"? Это получается все ядро языка, всякие дополнительные функции, например для баз данных, математики и прочего, практический опыт написания бекенда с использованием ооп, mvc архитектуры, и различных паттернов? Что там ещё?
557 1433013
>>32667
анош, у меня мало опыта, но я подразумеваю, что если в вакансии требуется непосредственное взаимодействие с конкретной технологией, то тебе так и напишут типа ляравель, уи. А если это вакансия джуна, денег платят мало, то, скорее всего, базовые навыки сгодятся аля знаешь слово "массив" - ты уже король. А вообще все индивидуально. Те, кому нужен работник на конкретную работу, они сразу пишут будешь работать на такой языке с таким фреймворком. А если это вакансия "контент-менеджера", плюс сисадмина, плюс дезайнера, и приветствуется знание php, то тут пшп не ключевое
558 1433054
в шарпотреде сказали,что вы говно и вообще чернь
559 1433175
>>33013
А если это вакансия стажёра в рогах и копытах? По идее требования должны быть на уровне "иметь базовые знания и уметь написать круд"?
2019-07-06 224813-Greenshot.png4 Мб, 1920x1080
560 1433200
закончил 2й курс ойти из 3х. ходил/писал на всё связанное с софтверной разработкой, везде либо по конкурсу не прошёл, либо вообще не ответили. решил веб попробовать (мне он никогда не был интересен, но 1)нужны деньги 2)я толком и не пробовал). есть 2 места, что выглядят нелохо, у обоих, примерно, одинаковые требования:

>Knowledge of PHP (OOP, MVC), HTML, CSS and JavaScript



Я нихуя из этого никогда не изучал (учил шарп, питон, джаву и т.д.), но принципы ООП знаю. Реально ли,по-вашему, за ~ неделю получить какую-то базу знаний по сабжу, чтобы пройти интерном(там прям сказано, что работа для студентов, но необходимая глубина знаний не указана) ? Так я знаю основы программирования и ООП, но в вебе - мало чего.
561 1433267
>>33200
За неделю ты только в вёрстке можешь разобраться базово. Сразу предупреждаю, халявы тут нет, конкурс большой и даже на интерна просят достаточно много знаний. Минимум несколько месяцев на все уйдет.
562 1433310
>>33054

>в шарпотреде сказали,что вы говно и вообще чернь


если даже сишники обращаются к нам на ВЫ, то думай сам, кто тут уважаемый авторитет доски
563 1433418
двач,мне горит с симфони.
держу вас в курсе
image.png256 Кб, 500x500
564 1433488
565 1433532
>>31621
тоже пытался поставить synthwave тему?
566 1433549
Короче есть два стула. Либо учить php, какое-то время проработать джуном, параллельно учить Java/C#/Scala (что-то одно), и перекатится уже туда. Тут пхп чисто для быстрого вкатывания, т.к. нужны деньги, и опыт работы вообще. Либо сразу в выше перечисленные языки, но это вероятно год минимум дроча языка + базовых знаний. А то я выпустился с шараги и нихуя не знаю точнее знаю где искать, но сходу мало что вспомню(диплом на пхп с yii писал, но там некрасиво получилось)

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

Куда двигаться короче?
567 1433553
>>33549
есть еще третий стул - остаться в пхп, смотрю по мидлам вилка зп хорошая. Но здесь главный косяк, что пхп может исчезнуть рано или поздно
568 1433605
>>33549
анон, ты же понимаешь, что это как с иностранными языками - потратив на один время, второй ты выучишь в разы быстрее.
569 1433622
>>33605
Да, но допустим я на php дойду до мидла. А потом перейду на Java, мне тогда на junior переходить?
570 1433768
>>33622
Нахуй переходи.
571 1433803
>>33622
У тебя ноль коммерческого опыта, какой мидл?
Более того - слишком высокого мнения о своих скиллах, при нулевом опыте.
Петов, вангую, нет ни одного - даже показать ничего не сможешь нормального.
На таких "мастеров" нынче везде насмотрелись.
Тебе перезвонят.
572 1433897
>>33549
Ты петух, тебя даже стажёром не возьмут
573 1433924
>>33622

>Да, но допустим я на php дойду до мидла. А потом перейду на Java, мне тогда на junior переходить?


Анон, с тем багажом знаний, который у тебя будет после изучений пшп, с полученным опытом разработки и вращения в программистской среде велика вероятность, что ты джуниора джавовского тупо проскочишь и пойдешь выше. Тебе главное опыт получить
574 1433948
>>33803
какое еще высокое мнение, я просто планирую на будущее. Через сколько-то лет стану мидлом же? Вот, и как дальше пойдут события думаю
575 1433950
>>33924
т.е. на будущее, если несколько лет прокодил на php, то при переходе на Java уже можно не на джуна пойти? Хотя наверное зависит от вакансии типа на пхп только для сайтиков бек писал, а на яве какие-нибудь микросервисы надо делать
576 1433995
>>33950
Ну кто тебя возьмёт java миддлом без опыта этого самого java? Хорошо, если на джуна возьмут. Сейчас даже на джаву стажера требования ниибические
577 1434082
>>33995
ну и нахуй так жить? Предположим всю жизнь ебашил десктоп на delphi ебаном, потом делфи рынок сдулся. Переучился на c# для десктопа, а там только стажером возьмут? Лол
578 1434094
>>34082
а если с .net на java или наоборот тоже такая хуйня будет?)
579 1434102
>>34082
Да, как-то так) Сурово в айти нынче
580 1434109
>>34094
Ну технологии же разные, совсем не родственные, пусть и конкурирующие. Опыт в соседней отрасли, конечно, будет небольшим плюсом к резюме, но энивей все решает опыт в специальности и техническое интервью.
581 1434448
Почему пыха ассоциируется у меня с пердежом старых дедов?
582 1434456
Короче я потихой выучил верстку ребят, что учить дальше php или js?
583 1434507
>>34456
Смотря кем хочешь быть, фронтендером или бекендером
584 1434508
>>34448
Потому что это и есть запах пыха. Я к нему уже привык
image.png120 Кб, 1920x1080
someApprentice !EaaiHmIJms 585 1434558
https://github.com/someApprentice/Crypter

Переделал схему наследования БД на Single Table Inheritance.
Перешел с Node.js на PHP.
Реализовал простой текстовый чат (без шифрования) и конфернеции между двумя пользователями.

Сообщения/конференции сохраняются в IndexeDB и извлекаются реактивно (https://rxdb.info/).

Проверять не обязательно, думаю я могу всё сделать самостоятельно. Но если есть какие-то интересные мысли или замечания и советы, всегда рад. Скорее всего у меня повсюду не вынесен код.

У меня есть вопросы:

1. Когда отправляется первое сообщение пользователю, то открывается сначала форма для отправки сообщения, а потом делается редирект в только что созданную конференцию, после отправки сообщения.pic-1 Это сделалось потому что нельзя изначально открыть конференцию, которая ещё не существует.

Было бы лучше если бы приватная конференция имела такой же id как и пользователь. И пользователь сам по себе как бы представлялися как приватная конференция. Тогда можно будет открывать диалог между двумя пользователями без создания отдельной конференция для них.

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

Вот схема:

Conference:
uuid
type
name //может быть как имя пользователя так и имя конференции
...

Conference_Reference:
user
conference
updated
unread

Message:
...
conference

Message_Reference:
user
message

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

Вопрос прост и короток: Ничего страшного если uuid приватных конференций будут такие же как у пользователя?

2. Вопрос связанный с плохим знанием Питона или более специфичный для используемой мною платформы WAMP.

Платформа которую я использую может использовать компоненты, которые запускаются вместе с ней и могут быть использованы для обработки того или иного действия. Эти компоненты определяются в конфиге ( https://github.com/someApprentice/Crypter/blob/master/wamp/.crossbar/config.json#L101-L120 ).

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

https://github.com/someApprentice/Crypter/blob/master/wamp/AuthenticatorSession.py#L4
https://github.com/someApprentice/Crypter/blob/master/wamp/AuthorizerSession.py#L5
https://github.com/someApprentice/Crypter/blob/master/wamp/MessengerSession.py#L4

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

И заострю внимание на том, что эти компоненты запускаются самой платформой при её запуске в консоле или точнее сказать как процесс.

Вопрос в том - правильно ли добавляю пути к модулям и как это исправить если нет? И не является ли этот вопрос скорее специфичным для этой платформы и лучше бы ему быть заданным на её форуме?

3. Должно быть правильно шифровать любой контент который передается в сообщении будь то голосовое сообщение, изображение или любой другой файл. Библиотека шифрования может шифровать Uint8Array ( https://github.com/openpgpjs/openpgpjs#encrypt-and-decrypt-uint8array-data-with-a-password ).

Можно ли перекодировать исходный файл в Uint8Array а затем обратно в файл, для его сохранения на диск/хранилище?

Я поискал ответы в интернете и нашел такие ответы

https://stackoverflow.com/questions/37134433/convert-input-file-to-byte-array
https://stackoverflow.com/questions/25354313/saving-a-uint8array-to-a-binary-file

которые предлагают такой подход

var reader = FileReader(file);

reader.onloadend = (e) => {
let a = new Uint8Array(evt.target.result);

//encrypt

let blob = new Blob([a], { type: mimeType });

...
}

Но я не могу понять, Blob и File принимают в конструктор array of ArrayBuffer... Uint8Array является ArrayBuffer'ом?

В документации сказано, что нельзя создать ArrayBuffer сам по себе, вместо этого, нужно создать TypedArray, которым является Uint8Array.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer

И Uint8Array тоже принимает в конструктор ArrayBuffer

Значит, можно обойтись без FileReader'а и написать напрямую

var buffer = async file.arrayBuffer()

var a = Uint8Array(buffer);

//encrypt

file = new File([encrypted], { type: ... });

Это верно?
image.png120 Кб, 1920x1080
someApprentice !EaaiHmIJms 585 1434558
https://github.com/someApprentice/Crypter

Переделал схему наследования БД на Single Table Inheritance.
Перешел с Node.js на PHP.
Реализовал простой текстовый чат (без шифрования) и конфернеции между двумя пользователями.

Сообщения/конференции сохраняются в IndexeDB и извлекаются реактивно (https://rxdb.info/).

Проверять не обязательно, думаю я могу всё сделать самостоятельно. Но если есть какие-то интересные мысли или замечания и советы, всегда рад. Скорее всего у меня повсюду не вынесен код.

У меня есть вопросы:

1. Когда отправляется первое сообщение пользователю, то открывается сначала форма для отправки сообщения, а потом делается редирект в только что созданную конференцию, после отправки сообщения.pic-1 Это сделалось потому что нельзя изначально открыть конференцию, которая ещё не существует.

Было бы лучше если бы приватная конференция имела такой же id как и пользователь. И пользователь сам по себе как бы представлялися как приватная конференция. Тогда можно будет открывать диалог между двумя пользователями без создания отдельной конференция для них.

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

Вот схема:

Conference:
uuid
type
name //может быть как имя пользователя так и имя конференции
...

Conference_Reference:
user
conference
updated
unread

Message:
...
conference

Message_Reference:
user
message

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

Вопрос прост и короток: Ничего страшного если uuid приватных конференций будут такие же как у пользователя?

2. Вопрос связанный с плохим знанием Питона или более специфичный для используемой мною платформы WAMP.

Платформа которую я использую может использовать компоненты, которые запускаются вместе с ней и могут быть использованы для обработки того или иного действия. Эти компоненты определяются в конфиге ( https://github.com/someApprentice/Crypter/blob/master/wamp/.crossbar/config.json#L101-L120 ).

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

https://github.com/someApprentice/Crypter/blob/master/wamp/AuthenticatorSession.py#L4
https://github.com/someApprentice/Crypter/blob/master/wamp/AuthorizerSession.py#L5
https://github.com/someApprentice/Crypter/blob/master/wamp/MessengerSession.py#L4

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

И заострю внимание на том, что эти компоненты запускаются самой платформой при её запуске в консоле или точнее сказать как процесс.

Вопрос в том - правильно ли добавляю пути к модулям и как это исправить если нет? И не является ли этот вопрос скорее специфичным для этой платформы и лучше бы ему быть заданным на её форуме?

3. Должно быть правильно шифровать любой контент который передается в сообщении будь то голосовое сообщение, изображение или любой другой файл. Библиотека шифрования может шифровать Uint8Array ( https://github.com/openpgpjs/openpgpjs#encrypt-and-decrypt-uint8array-data-with-a-password ).

Можно ли перекодировать исходный файл в Uint8Array а затем обратно в файл, для его сохранения на диск/хранилище?

Я поискал ответы в интернете и нашел такие ответы

https://stackoverflow.com/questions/37134433/convert-input-file-to-byte-array
https://stackoverflow.com/questions/25354313/saving-a-uint8array-to-a-binary-file

которые предлагают такой подход

var reader = FileReader(file);

reader.onloadend = (e) => {
let a = new Uint8Array(evt.target.result);

//encrypt

let blob = new Blob([a], { type: mimeType });

...
}

Но я не могу понять, Blob и File принимают в конструктор array of ArrayBuffer... Uint8Array является ArrayBuffer'ом?

В документации сказано, что нельзя создать ArrayBuffer сам по себе, вместо этого, нужно создать TypedArray, которым является Uint8Array.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer

И Uint8Array тоже принимает в конструктор ArrayBuffer

Значит, можно обойтись без FileReader'а и написать напрямую

var buffer = async file.arrayBuffer()

var a = Uint8Array(buffer);

//encrypt

file = new File([encrypted], { type: ... });

Это верно?
586 1434619
>>34448
переходи на питон
587 1434732
>>34507
А кем легче и куда быстрее вкатиться?
588 1434901
>>34732
удабливаю
пыха вымрет? питон? куда делать вкат?
589 1434912
>>34732

>куда легче


Бутылки собирать легче всего.
Если ты нулевой, то тебе везде медленно и трудно будет.
590 1434923
>>34732
По идее, во фронтенд вкатиться чуть быстрее и проще, чем в бек. Но это только если у тебя все отлично с вёрсткой.
Но на самом деле вкатиться проще и легче туда, где больше стажировок в твоём городе.
Это именно та ситуация, где нужно выбрать, что тебе по душе, и не работает фишка "похуй куда, главное быстрее уже начать деньги зарабатывать". Что тебе больше нравится, то и легче пойдёт.
591 1434946
>>34901
Пыха в данный момент очень неплохо развивается, и, учитывая, что она всегда лидировала, ещё минимум 10 лет можно за неё не беспокоиться.
Для вката она вообще идеальна, простая и лёгкая со всех точек зрения, при этом куча вакух и стажировок с низкими требованиями. В то же время, она не такая престижная, как фронтенд(спасибо дурачкам, кричащим что пыха говно и нинужна), соответственно и конкуренция не такая дикая.
592 1435003
>>34923
А если всё нраица, то как?
Learn-ruby-on-rails-in-bangalore1.png150 Кб, 800x500
593 1435023
594 1435031
>>35003
Тогда считаешь количество стажировок и джуновских вакансий в твоем городе. Где больше, туда и вкатываешься.
595 1435080
У меня 2 вопроса по задачке про студентов:
если авторизацию делаем по куке, тогда после закрытия браузера возможность редактирования навсегда теряется? Зачем так делать?
Можно ссылку на идеальное решение этой задачки? Потом хочу сверить.
596 1435093
>>35080

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


анон, я до нее еще не дошел, сам новичок, но разве кукисы хранятся не столько времени, сколько ты сам им задашь? Там в задании вроде написано "укажите срок жизни - год". Разве куки после закрытия браузера не сохраняются?
597 1435278
>>35080
Ты наверное перепутал куки и сессии =)
598 1435287
>>35080
Куки сохраняются. Потеряется если ты будешь передавать данные пользователя в адресной строке (методом GET если не ошибаюсь). Либо если укажишь время жизни сессии/куки (не уверен, можно ли устанавливать время жизни куки, но сессии точно, но все равно одно без другого жизнеспособно лишь частным случаем передачи самого идентификатора браузера или передачей через get в url), как написал этот анон >>35093.
Что данные сессии, что данные куки, всего лишь информация, которую ты записал в 1ом случае на стороне сервера или во 2ом на стороне клиента. Если ты не используешь сессии и куки, то аутентификация (узнай про разницу между авторизацией и аутентификацией, а она есть) проходит по информации из куки, метода get или идентификатора браузера (думаю своеобразный отпечаток, хотя не особо понимаю).
599 1435290
>>35287

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


Фикс
600 1435346
>>35278
>>35287
Все, понял, не сохраняется только если expires 0 поставить.

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


А вот здесь не понял, сейчас вот попробовал передать данные в адресной строке, кука не потерялась!
601 1435376
>>35346
Куки в передаче через url не задействовано. Без них можно передавать данные посредством url. После прохождения авторизации создается сессия и ее идентификатор передается посредством get запроса. Вроде такую функцию можно настроить в php.ini
Ты, к примеру, можешь выключить в своем браузере куки и никак не получишь доступ к сайту без них. Слышал только про идентификатор браузера, но сам плохо понимаю что это, да и боюсь небезопасно.
602 1435381
>>35376
Вообщем не мучайся, если интересно, то погугли. А так это один из способов, который почти нигде не используется уже. Но именно в этом способе пропадает связь если ты закрываешь вкладку или браузер.
ВРОТЕНД 603 1435520
В общем, работаю пыха-кодером уже года 3. До этого подрабатывал на фрилансе и пилил сайтики для себя.

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

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

Синтаксис и логику этих залуп знаю: HTML, CSS, JS, Jquery, но учил я все это мягко говоря лет 5 назад и ниибу что там щас.

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

>Что учить?


Go
605 1435577
>>35520

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



слющай, анон, у меня мало опыта, но там наверное надо джикверри делать аля

$('#контейнер инпутов').append('<p><input type="мой инпут" name="инпут['+айдишник айдишник инпута+']" /></p>');

можно, конечно, тупо десять штук полей понаделать невидимых, а потом показывать их при заполнении предыдущего, но так наверное не делают
606 1435675
>>35577
Ну я так и делаю, и также рассуждаю "но так наверное не делают". Вопрос не в том как сделать, в данном случае похуй на это - главное шоб работало, но в теории хотелось бы вкатиться в правильное делание
607 1435784
Если я не могу сделать даже ебаный цикл из уроков по основам PHP, мне наверное не стоить вкатываться ?
608 1435811
>>35784
Да, иди котлеты жарь в маке.
609 1435842
Еще вопрос по задачке про студентов, что такое

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


? Разве можно в sql искать по соединению столбцов?
610 1435850
Помогите советом добрым, я изучал питон, знаю его неплохо, думал с ним найти работу, но открыл вакансии своей мухосрани их 2 и висят они по несколько месяцев, потом посмотрел пхп и было около 20, аноны за сколько можно перекатиться, учитывая что питон я знаю до ооп включительно и немного трогал джангу?
611 1435867
>>35675
Попробуй vue, там доки можно за час-два прочитать и уже делать адовые вещи
вот например твоя задача https://pastebin.com/ijXJXpHt
612 1435869
>>35850
Несколько месяцев, зависит от твоего текущего уровня и знания верстки.
613 1435870
>>35867

>vue


Как меного времени на его изучение надо потратить?
614 1435933
>>35870
Час доки почитать и сделать todo приложуху, готово, синтаксис у жс си-подобный поэтому после пыхи я думаю никаких траблов не будет на интуиции писать
Самая большая проблема наверное это понять как инициализировать приложение, есть вариант использовать рантайм-онли как и с жквери, но удобнее конечно использовать компоненты (каждый компонент это отдельный файл), а там и новый синтаксис и вот это всё. У симфони(webpack-encore) и ларавел(laravel-mix) есть свои тулзы для этого, можешь посмотреть что удобнее.
615 1436011
>>35933
Тханкс. Еще такой вопрос: во фронт я вообще никак перекатываться не планирую, насколько вероятно что через 3 секунды как я задрочу vue - он станет неактуальной парашей? знаю что во фронте каждую наносекунду устаревает весь стек
616 1436018
Пасаны, дошел я значит до циклов. Первую задачку нихуя не асилил взялся за вторую. И проблема в том, что echo в середине цикла не срабатывает. Как только выношу за его пределы все ок. код https://ideone.com/8PtJBZ ЧЯДНТ
617 1436026
>>36018
строка 15
for ($m=1; $m>=20; $m++)
второй оператор в скобках: при каком условии цикл выполняется. У тебя наизнанку сделано.
for ($m=1; $m<=20; $m++) попробуй, а потом дальше чини.
618 1436334
>>35784
На следующий день просто перечитай урок и все получится. Если бы ты был тупым, то ты бы не смог браузер запустить. А ты даже в тред нужный зашел, так что в прогеры годишься
619 1436875
Анон помоги плез
<?php
$money=10000;
$age=16;
$count=0;
$procent=10;
for ($money; $money < 1000000; $money= $money+$procentMoney){
$procentMoney = ($money*$procent)/100;
$age++;
$count++;
}
echo "$age -возраст, $count - время, $procentMoney - сумма\n";
?>
Ответ частично правильный:
65 -возраст, 49 - время, 97017.233784872 - сумма, а в ответе написано по другому.
620 1436934
>>36875
Почитай же еще этих интересных уроков про переменные, да повтори циклы.
621 1437000
Пачаны, меня в гитхабе зафолловили пару раз, что мне делать? Там могут быть боты?
622 1437180
когда перекат?
623 1437181
>>34456
И то и другое. Либо node.js
624 1437182
>>34946
Двачую.
Вообще кто кричит что пыха говно, это какие то раки которые никогда не кодили. Они могут сказать что python лучше, только потому что у нее нет скобочек или знака $ на переменной.
Но они не понимают, что скобочка дает возможность проебаться с пробелами . А значок бакса у переменной дает php интерпретатору возможность более быстро работать ,за счет понимания что это переменная и не тратя время на это.
625 1437190
>>37181
Если пыху выучишь и дс, то с нодой за пару дней разберешься.
626 1437192
>>37190
Заебись. Вообще я Пыху почти выучил и js учу, и уже сейчас я могу динамический сайт запилить. Мб ноду выучу для пущего эффекта
627 1437197
>>37192
Там учить-то нечего, просто хороший, годный набор инструментов и местный композер впридачу. Веб там по тем же технологиям работает.
628 1437199
>>37197
А че за тема, я слышал, что можно на ноде делать десктоп приложение это правда?
629 1437203
>>37199
Хз я на её удаленке использую.
630 1437440
>>36875
Анон, ты молодец, все хорошо зделол, только внизу выводи не процент, а сумму, то-есть
echo "$age -возраст, $count - время, $money - сумма\n";
тебе же надо общую сумму вывести. В этом контексте она больше подойдет
631 1437526
пыханы, поясните - массив, используемый в foreach, где-то сохраняется, или каждый раз вызывается? Если использовать результат метода, например
foreach ($db->fetchQuery() as $kek)
то метод будет вызван для каждого элемента, или результат кэшируется и для обхода используется итератор по закэшированному значению?
632 1437639
>>34456
Наизусть выучил? По уроку хауди хо "учим верстку за час" недеюсь?
633 1437666
>>37440
Спасибо большое анон
634 1437769
>>37526
Сначала вызывается функция, она возвращает какое-то значение, с этим значением уже и работает foreach, у всего свой evaluation order так сказатб
635 1438092
Котаны, подскажите такую вещь.
Я использую PDO, запрос примерно так выглядит:
$stmt = pdo->prepare($sql);
$stmt->execute($params)

то есть у объекта pdo я вызываю метод prepare.
Но почему в документации это написано таким образом :
PDO::prepare
т.е. к статический метод класса.

https://www.php.net/manual/ru/class.pdo.php

Почему в документации они так пишут?
636 1438115
>>38092
Интересный вопрос
637 1438119
>>38092

>Но почему в документации это написано таким образом :


>PDO::prepare


я вроде у Зандстры читал, что часто в руководствах пишут эту конструкцию с точками чтобы показать не реальный способ вывода, а дать читателю понять откуда что берется. Хотя, возможно, это мои фантазии, я тот еще пиздабол
638 1438156
>>38092
Возможно что указатель на БД в PDO работает как синглтон, поэтому нет смысла делать объектом.
639 1438170
пацаны предлагают фулстак на yii2 я не умру?
640 1438459
Хотелось бы узнать насчёт английского языка. Часто требуют знать английский ? А то я совсем долбоёб, который даже перевести предложения не может.
641 1438464
>>38459
Минимум "на уровне чтения документации" в любом приличном месте. Начинай учить прямо сейчас. Иди в языкач, там пацаны пояснят что и как.
642 1438745
Не могу определиться с выбором первого фреймворка. Yii2, Laravel или Symfony? С чем будет легче, или надо выбирать посложней? Хочу аргументы для уверенности.
643 1438882
>>38745
При любом выборе ты пидор, сорр
644 1438921
Решаю на Yii2 задачу, помогите пожалуйста.

Создал CRUD на Gii для постов пользователей и с представления на сайте зарендерил update.php
Что нужно сделать чтобы форма update в которой _form.php заработала? Или я пошел не по тому пути? Хочу чтобы там где показывался пост, там и редактировать его
645 1438968
>>38745
Laravel выбирай, самый модный, легкий
646 1439120
>>38745
Лара - самый топ. На ней и пишу. Нравится. Когдато знакомился с yii2 но было это сто лет назад и я ниче не помню. Больше ни с чем не знаком.

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

Хз насколько я прав, но если прав то выбор таков: лара - если хочешь больше вакансий и более легкий вкот. Симфони - если хочешь больше зп, но вакансий поменьше будет и сам фреймворк посложнее
https://github.com/InspektorGadjet/FileSharing 647 1439264
>>29857

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

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

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

Папку src/Project стоило назвать лучше - например, src/FileSharing.

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

Конфиг у тебя закоммичен в гит. Если другой разработчик скачает проект, исправит конфиг, то его данные закоммитятся в гит и у тебя отвалится доступ к БД. Для решения этой проблемы обычно сам конфиг добавляют в gitignore, а в репозиторий кладут образец конфига с комментариями (config.php.dist), который надо скопировать и отредактировать при установке проекта.

> $view = new \Slim\Views\Twig('./templates', [


> 'cache' => false


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

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

php ./bin/upload.php /tmp/image.png

Она загружает файл и выводит ссылку на него. Или же ошибку, если что-то пошло не так. В случае ошибки возвращается ненулевой код возврата ( https://ru.wikipedia.org/wiki/Код_возврата ), при успехе - нулевой.

> use \Psr\Http\Message\ServerRequestInterface as Request;



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

> PDO::MYSQL_ATTR_INIT_COMMAND=>"SET NAMES UTF8",



Почитай про отличия utf8 и utf8mb4. utf8 - это не совсем полноценный utf-8.

> PDO::ATTR_ERRMODE=>TRUE



Тут должна быть не true, а одна из констант PDO::ERRMODE_...

> if (empty($files['newfile']->file)) {


> header("Location: /");


Молча редиректить без вывода сообщения пользователю - плохая идея. Тут правильнее было бы показать страницу ошибки или добавить сообщение об ошибке при редиректе.

Далее, если ты используешь контроллеры, то лучше сразу указывать их как обработчик запроса:

$app->post('/upload', контроллер);

У тебя же получается дублирование: часть кода контроллера ты пишешь в обработчике, часть в классе-контроллере. Какой в этом смысл? Выбери что-то одно, либо обработчик-функция, либо контроллер. А не оба варианта сразу:

$app->post('/upload', function (Request $request, Response $response, array $args) {
...
$controller = new \Project\Controllers\MainController($newfile, $directory, $copyDirectory);

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

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

На всякий случай можешь глянуть урок по MVC, там есть сервисы и пример кода: https://github.com/codedokode/pasta/blob/master/arch/mvc.md

Стоит как-то связать названия шаблонов с названиями контроллеров или обработчиков, так будет проще. У тебя же в URL /files, а шаблон называется чуть по-другому - file_list.php.

> $app->get('/delete/{filename}',



Метод GET предназначен для получения данных и не должен менять данные на сервере. Он не подходит для удаления.

> $fileRecorder = new \Project\Models\FilesDataGateway($pdo);


> $fileManager = new \Project\Models\FileManager();


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

> public function getInfoAboutFile(string $directory, string $serverName)


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

> $fileParameters['filesize'] = $fileManager->getFileSize($info['filesize']);


Вообще, в базу правильнее сохранять размер как число, а не форматированную строку. Так как ты не сможешь например посчитать общий объем файлов в БД.

> if($diff < 3600) {


> return floor($diff / 60) . ' минут назад';


Надо бы полноценно спрягать слова: 1 минуту, 2 минуты, 5 минут. Ну и showDate может быть имеет смысл вынести в utility-класс, эта функция к файлам имеет мало отношения.

> $function = "imagecreatefrom$typestr";



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

case IMAGETYPE_JPEG:
$decoder = 'imagecreatefromjpeg';
$encoder = 'imagejpg';
break;

То есть писать имя функции как есть.

> if ($type = 2) { # jpeg


Надо использовать константу IMAGETYPE...

Непонятно, зачем в функции createToken() сделан цикл.

> https://github.com/InspektorGadjet/FileSharing/blob/master/src/Project/Controllers/ListController.php#L20


> $file->author = $this->filesDataGateway->checkAuthor($this->checkCookie(), $file->serverName);



Здесь ты используешь объект как массив. У тебя нет класса, нет методов, нет определенного списка полей. Не логичнее ли тогда использовать массив? Для них хотя бы разные полезные функции есть.

Также, информацию об авторстве можно было бы получать из БД одним запросом, вместе с данными о файле (получать список токенов и сравнивать их с кукой).

Поле createdAt можно вообще не добавлять, а просто вызывать метод форматирования времени из шаблона.

> https://github.com/InspektorGadjet/FileSharing/blob/master/src/Project/Models/Downloader.php#L14


> header('Content-Disposition: attachment; filename=' . $realFileName);


В заголовках можно использовать только кодировку ASCII (кириллицу нельзя). Надо либо применять специальный способ кодирования, либо заканчивать URL именем файла. Ты можешь глянуть, как это сделано в библиотеке Symfony HTTP Foundation: https://github.com/symfony/http-foundation/blob/master/BinaryFileResponse.php#L147 (хотя они зря используют mb_detect_encoding - она не работает).

> https://github.com/InspektorGadjet/FileSharing/blob/master/src/Project/Controllers/ViewController.php#L20


Здесь нет проверки условия, что такой файл найден. А вдруг его нет?

> https://github.com/InspektorGadjet/FileSharing/blob/master/src/Project/Controllers/ViewController.php#L28


> if(!empty($_POST['comment'])) {


Если там есть объект Request, то правильнее использовать его.

> $info['id'] = $file->id;


> $info['name'] = $file->realName;


Тут проще передать в шаблон сам объект $file, чем копировать все его поля.

> https://github.com/InspektorGadjet/FileSharing/blob/master/src/Project/Interfaces/CheckCookie.php


Это очень странный интерфейс, и я не понимаю, что он обозначает и как используется.

https://github.com/InspektorGadjet/FileSharing/blob/master/src/Project/Models/Downloader.php
Здесь не указано, что делать, если файла нет.

https://github.com/InspektorGadjet/FileSharing/blob/master/src/Project/Models/FileManager.php#L31
Здесь правильно добавить в условие while проверку что position не выходит за границы массива.

> if($dayDiff < 60) {


> return 'в прошлом месяце';


Ну вообще, это неверно. Если сейчас 1 мая, и прошло 59 дней, то это будет позапрошлый месяц. А если сейчас 1 марта, то это может быть и прошлый год.

В проекте нет SQL-дампа.

> $('#mask').css({'width':maskWidth,'height':maskHeight});


> $(id).css('top', winH/2-$(id).height()/2);


А это нельзя сделать средствами CSS? Абсолютным или фикс. позиционированием?

> $('.comment_form').submit(function() {


> if($('textarea[name=comment]').val() == '') {


> $('.messenger').html('Вы не ввели текст');


> event.preventDefault();


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

> alert('Ваш комментарий успешно добавлен');


Слишком рано. Он еще не добавлен.

> href="/view/{{ item.serverName }}"


> src="../copyes/{{ info.copy }}"


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

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

> <p><h2>Комментарий автора:</h2></p>


По правитам HTML внутри p не может быть заголовков. Вот описание тега p из HTML5.2: https://www.w3.org/TR/html52/grouping-content.html#the-p-element

> Content model:


> Phrasing content.



(если кликнуть, будет подробное описание).

Браузер, увидев h2, закроет тег p. Попробуй отправить свой HTML код на валидацию в валидатор: https://html5.validator.nu/ Он должен указать на такие моменты.

> <div class="commets-list">


Тут опечатка в слове comments
https://github.com/InspektorGadjet/FileSharing 647 1439264
>>29857

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

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

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

Папку src/Project стоило назвать лучше - например, src/FileSharing.

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

Конфиг у тебя закоммичен в гит. Если другой разработчик скачает проект, исправит конфиг, то его данные закоммитятся в гит и у тебя отвалится доступ к БД. Для решения этой проблемы обычно сам конфиг добавляют в gitignore, а в репозиторий кладут образец конфига с комментариями (config.php.dist), который надо скопировать и отредактировать при установке проекта.

> $view = new \Slim\Views\Twig('./templates', [


> 'cache' => false


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

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

php ./bin/upload.php /tmp/image.png

Она загружает файл и выводит ссылку на него. Или же ошибку, если что-то пошло не так. В случае ошибки возвращается ненулевой код возврата ( https://ru.wikipedia.org/wiki/Код_возврата ), при успехе - нулевой.

> use \Psr\Http\Message\ServerRequestInterface as Request;



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

> PDO::MYSQL_ATTR_INIT_COMMAND=>"SET NAMES UTF8",



Почитай про отличия utf8 и utf8mb4. utf8 - это не совсем полноценный utf-8.

> PDO::ATTR_ERRMODE=>TRUE



Тут должна быть не true, а одна из констант PDO::ERRMODE_...

> if (empty($files['newfile']->file)) {


> header("Location: /");


Молча редиректить без вывода сообщения пользователю - плохая идея. Тут правильнее было бы показать страницу ошибки или добавить сообщение об ошибке при редиректе.

Далее, если ты используешь контроллеры, то лучше сразу указывать их как обработчик запроса:

$app->post('/upload', контроллер);

У тебя же получается дублирование: часть кода контроллера ты пишешь в обработчике, часть в классе-контроллере. Какой в этом смысл? Выбери что-то одно, либо обработчик-функция, либо контроллер. А не оба варианта сразу:

$app->post('/upload', function (Request $request, Response $response, array $args) {
...
$controller = new \Project\Controllers\MainController($newfile, $directory, $copyDirectory);

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

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

На всякий случай можешь глянуть урок по MVC, там есть сервисы и пример кода: https://github.com/codedokode/pasta/blob/master/arch/mvc.md

Стоит как-то связать названия шаблонов с названиями контроллеров или обработчиков, так будет проще. У тебя же в URL /files, а шаблон называется чуть по-другому - file_list.php.

> $app->get('/delete/{filename}',



Метод GET предназначен для получения данных и не должен менять данные на сервере. Он не подходит для удаления.

> $fileRecorder = new \Project\Models\FilesDataGateway($pdo);


> $fileManager = new \Project\Models\FileManager();


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

> public function getInfoAboutFile(string $directory, string $serverName)


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

> $fileParameters['filesize'] = $fileManager->getFileSize($info['filesize']);


Вообще, в базу правильнее сохранять размер как число, а не форматированную строку. Так как ты не сможешь например посчитать общий объем файлов в БД.

> if($diff < 3600) {


> return floor($diff / 60) . ' минут назад';


Надо бы полноценно спрягать слова: 1 минуту, 2 минуты, 5 минут. Ну и showDate может быть имеет смысл вынести в utility-класс, эта функция к файлам имеет мало отношения.

> $function = "imagecreatefrom$typestr";



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

case IMAGETYPE_JPEG:
$decoder = 'imagecreatefromjpeg';
$encoder = 'imagejpg';
break;

То есть писать имя функции как есть.

> if ($type = 2) { # jpeg


Надо использовать константу IMAGETYPE...

Непонятно, зачем в функции createToken() сделан цикл.

> https://github.com/InspektorGadjet/FileSharing/blob/master/src/Project/Controllers/ListController.php#L20


> $file->author = $this->filesDataGateway->checkAuthor($this->checkCookie(), $file->serverName);



Здесь ты используешь объект как массив. У тебя нет класса, нет методов, нет определенного списка полей. Не логичнее ли тогда использовать массив? Для них хотя бы разные полезные функции есть.

Также, информацию об авторстве можно было бы получать из БД одним запросом, вместе с данными о файле (получать список токенов и сравнивать их с кукой).

Поле createdAt можно вообще не добавлять, а просто вызывать метод форматирования времени из шаблона.

> https://github.com/InspektorGadjet/FileSharing/blob/master/src/Project/Models/Downloader.php#L14


> header('Content-Disposition: attachment; filename=' . $realFileName);


В заголовках можно использовать только кодировку ASCII (кириллицу нельзя). Надо либо применять специальный способ кодирования, либо заканчивать URL именем файла. Ты можешь глянуть, как это сделано в библиотеке Symfony HTTP Foundation: https://github.com/symfony/http-foundation/blob/master/BinaryFileResponse.php#L147 (хотя они зря используют mb_detect_encoding - она не работает).

> https://github.com/InspektorGadjet/FileSharing/blob/master/src/Project/Controllers/ViewController.php#L20


Здесь нет проверки условия, что такой файл найден. А вдруг его нет?

> https://github.com/InspektorGadjet/FileSharing/blob/master/src/Project/Controllers/ViewController.php#L28


> if(!empty($_POST['comment'])) {


Если там есть объект Request, то правильнее использовать его.

> $info['id'] = $file->id;


> $info['name'] = $file->realName;


Тут проще передать в шаблон сам объект $file, чем копировать все его поля.

> https://github.com/InspektorGadjet/FileSharing/blob/master/src/Project/Interfaces/CheckCookie.php


Это очень странный интерфейс, и я не понимаю, что он обозначает и как используется.

https://github.com/InspektorGadjet/FileSharing/blob/master/src/Project/Models/Downloader.php
Здесь не указано, что делать, если файла нет.

https://github.com/InspektorGadjet/FileSharing/blob/master/src/Project/Models/FileManager.php#L31
Здесь правильно добавить в условие while проверку что position не выходит за границы массива.

> if($dayDiff < 60) {


> return 'в прошлом месяце';


Ну вообще, это неверно. Если сейчас 1 мая, и прошло 59 дней, то это будет позапрошлый месяц. А если сейчас 1 марта, то это может быть и прошлый год.

В проекте нет SQL-дампа.

> $('#mask').css({'width':maskWidth,'height':maskHeight});


> $(id).css('top', winH/2-$(id).height()/2);


А это нельзя сделать средствами CSS? Абсолютным или фикс. позиционированием?

> $('.comment_form').submit(function() {


> if($('textarea[name=comment]').val() == '') {


> $('.messenger').html('Вы не ввели текст');


> event.preventDefault();


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

> alert('Ваш комментарий успешно добавлен');


Слишком рано. Он еще не добавлен.

> href="/view/{{ item.serverName }}"


> src="../copyes/{{ info.copy }}"


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

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

> <p><h2>Комментарий автора:</h2></p>


По правитам HTML внутри p не может быть заголовков. Вот описание тега p из HTML5.2: https://www.w3.org/TR/html52/grouping-content.html#the-p-element

> Content model:


> Phrasing content.



(если кликнуть, будет подробное описание).

Браузер, увидев h2, закроет тег p. Попробуй отправить свой HTML код на валидацию в валидатор: https://html5.validator.nu/ Он должен указать на такие моменты.

> <div class="commets-list">


Тут опечатка в слове comments
648 1439606
Блядь, изучая пхп меня не покидает чувство, будто я упускаю что-то очень важное. Вот выдрочу я этот ваш веб, например, максимально впитаю интерпретацию, после чего не смогу в базу и останусь среднестатистической макакой.
Может стоит хотя-бы начальные знания в с++ получить?
649 1439631
>>39606

>Может стоит хотя-бы начальные знания в с++ получить?


Нахуя ?
650 1439633
>>39606

>Может стоит хотя-бы начальные знания в с++ получить?


Когда начнёшь учить C++ смотри чтобы мыслей выучить ассемблер не появилось, а то ты так до ручной пайки транзисторов докатишься.
Первое веб-приложение ты годам к 95 напишешь.

Но это не отменяет изучения самого программирования как скилла, безотносительно платформы(php\js\С++)
651 1439654
>>39633

>Когда начнёшь учить C++ смотри чтобы мыслей выучить ассемблер не появилось, а то ты так до ручной пайки транзисторов докатишься.


Хотеть! Но времени нет, да и старый я уже. То есть можно выдрачивать стек не опасаясь на всегда окуклиться в вебе?
652 1439656
>>39631
Чтобы мое поделие не сжирало 8 гигов оперативной памяти, чтоб быть не как макака с магическим мышлением, а чтоб на кончиках пальцах максимально осмысленно писать код
14304092171050.jpg52 Кб, 800x532
653 1439960
Расскажите про мои шансы найти работу.
Не умею верстать. Знаю только основы html, с гуглом.
Знаю только основы JS, с гуглом. Делал некоторые костыли на jquery уровня "нажать на кнопку по событию". В душе не ебу как работает какой-нибуль React и прочие вебпуки.
Зато в похапе я знаю гораздо больше. Сейчас пишу бек для апи на laravel. Раньше юзал Yii, Code Igniter.
Знаю докер и линух немного. Могу на голом серваке поднять окружение из контейнеров, где будет стоять все говно, что требуется для работоспособности проекта.
Еще у меня такая фишка, что я походу научился писать оче большие приложения + рефакторить. Могу залезть в говнокод проекта и улучшить его (но бля, видит бог, я не хочу таким заниматься). Знаю, как написать архитектуру приложения, чтобы потом не потребовалось рефакторить или же он был как можно проще.

Хуй знает че делать. Сейчас век жс-блядства, чтобы веб-разраб не знал жиэс - это нонсенс.
Плюс пых сам по себе становится все больше никому нахуй не нужен.
Еще у меня есть зайчатки умений в Java и Selenium, могу писать всякую консольную поебень, но, думаю, всем на это похуй
654 1440062
>>39960

>есть у меня такая фишка - ниче не знаю, но все могу


Ты охуенен, когда я выросту. хочу быть какты
655 1440084
>>40062
Ну как-то так, да
656 1440090
>>39960
А какие-то особенные навыки у тебя есть?
То, что вёрстку не знаешь - серьёзный минус тебе же.
657 1440218
Помогите с ajax

$('form').on('beforeSubmit', function(e){
var form = $('form')[0];
var formData = new FormData(form);
console.log(formData);

$.ajax({
url:"$url",
type: 'POST',
data: formData,
cache: false,
processData: false,
contentType: false,
error: function(){
alert('Error!');
}
});

В Yii2 ajax не передает 2 input'a, в одном текст, в другом файл, с контроллером, моделью все хорошо, проверял, здесь выдает Error
525 - 657 658 1440220
>>32619

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

>>34558

Вопросы по схеме БД:

- зачем нужна таблица participant, если есть conference_reference? Я не понимаю, чем таблица participant отличается от conference_reference.
- не стоит ли сделать тип ENUM для message.type, чтобы ограничить список допустимых значений?
- не стоит ли сделать message_attachment.type типом ENUM?
- что за URL указывается в поле message.content? URL на стороннем сервере? На своем? Если на своем, не логичнее ли вместо URL указать внешних ключ на таблицу файлов, либо какой-то идентификатор файла, из которого строится URL? Идентификатор удобен тем, что позволяет в будущем менять вид URL файла.
- возможно, стоит в conference_reference убрать id и использовать в качестве ключа пару (conference_uuid, user_uuid). Например, я вижу, что message_reference уже использует пару (conference, user).

И еще, ничего, что тут приватный ключ лежит? https://github.com/someApprentice/Crypter/blob/master/wamp/.crossbar/key.priv

И еще, не отдаем ли мы тут детали ошибки на сервере пользователю: https://github.com/someApprentice/Crypter/blob/master/wamp/AuthenticatorSession.py#L55

Тут, в тестах, возможно стоило сделать вспомогательную функцию для генерации токенов, так как в них легко опечататься и долго гадать, потому тест не работает: https://github.com/someApprentice/Crypter/blob/master/wamp/tests/authenticator_test.py

Еще, я у тебя вижу комментарии:

> TypeError: exceptions must be old-style classes or derived from BaseException, not <class 'module'>


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

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

Также, немного неудобно, что приходится поддерживать 2 набора сущностей: в Питоне и в PHP.

Что касается исключений при авторизации, мне кажется, их правильнее ловить в обработчике авторизации, а не тут: https://github.com/someApprentice/Crypter/blob/master/api/src/EventListener/ExceptionListener.php Также, не стоит отдавать подробности исключения клиенту, они могут содержать важные внутренние данные.

Тут (https://github.com/someApprentice/Crypter/blob/master/api/tests/Controller/AuthControllerTest.php ) есть такой код:

$client->request(
$method = 'POST',
$uri = '/api/auth/login',

Так писать не стоит, это не keyword arguments из Питона и имена переменных не учитываются никак.

В тестах авторизации ( https://github.com/someApprentice/Crypter/blob/master/api/tests/Controller/AuthControllerTest.php ) ты проверяешь что тебе выдана кука с определенным именем. Ты полагаешься на знание внутреннего устройства механизма авторизации. И наличие куки не гарантирует авторизации. Правильнее запрашивать какую-то страницу для проверки доступа к ней. Можно даже сделать специальный тестовый метод /test/whoami для этого. Также, не надо копипастить огромные полотна кода, можно было сделать вспомогательную функцию для отправки запросов.

Соответственно тесты будут вида canLoginWithValidPassword, cannotLoginWithWrongPassword.

Далее, это ненадежный способ проверки, ведь речь тут о безопасности:

> https://github.com/someApprentice/Crypter/blob/master/wamp/AuthorizerSession.py#L40


> if 'private.message.to.' in uri:



Не лучше ли использовать str.startswith() ?

> regex = re.compile('^private\.message\.to\.([a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12})$')


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

Также, я тут подумал, что для огромных конференций обновление через websocket может потребовать отдельную схему. У тебя, как я понял, при отправке сообщения в групповой чат на 1000 пользователей будет отправлено 1000 уведомлений private.message.to... и conference.updated.for.... Это будет нагружать вебсокет-демон. Логичнее для огромных чатов просто сделать канал updates.{conference_uuid} и слать туда одно уведомление. А клиент пусть отдельным запросом выясняет, что поменялось. Можно конечно слать и само сообщение, но надо убедиться, что кикнутые из чата, но не отписавшиеся от веб-сокет канала пользователи не смогут его получить.

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

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

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


> Было бы лучше если бы приватная конференция имела такой же id как и пользователь. И пользователь сам по себе как бы представлялися как приватная конференция. Тогда можно будет открывать диалог между двумя пользователями без создания отдельной конференция для них.



Этот вопрос можно решить без изменений в БД, на уровне интерфейса. Мы можем, например, сделать URL вида /talk/{userId} и при его открытии смотреть: есть приватный диалог с этим пользователем или нет. Если есть - подгружать данные (либо редиректить на URL с id конференции), если нет - показать пустую страницу. То есть тебе не надо создавать что-то в БД только потому, что пользователь нажал на имя контакта.

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

Твой вариант подразумевает, что если у пользователей A и B есть контакт C, то у них будет общая conference, но четыре разных conference_reference (A + C, C + A, B + C, C + B). Это не очень удачно, на мой взгляд. Не очень понятно, зачем тогда вообще нужна сущность conference и не проще ли из conference_reference, соответствующего диалогу, ссылаться напрямую на пользователя. И это будет создавать путаницу.

Если хочется, чтобы id конференции совпадал с пользовательским, тогда логичнее было бы в качестве id конференции брать отсортированную пару id пользователей. То есть конференция пользователей A и B может иметь идентификатор A_B. А в таблице можно использовать составной ключ:

TABLE conference (
lower_user_id UUID REFERENCES users (id),
higher_user_id UUID REFERENCES users (id),
PRIMARY KEY (lower_user_id, higher_user_id)
)

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

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

TABLE conference (
id UUID PRIMARY KEY,
-- Заполняются только для приватных диалогов из 2 человек
lower_dialog_user UUID DEFAULT NULL REFERENCES users (id),
higher_dialog_user UUID DEFAULT NULL REFERENCES users (id),
UNIQUE KEY(lower_dialog_user, higher_dialog_user)
)

Есть ли какие-то недостатки у такого подхода?
525 - 657 658 1440220
>>32619

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

>>34558

Вопросы по схеме БД:

- зачем нужна таблица participant, если есть conference_reference? Я не понимаю, чем таблица participant отличается от conference_reference.
- не стоит ли сделать тип ENUM для message.type, чтобы ограничить список допустимых значений?
- не стоит ли сделать message_attachment.type типом ENUM?
- что за URL указывается в поле message.content? URL на стороннем сервере? На своем? Если на своем, не логичнее ли вместо URL указать внешних ключ на таблицу файлов, либо какой-то идентификатор файла, из которого строится URL? Идентификатор удобен тем, что позволяет в будущем менять вид URL файла.
- возможно, стоит в conference_reference убрать id и использовать в качестве ключа пару (conference_uuid, user_uuid). Например, я вижу, что message_reference уже использует пару (conference, user).

И еще, ничего, что тут приватный ключ лежит? https://github.com/someApprentice/Crypter/blob/master/wamp/.crossbar/key.priv

И еще, не отдаем ли мы тут детали ошибки на сервере пользователю: https://github.com/someApprentice/Crypter/blob/master/wamp/AuthenticatorSession.py#L55

Тут, в тестах, возможно стоило сделать вспомогательную функцию для генерации токенов, так как в них легко опечататься и долго гадать, потому тест не работает: https://github.com/someApprentice/Crypter/blob/master/wamp/tests/authenticator_test.py

Еще, я у тебя вижу комментарии:

> TypeError: exceptions must be old-style classes or derived from BaseException, not <class 'module'>


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

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

Также, немного неудобно, что приходится поддерживать 2 набора сущностей: в Питоне и в PHP.

Что касается исключений при авторизации, мне кажется, их правильнее ловить в обработчике авторизации, а не тут: https://github.com/someApprentice/Crypter/blob/master/api/src/EventListener/ExceptionListener.php Также, не стоит отдавать подробности исключения клиенту, они могут содержать важные внутренние данные.

Тут (https://github.com/someApprentice/Crypter/blob/master/api/tests/Controller/AuthControllerTest.php ) есть такой код:

$client->request(
$method = 'POST',
$uri = '/api/auth/login',

Так писать не стоит, это не keyword arguments из Питона и имена переменных не учитываются никак.

В тестах авторизации ( https://github.com/someApprentice/Crypter/blob/master/api/tests/Controller/AuthControllerTest.php ) ты проверяешь что тебе выдана кука с определенным именем. Ты полагаешься на знание внутреннего устройства механизма авторизации. И наличие куки не гарантирует авторизации. Правильнее запрашивать какую-то страницу для проверки доступа к ней. Можно даже сделать специальный тестовый метод /test/whoami для этого. Также, не надо копипастить огромные полотна кода, можно было сделать вспомогательную функцию для отправки запросов.

Соответственно тесты будут вида canLoginWithValidPassword, cannotLoginWithWrongPassword.

Далее, это ненадежный способ проверки, ведь речь тут о безопасности:

> https://github.com/someApprentice/Crypter/blob/master/wamp/AuthorizerSession.py#L40


> if 'private.message.to.' in uri:



Не лучше ли использовать str.startswith() ?

> regex = re.compile('^private\.message\.to\.([a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12})$')


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

Также, я тут подумал, что для огромных конференций обновление через websocket может потребовать отдельную схему. У тебя, как я понял, при отправке сообщения в групповой чат на 1000 пользователей будет отправлено 1000 уведомлений private.message.to... и conference.updated.for.... Это будет нагружать вебсокет-демон. Логичнее для огромных чатов просто сделать канал updates.{conference_uuid} и слать туда одно уведомление. А клиент пусть отдельным запросом выясняет, что поменялось. Можно конечно слать и само сообщение, но надо убедиться, что кикнутые из чата, но не отписавшиеся от веб-сокет канала пользователи не смогут его получить.

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

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

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


> Было бы лучше если бы приватная конференция имела такой же id как и пользователь. И пользователь сам по себе как бы представлялися как приватная конференция. Тогда можно будет открывать диалог между двумя пользователями без создания отдельной конференция для них.



Этот вопрос можно решить без изменений в БД, на уровне интерфейса. Мы можем, например, сделать URL вида /talk/{userId} и при его открытии смотреть: есть приватный диалог с этим пользователем или нет. Если есть - подгружать данные (либо редиректить на URL с id конференции), если нет - показать пустую страницу. То есть тебе не надо создавать что-то в БД только потому, что пользователь нажал на имя контакта.

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

Твой вариант подразумевает, что если у пользователей A и B есть контакт C, то у них будет общая conference, но четыре разных conference_reference (A + C, C + A, B + C, C + B). Это не очень удачно, на мой взгляд. Не очень понятно, зачем тогда вообще нужна сущность conference и не проще ли из conference_reference, соответствующего диалогу, ссылаться напрямую на пользователя. И это будет создавать путаницу.

Если хочется, чтобы id конференции совпадал с пользовательским, тогда логичнее было бы в качестве id конференции брать отсортированную пару id пользователей. То есть конференция пользователей A и B может иметь идентификатор A_B. А в таблице можно использовать составной ключ:

TABLE conference (
lower_user_id UUID REFERENCES users (id),
higher_user_id UUID REFERENCES users (id),
PRIMARY KEY (lower_user_id, higher_user_id)
)

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

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

TABLE conference (
id UUID PRIMARY KEY,
-- Заполняются только для приватных диалогов из 2 человек
lower_dialog_user UUID DEFAULT NULL REFERENCES users (id),
higher_dialog_user UUID DEFAULT NULL REFERENCES users (id),
UNIQUE KEY(lower_dialog_user, higher_dialog_user)
)

Есть ли какие-то недостатки у такого подхода?
659 1440221
>>34558

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



Есть возможность в конфиге указать дополнения к pythonpath: https://crossbar.io/docs/Native-Worker-Options/ . Не подойдет ли это тут? Единственное, я не советую привязываться к текущей директории, чтобы ничего не ломалось, когда текущая директория меняется. А привязываться к расположению файла. Либо использовать вспомогательный bash-скрипт, который задаст правильную текущую директорию перед запуском сервера.

Также, ты не очень удачно назвал директорию src, надо было назвать как-то вроде wampserver.

Если ты добавил корень всего в pythonpath, то далее ты просто пишешь что-то вроде: import database from src

Я советую почитать какую-нибудь статью про модули и пакеты, хотя бы эту: https://realpython.com/absolute-vs-relative-python-imports/

Там еще есть relative imports, но мне кажется, тут можно обойтись без них. То есть разберись с модуляим и пакетами в python и тем, как они ищутся. Добавь корневую директорию в pythonpath, и импортируй стандартным способом.

> Можно ли перекодировать исходный файл в Uint8Array а затем обратно в файл, для его сохранения на диск/хранилище?



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

>В документации сказано, что нельзя создать ArrayBuffer сам по себе, вместо этого, нужно создать TypedArray, которым является Uint8Array.



Если мы посмотрим определения, то увидим, что:

- ArrayBuffer - просто представляет набор байт в памяти фиксированной длины. Он не позволяет с ними что-то делать. Чтобы что-то делать с данными, нужно создать представление для доступа к ним: DataView или TypedArray
- DataView - позволяет читать/записывать числа разных размеров в ArrayBuffer
- TypedArray (Unit8Array и другие) - позволяет работать с данными в буфере, как будто это массив чисел определенного типа. Это именно представление для буфера, даже если ты не передаешь буфер или передаешь в конструктор не-буфер, он создает его сам. Как я понял, за TypedArray всегда прячется какой-то буфер, даже если ты его явно не создавал.

Blob - это абстрактная штука, из которой можно читать данные, оптимизированная под огромный объем данных (A Blob object represents a file-like object of immutable, raw data.). Он отличается от ArrayBuffer следующими особенностями:

1) он может собираться из нескольких отдельных буферов, позволяя избежать выделения памяти и копирования данных в одну общую область памяти. Вместо копирования он просто хранит ссылки на исходные буферы. И когда ты делаешь blob.slice(), он просто создает новый блоб со ссылками на куски буферов без выделения памяти и копирования каких-то данных. ArrayBuffer же представляет собой одну последовательную область памяти.

2) он может представлять данные, которые пока не загружены в память, или которых так много, что они в нее не поместятся, или которые потребуют много времени для чтения, и читать их кусками или потоком (методы stream(), slice()). Я подозреваю, что когда ты делаешь slice(), он реально ничего не читает в память и не меняет, а просто создает пометку "взять байты с X по Y из низлежащего блоба".

3) он может содержать информацию о MIME-типе и виде символов конца строки

4) он иммутабелен

5) для него можно создать URL (внутри браузера, он имеет вид blob://12345678) и пользователь может скачать блоб как файл по этому URL.

File это расширение Blob с доп. атрибутами и он представляет существующий файл на диске.

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

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

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

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

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

> Но я не могу понять, Blob и File принимают в конструктор array of ArrayBuffer...



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

> Uint8Array является ArrayBuffer'ом?



Нет, это представление для записи/чтения данных из буфера по одному числу типа uint8 за раз.

Зачем нужен FileReader, когда есть blob.stream(), я не очень понимаю, я думаю, он просто исторически появился раньше (в FF3.6), чем Blob.stream() (это новая экспериментальная технология).
659 1440221
>>34558

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



Есть возможность в конфиге указать дополнения к pythonpath: https://crossbar.io/docs/Native-Worker-Options/ . Не подойдет ли это тут? Единственное, я не советую привязываться к текущей директории, чтобы ничего не ломалось, когда текущая директория меняется. А привязываться к расположению файла. Либо использовать вспомогательный bash-скрипт, который задаст правильную текущую директорию перед запуском сервера.

Также, ты не очень удачно назвал директорию src, надо было назвать как-то вроде wampserver.

Если ты добавил корень всего в pythonpath, то далее ты просто пишешь что-то вроде: import database from src

Я советую почитать какую-нибудь статью про модули и пакеты, хотя бы эту: https://realpython.com/absolute-vs-relative-python-imports/

Там еще есть relative imports, но мне кажется, тут можно обойтись без них. То есть разберись с модуляим и пакетами в python и тем, как они ищутся. Добавь корневую директорию в pythonpath, и импортируй стандартным способом.

> Можно ли перекодировать исходный файл в Uint8Array а затем обратно в файл, для его сохранения на диск/хранилище?



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

>В документации сказано, что нельзя создать ArrayBuffer сам по себе, вместо этого, нужно создать TypedArray, которым является Uint8Array.



Если мы посмотрим определения, то увидим, что:

- ArrayBuffer - просто представляет набор байт в памяти фиксированной длины. Он не позволяет с ними что-то делать. Чтобы что-то делать с данными, нужно создать представление для доступа к ним: DataView или TypedArray
- DataView - позволяет читать/записывать числа разных размеров в ArrayBuffer
- TypedArray (Unit8Array и другие) - позволяет работать с данными в буфере, как будто это массив чисел определенного типа. Это именно представление для буфера, даже если ты не передаешь буфер или передаешь в конструктор не-буфер, он создает его сам. Как я понял, за TypedArray всегда прячется какой-то буфер, даже если ты его явно не создавал.

Blob - это абстрактная штука, из которой можно читать данные, оптимизированная под огромный объем данных (A Blob object represents a file-like object of immutable, raw data.). Он отличается от ArrayBuffer следующими особенностями:

1) он может собираться из нескольких отдельных буферов, позволяя избежать выделения памяти и копирования данных в одну общую область памяти. Вместо копирования он просто хранит ссылки на исходные буферы. И когда ты делаешь blob.slice(), он просто создает новый блоб со ссылками на куски буферов без выделения памяти и копирования каких-то данных. ArrayBuffer же представляет собой одну последовательную область памяти.

2) он может представлять данные, которые пока не загружены в память, или которых так много, что они в нее не поместятся, или которые потребуют много времени для чтения, и читать их кусками или потоком (методы stream(), slice()). Я подозреваю, что когда ты делаешь slice(), он реально ничего не читает в память и не меняет, а просто создает пометку "взять байты с X по Y из низлежащего блоба".

3) он может содержать информацию о MIME-типе и виде символов конца строки

4) он иммутабелен

5) для него можно создать URL (внутри браузера, он имеет вид blob://12345678) и пользователь может скачать блоб как файл по этому URL.

File это расширение Blob с доп. атрибутами и он представляет существующий файл на диске.

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

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

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

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

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

> Но я не могу понять, Blob и File принимают в конструктор array of ArrayBuffer...



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

> Uint8Array является ArrayBuffer'ом?



Нет, это представление для записи/чтения данных из буфера по одному числу типа uint8 за раз.

Зачем нужен FileReader, когда есть blob.stream(), я не очень понимаю, я думаю, он просто исторически появился раньше (в FF3.6), чем Blob.stream() (это новая экспериментальная технология).
660 1440222
>>35080

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

Кука хранится столько, сколько укажешь. Однако, если ты не укажешь время жизни, то она будет храниться до закрытия браузера (это называется сессионная кука, сессия - имеется в виду сеанс работы с браузером, а не PHP-сессия).

>>35520

Изучать придется с основ верстки, CSS, JS. У нас есть задачи в ОП-посте, но только по самым основам.

>>35842

WHERE CONCAT(name, ' ', surname) LIKE '%иван%'

>>35867

Честно говоря для добавления поля в форму делать полноценное приложение с вебпаком, npm, моделями, вью и полмегабайтом кода выглядит как оверкилл.

>>36875

for ($money; ...

Здесь выражение $money ничего не делает (получает значение переменной и выбрасывает его). Надо писать либо так:

for ( ; $money < 1000000; ...

Либо так:

for ($money = 10000; $money < 1000000; ...

>>37180

Надо бы старые вопросы проверить еще.

>>37182

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

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

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

>>37199

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

>>37526

Функция вызовется один раз.

>>38092

Потому что у них так принято. Мне больше нравится писать в такой ситуации PDO#prepare().

Возможно, это навеяно Си++, там ты описываешь тело функции класса похожей конструкцией:

void PDO::prepare() { ... }

(вызов статического метода в Си++ делается как Class.someMethod(), потому путаницы нет).

>>39606

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

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

Я думаю, после этого тебе все станет более-менее понятно. Так как PHP написан на Си и ты сможешь читать его код.

Си++ не очень нужен, можешь изучить, но это просто добавление ООП и шаблонов в Си.

>>40218

Посмотри документацию jquery.ajax, что разрешено передавать в качестве data.
660 1440222
>>35080

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

Кука хранится столько, сколько укажешь. Однако, если ты не укажешь время жизни, то она будет храниться до закрытия браузера (это называется сессионная кука, сессия - имеется в виду сеанс работы с браузером, а не PHP-сессия).

>>35520

Изучать придется с основ верстки, CSS, JS. У нас есть задачи в ОП-посте, но только по самым основам.

>>35842

WHERE CONCAT(name, ' ', surname) LIKE '%иван%'

>>35867

Честно говоря для добавления поля в форму делать полноценное приложение с вебпаком, npm, моделями, вью и полмегабайтом кода выглядит как оверкилл.

>>36875

for ($money; ...

Здесь выражение $money ничего не делает (получает значение переменной и выбрасывает его). Надо писать либо так:

for ( ; $money < 1000000; ...

Либо так:

for ($money = 10000; $money < 1000000; ...

>>37180

Надо бы старые вопросы проверить еще.

>>37182

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

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

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

>>37199

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

>>37526

Функция вызовется один раз.

>>38092

Потому что у них так принято. Мне больше нравится писать в такой ситуации PDO#prepare().

Возможно, это навеяно Си++, там ты описываешь тело функции класса похожей конструкцией:

void PDO::prepare() { ... }

(вызов статического метода в Си++ делается как Class.someMethod(), потому путаницы нет).

>>39606

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

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

Я думаю, после этого тебе все станет более-менее понятно. Так как PHP написан на Си и ты сможешь читать его код.

Си++ не очень нужен, можешь изучить, но это просто добавление ООП и шаблонов в Си.

>>40218

Посмотри документацию jquery.ajax, что разрешено передавать в качестве data.
661 1440252
анончик,
А как выводить из базы данных текст что бы лежал в центре моего новостного блога , без пользовательских авторизаций,
то есть все оффлайн, открывают мой сайт и там сразу все новости по датам .
Я правильно понял, что
Это надо отдельную базу данных делать к которому нет пароля и можно вытягивать без пароля? Или же с паролем, но этот пароль всегда будет лежать в переменной ,в моем php коде? (безопасно ли это?) Ведь новые новости тоже надо будет заносить
662 1440309
Где можно почитать/посмотреть про RESTful api ?
663 1440340
Я оочень крутой прогарммист поцоны вы даж не представляете я о ч круут на Laravel такое пишу вы бы видали
664 1440384
>>40252
Аношка, я сам новичок, но попробую объяснить, остальные поправят. Твой движок/фреймворк коннектится к базе данных через пароль и логин. После того, как он законнектился, твой движок посылает sql-запрос к базе "выбрать все новости". Движок получает ответ от базы, и, если ответ не пустой, выводит новости на страницу. Пароль посетителя/администратора сайта и пароль к базе данных mysql вообще никак не связаны, это разные пароли. Условно говоря, область видимости новостей, которые ты показываешь посетителю, регламентируется не базой данных и ее паролем, а движком/фреймворком/скриптом. Пароль к базе данных всегда есть. Пароль пользователя сайта может быть, а может и не быть.
Ты можешь в своем движке прописать так: скрипт, просто показывай новости всем. А можешь прописать так: скрипт, показывай новости только тем, у кого есть особые куки/сессия/еще что-нибудь. По этому же принципу организовано добавление новостей, добавлять новости через сайт может только тот, у кого есть пароли/куки/особая сессия - это и есть администратор сайта.
665 1440385
>>40384
Не ну получается подключение к mysql всегда скрип выполняет? Для всех (оффлайн) Например mysqli(localhost, dbname, dbpass) и тому подобное.
Регестрация и авторизация через другую таблицу т.е уже новое подключение mysqli(localhost, dbname, dbpass) и т.д . Или как

Спасибо, в остальном исчерпывающе
666 1440389
>>40384
Просто если бд подключена всегда, то когда злоумышленик достанет наш php код, то сможет испоганить всю бд
667 1440390
не могу решить одну задачу 3 часа мне плохо очень что делать(
668 1440396
>>40390
Кидай сюбда
669 1440461
>>40384

>Пароль посетителя/администратора сайта и пароль к базе данных mysql вообще никак не связаны, это разные пароли


Да, но разве пароли админки не лежат внутри бд? Пусть даже в хэш-виде, И если у злоумышленника будет пароль от бд то и будет пароли админа , пусть даже в захешированом виде
670 1440464
Анон а когда человек обновляет страничку при новом чтении session_start(); он пересоздаст человеку сессию или само поймет что сессия открыта? Алсо , в каких случаях сессию надо принудительно закрывать?
671 1440566
>>40389

Часто в БД ставят ограничение, с каких IP можно к ней коннектиться. Например, пишут 127.0.0.1 - только с того же компьютера, где расположена БД, а снаружи нельзя. И злоумышленнику тогда надо сначала получить доступ к этому компьютеру, а не только пароль.

Или фаерволлом закрывают доступ.
672 1440570
>>40464

session_start() работает так:

- если у человека есть кука вроде PHPSESSION (не помню название), и идентификатор в ней указывает на существующий файл сессии, то загрузить данные из него в массив $_SESSION
- иначе сгенерировать новый ид, создать новый пустой файл, создать пустой массив $_SESSION, попросить браузер создать куку с этим id

А по завершению скрипта или при вызове session_write_close данные из $_SESSION сбрасываются в файл.

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

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

Если на твой сайт зайти браузером или роботом без поддержки кук, то новая сессия будет создаваться при каждом обращении к странице с session_start().

Некоторые пишут свою обертку поверх сессий, которая сохраняет данные только при попытке что-то записать в сессию, и не сохраняет пустые сессии без данных.
673 1440571
>>40566

>Часто в БД ставят ограничение, с каких IP можно к ней коннектиться.


Тогда нужно отдельную бд для админа и отдельную для остальных? А то закроется всем доступ к регемтрации
674 1440572
>>40385

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

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

Но ты можешь попробовать реализовать свою модель с разными пользователями. Только попробуй начать с проектирования и продумывания разных ситуаций вроде разграничения доступа (только автор имеет право редактировать комментарий, но все имеют право его читать), предоставления доступа другому пользователю, смены пароля, регистрации и тд.
675 1440667
>>40572

>БД не очень рассчитаны на работу с миллионами пользователей.


а что их заменяет?
676 1440676
>>40571
Нет, ты видимо не понял)
Запросы идут от пользователей на твой сервер - где есть подключение к БД, снаружи нельзя подключиться к БД как пользователь - к примеру mysql -uroot -p, если ты делал mysql_secure_installation, там при настройке можно запретить remote access (удаленный доступ)
677 1440823
>>40222

>Честно говоря для добавления поля в форму делать полноценное приложение с вебпаком, npm, моделями, вью и полмегабайтом кода выглядит как оверкилл.



Так ведь вью тем и хорош что это не реакт, его как и jquery можно просто подключить через скрипт, весит это всё дело 30кб, вроде даже меньше чем jquery. Конечно для той задачи опа вообще никакие библиотеки не нужны, а в реальных проектах (на фрилансе например) 95% времени уже будет подключен jquery поэтому лишнее тянуть явно нет смысла.
678 1440866
Подскажите залетному вкатывальщику в админы. Не могу понять грань веб-серверов, что должен знать админ, что бэкенд разраб. Задачей админа является создание платформы для пыха-кодера? Поднять Апач и необходимые пхп модули, чтобы phpinfo корректно отображалось или что-то ещё? Должен ли админ знать пхп на начальном уровне? В требованиях просто пишут Апач, нгинкс.
679 1440868
Как в Yii GridView обновлять запись в модальном окне? Нажимаешь на карандаш, выходит окно с id записи и редактируешь его.
1.jpg29 Кб, 680x510
680 1440890
Нас котить-то будут или нет?
681 1440892
>>40890

Погоди еще немного, там еще вверху есть неотвеченные вопросы.
682 1440894
>>40461

>Да, но разве пароли админки не лежат внутри бд?


да, но они обычно лежат в зашифрованном виде

>И если у злоумышленника будет пароль от бд то и будет пароли админа


скажу больше, если у тебя, как у злоумышленника, есть пароль к бд, тебе не нужно расшифровывать/менять на свои пароли админа. Ты уже можешь все делать через базу, например менять контент. Идешь в таблицу, где хранится текст страниц, и дописываешь к каждому предложение матерное слово или вставляешь картинку с пенисом.
Другое дело, что альтернативы-то нет. Какую ты можешь предложить альтернативу хранения паролей админа, если не в базе? Тебе верно сказали - можно ограничить доступ по айпи. Еще можно дополнительно в хтакссессе прописать пароль на доступ в папку с админкой. Можно хранить пароль в коде. Но тогда любой, кто чудом достанет твой пароль к фтп, сможет его поменять. Плюс он из файла с конфигом возьмет пароль для доступа к базе.
А зачем усложнять? Если у тебя обычный сайт с новостями, то, во-первых, ты серьезным взломщикам вообще не нужен. Что у тебя воровать? "Ольга Бузова шокировала Анапу голыми прелестями?" Кому эта Бузова нужна-то. Во-вторых, если тебя взломают, ты тупо заходишь в панель управления хостингом, меняешь пароль к фтп, к базе, потом восстанавливаешь базу и все. На все максимум десять минут. Большинство хостеров делают бекапы периодически, так что если у тебя даже резерва нет, просто говоришь им - восстановите мне, и они скидывают архив. Вот если у тебя серьезный магазин с клиентской базой и кредитками клиентов - это да, но там уже другой масштаб
683 1440895
>>40892
спс
684 1440932
>>15604 (OP)
Аноны, иду на вакансию НЕ PHP программиста, но требуют:
Знание PHP на базовом уровне
А какой это уровень? Что я должен знать?
685 1440943
>>40932
Если это вакансия админа/эникейщика, то глубоких знаний в пхп с тебя скорее всего не спросят. В любом случае скажешь, типа, готов совершенствоваться заради вас, дорогой начальник Махмуд Сверхпланович, и самообучаться. А если вакансия на синьера php за 150 тыщ муленов, то, скорее всего, там php чуть-чуть знать да надо
686 1440945
>>40932
Смотри чтобы внезапно не выяснилось, что тебе там ещё серваки настраивать и полы мыть надо.
Я б не совался к таким.
687 1440961
>>40943
>>40945
Так говорится об обучении, просто сам ПХП знать нужно на базовом уровне, а там либо он не нужен\либо нужен, и нужно научиться. А я не понял, что значит этот базовый уровень. ООП хватит или у ПХП для базовиков есть планка повыше.
688 1440966
>>40894

>можно ограничить доступ по айпи


Как? На всю базу?
А нету метода запросить айди через php код?
Типо if(your ip == 127.996.66){
авторизация в качестве админа = true;
}
689 1440969
>>40868
в настройках гридвью где колонки добавь для действия update онклик на жс функцию которая будет открывать модалку
690 1440999
>>40894

>Что у тебя воровать?


Ну если у тебя опозиционны сайт новостей типо медузы,кому то приятно просто будет всю базу тебе сломать.
хотя для этого существуют бэкапы
Но я же не только буду делать именно новостные сайты, верно?
691 1441000
>>40894

>фтп


Это что?
692 1441150
>>35520
Ну блин даже не знаю что и сказать, человеку который проработал 3 года. Я вот джуник и вообще не работал, но даже я думаю что тебе достаточно взять лень в кулак и начать учить что тебе не понятно (этот самый ангуля реакт и т.д) И уж темболее не думаю, что это сложно будет для тебя ,человека у которого база 3 года
693 1441152
>>35784
Нет. открывай другие сайты, уроки по циклам
694 1441162
Мудрый Антон, подскажи что делать , читаю теорию по разу с последующим выполнением задач , но они у меня так криво получаются, или вообще не получаются, в общем я не могу понять логику построения и их решения . Для одупления этого что я должен сделать ?
Пример - не мог несколько часов решить задачу - дан массив с числами, проверьте есть ли в нем одинаковые , последовательные числа
Arr = [1,1,1,3,52]
И вот эту чухню я решал часа два , я совсем говно или можно что то ещё сделать ? Если можно подскажите что
695 1441163
>>41162
Курсы прохожу тут
http://code.mu/tasks/php/
696 1441166
>>41000
FTP (англ. File Transfer Protocol) — протокол передачи файлов по сети.
697 1441198
>>41162
Тебе надо пройти по массиву, каждый раз сохранять предыдущее число, сравнивая его с текущим. Если оно не равно, то можно добавить его в результирующий массив.

Как-то надо решать эту задачу.
698 1441211
>>40894

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


Так они же лежат в конфиге
699 1441215
>>41198
Да проблема в том что я долго решаю детские задачи и не дорубаю логику , есть варианты как то это исправить или это тупо с опытом приходит?
700 1441217
>>41215
с опытом. лучше каждый день по чуть-чуть, чем запоями с большими перерывами.
701 1441242
>>41162
Антон, пойми все что ты делаешь, приходит с опытом. Ты когда маленький был, все время падал. Сейчас ты этого не помнишь, но тогда это было, и было У ВСЕХ.
Если мудрый антоша решает задачу за 5 минут, а ты два часа, это только потому-что мудрый антоша всю свою жизнь сталкивался с математикой, но поверь, когда он начинал, он делал такие же ошибки.
Преимущество "гениев" и мудрых антош только в том, что когда они были маленькие, они были очень близко со схожей тематикой. Эти ребята решали схожие задачи, но в упрощенном стиле (грубо говоря им не тонну песка лопатой перекидать надо было, а всего пару ведер. Тоже напряг, но не такой сильный)И когда выросли их мозг уже привык работать в подобной "логике". Но когда мудрый антоша начинал, он тоже был глупым и долго и трудно все делал.

Главная ошибка всех обучающихся, бросить то, что тяжело дается.

Любой навык, любое действие должно быть выстрадано.

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

Посмотри на друзей левшей. Посмотри на одноруких, одноногих, кто не сломался, адаптировался.

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

Единственное, что от тебя требуется, это каждый раз, не через большие промежутки времени (лучше каждый день), по чуть чуть, пытаться решить задачу . Полчаса, час, но каждый день. И ты научишься всему.
702 1441393
>>41242
Хорошая речь, жаль не все прислушаются
703 1441408
>>41242
Очень хорошо написал все, мотивирует заебись!
704 1441436
Анон где можно почитат что-нибудь полноценное про авторизацию, и какую именно выбирать, а то куча всего: куки, сессии, аутентификация, S_SERVER[]. И не понятно что с чем смешивать и в какой очередности юзать
705 1441776
Что читать по PHP? Хотел почитать книгу Локхарта (Современный PHP...), только там похоже еще PHP 5. По JS много хороших новых книг появляется, а по PHP как то глухо. Что посоветуете?
706 1441834
PHP является самым совершенным языком для веб 3.0. Только он обладает этими потрясающими качествами:

- на нём работает 80? веба ( https://w3techs.com/technologies/overview/programming_language/all ). Это означает широкую поддержку и массу вакансий
- никогда не зависает, потому что каждый скрипт завершается вместе с запросом
- очень быстрый, начиная с версии 7.1 гораздо быстрее ноды и питона, в том числе благодаря технологиям оптимизации (memcache, opcache, etc)
- в версии 8 (уже осенью) появится предзагрузка постоянных данных и JIT- компиляция, что сделает его ещё быстрее
- поддержка всех современных СУБД, от Postgres и MS SQL до Redis и Mongo
- при лаконичном Си-подобном синтаксисе, инструментарий для разработки практически не уступает Java и C#
- поддерживает машинное обучение даже на виртуальном хостинге
- написан на святом C++, можно дописывать свои расширения
- при необходимости, легко реализуема асинхронность и очереди событий
707 1441835
>>41776
скляр, симдянов
708 1441836
>>41776
Matt Zandstra Php Объекты Шаблоны. Книга лютая годнота, но там чисто ООП.
709 1441838
>>41834
Только причём тут веб 3.0?
710 1441841
Столкнулся со странным явлением, посылал запрос на апдейт базы данных, не получалось. После того как пхпмайадмине вручную послал запрос на обновление строки она обновилась и начала меняеться помощью пхп, но остальные строки по прежннему не апдейтеться, втф?!
711 1441850
>>41841
по прежнему чудеса, бился несколько часов, написал на двач и за минуту все заработало, всего лишь заключил все переменные запроса в скобки. Но все равно нихуя не понял так как пробовал уже такой способ.
712 1442021
>>41835

>скляр, симдянов


Годно, спасибо.

>>41836

>Matt Zandstra Php Объекты Шаблоны. Книга лютая годнота, но там чисто ООП.


Не совсем то что мне нужно. В любом случае спасибо.
713 1442067
>>15604 (OP)
Все юзают линукс в итт?
714 1442079
>>42067
Не все конечно, по любому есть еще пользователи MacOS и некоторое количество пользователей Windows. Я когда начал изучать программирование, тоже много слышал про Линуксы, что они лучше подходят для этого дела. В какой то момент решил попробовать, и с тех пор Линукс единственная ОС которую я использую. Как минимум стоит попробовать. Ничего не потеряешь, получишь новый опыт, и возможно поймешь что это твое.
715 1442080
>>42079
Ну я пользовался лет 5, мне просто интересно стало, много ли его юзают конкретно программисты.
716 1442082
>>42067
нет
717 1442101
>>42067
Линкус? Ты ополоумел? А играть как?
718 1442112
>>42101
плойка
719 1442133
>>42079
Я на маке щас, оч годная ос.
Но я хочу винду, по одной простой причине - игры.
Так уж вышло что монополист виндовс захватил основную массу потребителей и все почти игроделы пилят именно на этой платформе.
720 1442197
>>42101
>>42133
А если откинем игры(не нужны) то линукс выходит маст хэв?
721 1442212
>>42101
Играть вполне можно... Ну и есть дуалбут в конце концов!
722 1442298
>>42197
Лучше конечно работать в какой-то виртуальной среде где уже все зависимости установлены, но если у тебя < 8 гб памяти то сразу мимо. Мне в каком-то проекте нужно было sass компилить, и тут нода, которая в виртуалке, начала высирать ошибки про симлинк и т.п., там какие-то траблы с тем как винда лочит файлы и вот это всё, я ничего не понял короче и просто установил ноду на шиндовс, и она уже компили прям с винды мне эти sass файлы. После этого вспоминаю дни когда я пытался на какой-то некроноут аудио дрова поставить.
723 1442315
>>42197
Скорее да чем нет.
Видяра говно сама по себе, глюченое, ядро плодит мусор.
Из плюсов всякий софт типо фотошопа, и еще парочки годных редких программ для архитекторов\видеомейкеров\3д мейкеров.
Все, на этом плюсы кончаются.
Линкус = идеальная скорость, качественное ядро. Минусы: нехватка нескольких ПО-гигантов . И иногда немного ебабинга с настройками ( для новичков)
724 1442317
>>42315
>>42197

Забыл добавить: Мак такой же пизатый как линукс ,ибо произошел от UNIX.
Но мак дорогой. поэтому я плюсую линуксу в "маст хэв ,ноу гейм"
725 1442326
>>42197

>маст хэв?


Знать - обязан. Почти весь веб на этом работает.
Нравится - не нравится, это уже никого не касается. так-то вполне даже отличная ОСь только не десктоп-версии для пердоликов
726 1442346
>>42326

>Знать - обязан


А что именно надо знать на нем? Кроме обычных команд консоли
727 1442348
>>42326

>только не десктоп-версии для пердоликов


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

>Кроме обычных команд консоли


Это какие?

>что именно надо знать


Мочь софт поставить\собрать, веб-сервер поднять LAMP тот же, конфиги и софт основные, права как раскидать. Ну базовые для пользователя вещи - ты ж не админ.
729 1442366
>>42349

>Это какие?


Ну там перемещение по каталогам, копирование одной папки в другое место, скачать \ распоковать\ установить,
установить права с chmod

>Мочь софт поставить\собрать,


По сути это все фигня, хотя бывает что надо собрать из исходников прогу(это уже позаебистее, но почти всегда есть пошаговые инструкции) я раньше мог ,но щас забыл. Все гуглится, просто где то надо прям долго читааать гугл пока найдешь что надо.
>веб-сервер поднять LAMP тот же, конфиги и софт основные
Та же фигня, сложность бывает только из-за конфиликтов версикй, когда внезапно твой мак линух апает версию, а LAMP ты скачал какой-то старый и открыл инстуркцию , сделал , а все не работает. Тогда ищешь другие версии\инструкции.
Это все я уже делал, но щас благополучно забыл . Думаю потом с гуглом разберусь, если нужно будет
730 1442371
>>42366

>с гуглом разберусь


Пресвятой Гугл всегда выручает в нашем нелёгком деле.
731 1442386
>>42346
Как работать с пакетами, с файловой системой, с конфигурированием, чтобы мог установить и настроить базу данных, веб-сервер, автоматизацию настроить.
732 1442387
>>42366
Сейчас есть докер, поэтому собирать что-то вообще не нужно. Да и в нормальных дистрах все уже собрано. Плюс есть всякие brew и прочее.
733 1442420
Как можно сохранить весь консольный вывод в файл/переменную?
734 1442444
>>42420
команда > файл.txt. Можно дописывать в файл новые строки не удаляя всего содержимого, нужно использовать >>. В KDE, в стандартной утилите konsole можно сохранить через меню 'файл'.
735 1442447
>>42420
Мы тебе гугл что ли?
736 1442522
Учебник ОПа - это лучшее собрание туториалов для любого истинного новичка-вкатывальщика. Я искренне говорю, что не смог найти ровным счётом ничего на английском языке даже близко стоящего с ОПовым сайтом по степени доступности и объёма материала. Я плохо искал? Вопрос не риторический.
737 1442530
>>42447
Да я вопрос не так сформулировал, там всё сложнее. Но я уже разобрался.
738 1442559
>>20374

>Саблайм — неплохой


Дальше не читал
739 1442754
Все правильно сделал?
740 1442757
>>42754
Ну, помимо того что нет защиты от инъекций.
741 1442789
>>42754

>$zapros


Говнокод.
742 1442798
Анон, почему не робит куки?
Может ли это быть потому что и в 1 коде и 2 перед установкой куки и считыванием есть строки с echo?
743 1442799
>>42798
Причем код выполняется,на экране есть
cookie /'hh/'
home YES 2 ! !!! welcome hh
744 1442804
>>42754
Да чет ты кажется все спутал.
Где подкобючение к бд?
connection = new Mysqli(параметры бд..)
И зачем ты создал глобальную переменную скл и не вставил туда ничего? А потом проверяешь ее на содержимое? Вместо нее как раз должна быть подключение к бд и передаваться в mysqli_query(connection, zapros)
745 1442806
>>42789
Первый пошел.
Я намеренно использую такое название, потому что $request и $queue неприятно писать.
746 1442810
>>42804
Все это есть в отдельном require_once(data-control/connect.php) и там вроде все правильно. Вообще, я хотел обратить ваше внимание на безопасность.

Ну, Буду считать что я все сделал правильно. И в том числе что подорвал пердак одному PSR-4-эстету
747 1442811
>>42810
Еси все работает то че ты принес свои скрины тогда?
748 1442812
>>42811
Тогда извиняюсь. Я думал что безопасность тоже важна.
749 1442813
>>42798

>Может ли это быть потому что и в 1 коде и 2 перед установкой куки и считыванием есть строки с echo?


Скорее всего.
750 1442815
>>42812
Ну добавь себе это
https://www.php.net/manual/ru/function.htmlentities.php
когда получаешь значение из POST и после фильтровки записывай в переменные. И уже потом работай с ними.
Вот это можешь добавить.
https://www.php.net/manual/ru/mysqli.prepare.php
751 1442820
>>42813
Поставил установку куки в начале файла. Все равно не робит
752 1442825
>>42820
Скинь весь код на пастбин.
753 1442827
>>42806

>$request и $queue неприятно писать


Лул. Неприятно тебе, а пошёл я?
Уноси говнокод.
754 1442828
>>42827
Унес.
755 1442877
Где лучше ставить htmlspecialchars()? При записи в бд или уже при выводе в шаблоне?
756 1442915
Сап двач. Есть вопрос по бд. Представим что у нас есть несколько таблиц: users, groups(какие-то группы, в которые пользователь может вступать), group_user(many-to-many табла). Изначально group_user имеет такие поля как: id, group_id, user_id. Есть ли смысл убрать вообще id(я по нему так-то никакие запросы не делаю, может и места будет меньше занимать) и сделать композитный ключ (group_id, user_id) или (user_id, group_id) - тут уже я так понял нужно смотреть по какому полю чаще запросы идут. Получается что и на уровне бд я полностью исключу вариант когда пользователь вступает в группу два раза
758 1442930
>>42877
Когда ловишь значения из POST , фильтруешь их этой функцией, а потом присваиваешь их своим переменным. С которыми уже работаешь . (вместо того, что бы работать сразу с $_POST['name'] ...)
759 1442943
>>42929
Блин. Просил выложить весь код а ты выложил только два файла.
Ладно, из того что знаю могу посоветовать:
1) Сделать куки доступным для всего домена и поставить таймер побольше.
setcookie('name', $login , time()+3600, "/");

2) Проверить инклуды и рекваиры.

3) Проверить куки в index.php через print_r или var_dump. Так-же проверь его еще где-нибудь, например перед самым его созданием.

4) Научись кодить красиво.
760 1442949
>>42943

> Проверить куки в index.php через print_r или var_dump. Так-же проверь его еще где-нибудь, например перед самым его созданием.


Print_r($_COOKIE); выдает это : Array ( [PHPSESSID] => 31f87f3b000efea42132e9c69e9dd4a3 )

> Просил выложить весь код а ты выложил только два файла.


Там просто остальные файлы не свзаны с куки

>4) Научись кодить красиво.


Постараюсь.
Спс.
761 1442952
>>42949

>Array ( [PHPSESSID] => 31f87f3b000efea42132e9c69e9dd4a3 )


Ну вот. Куки не содержит hh.
762 1442958
>>42952
Почему? Я ведь когда устанавливаю куки так же рядом в строчке вывожу эхо. Значит код дошел до этого момента.
763 1442972
>>42952
Все, заработало.
В 1 раз я куки установил в конце файла, поэтому echo сбивал мне его.
Потом я поставил его в начало файла, и не заметил что POST 'login' у меня иниицируется после. Сейчас поставил сразу после лолви POST'login'
764 1442981
765 1442986
>>42981
Збс, как раз хотел его учить.
Начну сразу с 6
766 1443006
>>42986
а какая разница-щас или потом?
767 1443012
>>42929

>$_MYERRORS += $conn->error;


Нихуя се.
768 1443044
>>43006
Ну просто, свежачок Хотя я понимаю, что разницы особо не будет
>>43012
Что ))
769 1443095
>>27166
да здраствует руби!
770 1443106
Как генерируются веб страницы ? Допустим создаёшь тред на дваче и генерируется веб страница. Как это работает ?
771 1443110
>>27142
вот же ебучий пиздабол. пугает вкатывальщиков бедных. иди нахуй сын дерьма. работы дохуя, так шо вкатывайтесь ребятишки
772 1443116
>>43106
Бывает клиентский и серверный рендеринг. Так просто это не объяснишь. Фреймворки попробуй, в них это реализовано.
773 1443126
>>43110
но язык все равно стремный
774 1443130
>>43106
Жмякаешь создать тред, посылается запрос по http+ssl,
сервер смотрит что ты хочешь . ему приходит мол вот такой вот айпиадрес хочет тред создать , чекают тя по бан листу , ты чист? тогда сервер выдает ответ тебе. Мол тред создан. Ну и их бд заполняется твоим новым тредом и он виден всем после обновления стр. Или в реалтайме если там есть js скрипт
775 1443132
>>27142
Самое смешное, что на php больше всего ваканский среди всех языков.
мимо чекер hh ru 2-3 раза в неделю в течении года.
Но во всем интернете все почему то верят что php мертв, видимо это какой-то сломанный телефон.
776 1443133
>>43126
Тому кто с Си-подобного языка перекатывается будет оч легко и даже приятно
Mda 777 1443518
Только начал, ничего не понял. Что не так с 5 строкой? Дальше я нагородил бреда, но сейчас интересует именно 5 строка.
Пишет следующее: unexpected '$anonDice1' (T_VARIABLE) in /home/byLiQ5/prog.php on line 5
https://ideone.com/rUS82j
778 1443541
>>43518
В 3 строке точку с запятой забыл. Всегда смотри на предыдущие строки, ошибка может быть там!
779 1443582
>>43541
Спасибо, там действительно ошибка. Дальше пока сам посмотрю.
780 1443983
Анины, какой фреймворк начинать учить новичку? Ляравель или Симфони? Или уи"?
781 1444008
Решил задачу со списком студентов.
https://github.com/Onethity/studlist
Если кому не лень, то гляньте пожалуйста косяки.
782 1444025
Котомальчики, поясните мне про фреймворки. Вот сейчас я сижу и смотрю уроки по Ляравелю. Там автор все подробно объясняет, берем опенсервер, устанавливаем, потом берем компосер, потом делаем то-то в командной строке. У меня как у новичка возникает вопрос - что я получу на выходе и как это вообще установить на работающий сервер к хостинг-провайдеру?
Раньше я думал, что у меня есть файлы проекта. Мне не нужен сервер, мне не нужен компосер, есть архив с самописным движком. Я меняю там шаблоны под заказчика, прописываю пароли в конфиге, копирую дамп базы, поднимаю базу там - у провайдера, потом копирую файлы сайта к хостеру и все, сайт работает.
Но уроки Ларавеля сбили меня с толку. Я могу получить на входе просто файлы? Просто папку с файлами и дамп базы? Или мне нужно будет и у провайдера на сервере компосер устанавливать и делать кучу сложных вещей, вместо того чтобы просто взять-скопировать на рабочий сервер готовую копию, которую мне дал Ларавель, и счастливо засмеяться?
783 1444030
>>44008
Пока есть свободная минута. Первое что бросается в глаза:
1. 1 класс 1 файл. Без исключений. Сделай папку Exception и туда сложи все кастомные исключения.
2. Не смешивай стили именования переменных и функций.
Читай PSR-1/2/4: https://www.php-fig.org/psr/
3. Ты бросаешь исключения в никуда. Нужен обработчик, который будет писать в лог хотя бы. https://github.com/codedokode/pasta/blob/master/php/exceptions.md

>>43983
Symfony + ApiPlatform -> Laravel (опционально) если времени много. Laravel (Eloquent -> Doctrine) -> Symfony если нужно быстрей искать работу. хУй под конкретные вакансии в мелких городах.
784 1444041
>>44030
Спасибо, добра тебе
785 1444065
>>44025

>что я получу на выходе и как это вообще установить на работающий сервер к хостинг-провайдеру?


Представим что тебе не повезло и хостер дает только доступ по фтп, а ты пишешь не на вордпресе а на каком-то фреймоврке. Руками прокидываешь папку vendor, папку node_modules(если есть, удачи это говно по фтп отправить) - готово

Представим что можно подключиться по ssh, а заказчик настолько продвинутый что юзает гит и на проде никто ничего не лезет блять трогать.
подключаешься по ssh, git clone/pull, composer install - готово
786 1444077
>>44065
спасибо, пойду разбираться
787 1444080
>>44030
Спасибо большое, поправлю на днях.
Анон с задачкой
788 1444131
Ребят, как учить Ларку и другией фреймворки? Документация, видео, книги, статьи. С чего из этого начинать? Направьте пожалуйста
789 1444226
>>44131
Открывай доки и делай бложик с коментами. Тащетма секретов тут никаких нет.
790 1444234
>>44131
тебя ждет хардкор
791 1444237
>>15604 (OP)

САП, пхп-товарищи, есть вопрос.

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

Задача: сделать тестовое:
"Развернуть на laravel 5.2 приложение, со следующими частями:
1) Пользователи - могут регистрироваться, авторизовываться и писать друг-другу сообщения (не обязательно чатик в реальном времени, просто возможность послать сообщение другому пользователю и прочитать сообщение)
2) База - postgresql
3) Система - ubuntu 14.04 lts (если есть возможность - развернуть через virtualbox + vagrant на windows-машине)
4) Если хватит времени - можно написать unit-тесты (не обязательно)"
Если бы задача была на Джанге, в принципе, я бы сделал.

Вопрос: есть ли годная книжка по ларавель/пхп или мануалы, которые помогут за неделю-две влезть до уровня, на котором это задание можно решить с учетом предыдущего опыта?
792 1444240
>>44237
Для php гугли на трэкерах profit php. Полистай на быстрой промотке основные моменты.
Для Ларавеля: laracasts и "Let's Build A Forum with Laravel and TDD" (там за несколько первых уроков будет все что нужно для твоего задания).
793 1444243
>>44240

Спасибо, анон.
794 1444319
Сап двощ, как бы вы сделали фичу Непрочитанные сообщения в чятике? Имеет ли смысл просто сделать какое-то поле unread_messages: (count) и обновлять его на уровне приложения чтобы каждый раз не высчитывать для каждого чата это непрочитанное сообщение (у которого может быть тоже поле например seen: true|false)
795 1444340
Какую СИСТЕМУ ДЕПЛОЯ вы используете?
Раньше я, как честный долбоеб, хуячил все прямо на продакшн и горя не знал.
Потом изобрел деплой через GIT.
На тестовый серв хуячу все через ftp, проверяю, когда фича сделана - комичу в гит, а потом на продакшене делаю pull.
Точнее у меня там небольшой bash-скрипт, но суть такая.

И бля, это вполне себе заебись работает.
Апдейт в одну кнопку буквально. Продакшн никогда не падает теперь.

Какие есть еще более профессиональные варианты?
796 1444343
>>44319
Тупой вопрос, все зависит на 100% от архитектуры твоей БД.
Где-то инфа о количестве записей доступна по-дефолту, где-то она получается быстро, где-то медленно и имеет смысл делать отдельный счетчик.
Все по-разному.
797 1444357
>>15604 (OP) (OP)
https://github.com/asdasdasdasddasasdasdas/StudentList
Чекните список студентов пожалуйста.
798 1444358
Делаю задание с игрой в кубики, и у меня возник вопрос. Почему если я в 22 строке вместо "elseif" напишу просто "else" то у меня возникает ошибка?
И ещё вопрос по поводу 16 строки. Почему в этом гайде при выпадении даблов игра заканчивается? Ведь даблы могут выпасть разные, а не одни и те же. Соответственно будет победитель и проигравший. Собственно по скрину видно что выиграл компьютер.
Автор специально допустил эту ошибку?
На второй пикче я сделала игру честной. Правильно надеюсь?

И ещё вопрос по поводу того как сделал эту же задачу этот >>43518 анон. Он же наебался, разве нет? В 16 строке у него может вылезти "1 и 1" и "6 и 6" при этом ему напишут что у него ничья. А в 19 строке у него может быть "1 и 1" и "5 и 6" при этом ему напишут что победил "1 и 1". Разве нет?
Не ругайтесь только если я чего то не понимаю, изучаю пхп всего час и возможно чего то не поняла.
799 1444458
>>44358

>просто "else" то у меня возникает ошибка?


Смотри синтаксис языка - условные операторы. Как-то так называется.

>Автор специально допустил эту ошибку?


Не баг, а фича.
Так надо.

>в 19 строке у него может быть "1 и 1" и "5 и 6" при этом ему напишут что победил "1 и 1". Разве нет?


Дабл сильнее суммы. Это вроде как в покере.
800 1444462
>>44226
Спасибо
801 1444473
>>44458

>Дабл сильнее суммы. Это вроде как в покере.


Но ведь смысл игры в том, что у кого больше сумма чисел, тот и побеждает...
802 1444514
>>44473
Сумма чисел у тебя есть всегда, какие бы кубики не выпали, а дабл бывает несколько реже.
803 1444527
>>44514
В любом случае, у того анона сначала бы написало, что победило "1 и 1", потому что даблы побеждают недаблы, а чуть ниже написало бы что победило "5 и 6", потому что сумма чисел больше. Потому я и написала что у него ошибка.
804 1444532
>>44527
Ну там порядочно так if - else, в которых легко запутаться. Слишком много их городить не стоит в коде и лучше выносить в функции.
658-804 805 1444775
>>44358

else значит "иначе" и после него не пишут условие. elseif значит "иначе, если ..." и после него пишут условие.

> И ещё вопрос по поводу 16 строки. Почему в этом гайде при выпадении даблов игра заканчивается?



Потому что если выпали даблы у обоих игроков, то это ничья и уже не важно, у кого больше очков. Такие условия. Если только у одного - то это ничего не значит. Там можно вместо exit просто сделать один большой блок if/esleif с четырьмя ветками.

Анон из >>43518 сделал игру немного по другим правилам.

Во втором примере кода не нужен exit и можно последний elseif заменить на else.

>>44357

А где composer.json/composer.lock? Надо убрать их из gitignore, и добавить на гитхаб, иначе как скачавший установит зависимости? То же самое с .htaccess, его надо добавить на гитхаб.

Про конфиг надо написать инструкцию в README.

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

>>44319

Как правило, имеет, так как выгода от быстрого получения цифры превышает затраты на реализацию этой фичи. Иначе придется делать запросы, обходящие большое число записей в поисках непрочитанных.
806 1444776
>>44340

Я видел в основном самописные системы на bash-скриптах. Либо при коммите в мастер запускается баш-скрипт, либо вручную запускается при деплое.

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

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

Кто-то пишет скрипты на ansible. Это полезно, когда у тебя будет больше одного сервера и надо массово выполнять на них какие-то команды.

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

>>44025

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

При этом Ларавель может потребовать поменять какие-то настройки в php.ini или установить расширения к PHP, если хостер это не позволяет, то он не подходит.

>>43518

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

Также, твой код оформлен не по PSR-1 и PSR-2. Скобки ставятся так:

if (...) {
...
} else {
...
}

Тяжело читать нестандартное форматирование.

exit в конце не требуется.
806 1444776
>>44340

Я видел в основном самописные системы на bash-скриптах. Либо при коммите в мастер запускается баш-скрипт, либо вручную запускается при деплое.

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

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

Кто-то пишет скрипты на ansible. Это полезно, когда у тебя будет больше одного сервера и надо массово выполнять на них какие-то команды.

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

>>44025

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

При этом Ларавель может потребовать поменять какие-то настройки в php.ini или установить расширения к PHP, если хостер это не позволяет, то он не подходит.

>>43518

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

Также, твой код оформлен не по PSR-1 и PSR-2. Скобки ставятся так:

if (...) {
...
} else {
...
}

Тяжело читать нестандартное форматирование.

exit в конце не требуется.
807 1444777
>>43106

Браузер соединяется с сервером и отправляет на него HTTP-запрос (просьбу предоставить страницу по определенному URL). Сервер обрабатывает его и дает HTTP-ответ, содержащий тело страницы (обычно это текст с разметкой HTML), а браузер отображает страницу на экране. Если страница содержит дополнительные элементы (например, картинки, видеофайлы, таблицы стилей CSS, программы на языке яваскрипт), то браузер для каждой делает отдельный HTTP-запрос по такому же принципу.

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

Подробнее описано в моем уроке, в разделе "статические и динамические сайты": https://github.com/codedokode/pasta/blob/master/soft/web-server.md#статические-и-динамические-страницы

>>42877

При выводе в шаблоне. А вообще, есть шаблонизаторы, которые это делают сами.

При записи в БД делать это неудобно, так как, например, кодирование меняет длину строки и затрудняет её поиск (так как символы могут быть закодированы). Ну представь, что тебе надо найти в БД строки длинее 15 символов. Тебе придется извлечь все строки из БД, раскодировать их, и сделать проверку. А если бы они были в исходном виде, хватило бы SQL-запроса WHERE LENGTH(x) > 15.

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

>>42930

Ты даешь вредные советы. Так делать очень неудобно. Посмотри, что я написал выше по этому поводу.
808 1444778
>>42798

Ты можешь посмотреть параметры куки в инструментах браузера. Открой их (F12 или Ctrl + Shift + I) на вкладке Resources, там открой список кук и посмотри. Также, ты можешь увидеть установку куки, если откроешь вкладку Network, обновишь страницу, посмотришь заголовки ответа сервера и заголовок Set-Cookie.

>>42915

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

>>42754

Качество кода пока низкое. Нужно доделывать.

Нет, у тебя SQL инъекция. Читай, например, мой урок: https://github.com/codedokode/pasta/blob/master/security/sql-injection.md

В запросе надо явно указать названия полей: INSERT INTO table (f1, f2, f3) VALUES ..., иначе при добавлении колонок в середину таблицы этот код сломается.

Глобальные переменные в общем плохая идея.

При использовании mysqli надо писать в лог подробности ошибок, иначе ты потом о них не узнаешь. Сейчас у тебя просто отдается сообщение пользователю, а в чем была причина не фиксируется. Смотри пример кода тут: https://www.php.net/manual/ru/mysqli.quickstart.prepared-statements.php

В примере кода 2 нет проверки функций mysqli на то, что они вернули ошибку.

Только echo там надо заменить на trigger_error(текст, E_USER_ERROR) для передачи ошибки в стандартный обработчик ошибок PHP.

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

Вместо цифровых кодов ошибок надо сделать константы - для читабельности, сравни свой код и это:

const AUTH_INVALID_PASS = 2;
....
showDeniedPage(AUTH_INVALID_PASS);

Имена функций принято начинать с глагола. Код стоит оформлять по рекомендациям PSR-1 и PSR-2.
808 1444778
>>42798

Ты можешь посмотреть параметры куки в инструментах браузера. Открой их (F12 или Ctrl + Shift + I) на вкладке Resources, там открой список кук и посмотри. Также, ты можешь увидеть установку куки, если откроешь вкладку Network, обновишь страницу, посмотришь заголовки ответа сервера и заголовок Set-Cookie.

>>42915

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

>>42754

Качество кода пока низкое. Нужно доделывать.

Нет, у тебя SQL инъекция. Читай, например, мой урок: https://github.com/codedokode/pasta/blob/master/security/sql-injection.md

В запросе надо явно указать названия полей: INSERT INTO table (f1, f2, f3) VALUES ..., иначе при добавлении колонок в середину таблицы этот код сломается.

Глобальные переменные в общем плохая идея.

При использовании mysqli надо писать в лог подробности ошибок, иначе ты потом о них не узнаешь. Сейчас у тебя просто отдается сообщение пользователю, а в чем была причина не фиксируется. Смотри пример кода тут: https://www.php.net/manual/ru/mysqli.quickstart.prepared-statements.php

В примере кода 2 нет проверки функций mysqli на то, что они вернули ошибку.

Только echo там надо заменить на trigger_error(текст, E_USER_ERROR) для передачи ошибки в стандартный обработчик ошибок PHP.

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

Вместо цифровых кодов ошибок надо сделать константы - для читабельности, сравни свой код и это:

const AUTH_INVALID_PASS = 2;
....
showDeniedPage(AUTH_INVALID_PASS);

Имена функций принято начинать с глагола. Код стоит оформлять по рекомендациям PSR-1 и PSR-2.
809 1444779
>>42811

Для проверки кода очевидно.

>>42815

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

>>42827

Не надо так писать, если не можешь помочь, то лучше ничего не пиши.

>>41841

Без кода не помочь.

>>41436

Самые популярные варианты - это либо сессия, либо куки.

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

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

Как сделать БД пользователей - это просто таблица с данными о них. При регистрации в нее вставляется новая запись. Пароли стоит хранить в безопасной форме: https://github.com/codedokode/pasta/blob/master/security/password-hashing.md
810 1444780
>>41162

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

Могу посоветовать сайт https://codeforces.com/problemset Там есть очень сложные задачи, потому начинать советую с тех задач, которые решили большое число человек (пример: https://codeforces.com/problemset/problem/1183/A ). Если захочешь решать более сложные, придется погуглить про решение олимпиадных задач.

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

>>35784

Надо показать код, спросить совета и попросить дополнительные задачи на циклы. Раз уж мы заговорили про циклы, вот тебе задача. Дан массив со списком букв вроде такого: ['a', 'b', 'd', 'c', 'a', 'b']. Найди в нем все буквы, которые встречаются не 2 раза (то есть 1 или более 2 раз), убери из них повторяющиеся и выведи на экран.
811 1444781
>>40966

В MySQL можно ставить ограничения по отдельным пользователям и указывать IP, с которого может заходить пользователь. На практике это неудобно, так как у пользователя может отключиться интернет, он зайдет через мобильный интернет, а там динамические IP адреса. Плюс, это небезопасно, так как протокол связи с БД может быть незашифрован и провайдер с государством будут видеть твои данные и пароли (и в случае РФ, сохранять их на диск по закону Яровой).

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

>>40866

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

Так что если ты прочтешь хотя бы начало мануала по PHP, это поможет.

>>40667

Я имел в виду, миллион пользователей БД. Потому делают одного пользователя БД, под которым к ней подсоединяется PHP скрипт независимо от залогиненного на сайте пользователя.
812 1444814
>>44778

>Качество кода пока низкое. Нужно доделывать.


Спасибо за ответ. Приму все твои советы.
813 1444826
котаны, скажите далбоебу почему эта регулярка выдает false

https://ideone.com/vsl4kT

я какой то тупой ублюдок
814 1444828
>>44826
а на regex101.com совпадение есть
на ровном месте бдядж торможу
815 1444836
>>44826
https://ideone.com/QfUSde
Так работает? Надо флаг u добавить, чтобы с русским языком все нормально ловилось.
816 1444843
>>44836
Да, работает, спасибо большое!
Забыл про этот флаг наглухо.
Безымянный.png37 Кб, 1132x532
817 1444872
Братья, кто шарит в WooCommerce + wordpress? Есть одна карточка продукта , и мне тут нужно переверстать табы с инфой о продукте в совсем другую форму (из того что выше в то что ниже). Как блять сделать это? Почему в этой cms верстка блять в перемешку с php ? Нихуя не понятно в какой части кода выводится тот или иной тэмплейт, нихуя не понятно где он для себя стили берет, и самое главное как блять поменять эти стили. Вопрос в том, как редактировать стили темы? Тема storefront. Я просто не понимаю нахуй, помогите.
818 1444914
>>44781
>>44779
>>44777
Спасибо
819 1445025
Делаю задание с первой пикчи, и никак не могу понять в чём проёб. Почему "i" так и остаётся без изменений?
820 1445030
>>45025
$i у тебя нигде не изменяется. Перед первой итерацией ему присвается $a * $a и все.
821 1445035
>>45030
$i разве не должно само рассчитываться из умножения $a ?
Как тогда сделать чтобы и $i изменялось?
822 1445041
>>45035
Первый аргумент задаёт лишь начальное значение, и оно выполняется один раз, все последующие итерации выполняет третий аргумент
823 1445045
>>45035
Как лично я делал, после кавычек написал действие, которое ты написал в переменных $a через конкатенацию
824 1445337
>>44776
спс
825 1445346
>>44779

>Не надо так писать


Иди нахуй.
изображение.png15 Кб, 196x141
826 1445476
827 1445494
Поясните новичку про open-сервер позязя. Нам на странице загрузки три варианта - премиум, ультимат и васик, они бесплатные или нет? Где цена-то?
https://ospanel.io/download/
828 1445499
>>45494
Есть бесплатный вариант, но он долго грузится. Вполне удобная штука, но можно и другое что попробовать.
829 1445503
>>45499
Спасибо, аношка. А что из альтернатив предложишь? Мне бы такую штуку, чтобы на флешке был сервер с моими двумя хеловордскими сайтами, и я бы его мог показать на собеседовании в макдак
830 1445511
>>45025
Или клади на хостинг или показывай с лэптора. Никто в адекватной канторе флешкой тыкать не даст.

Amazon дает год триала AWS. Нужна карта для привязки, с которой спишут 1 эуро. Если ты еще юн для своей карты, то батя или мамка просто мечтают завести там аккаунт (главное не забыть отменить перед концом триала). Еще можно купить дешманский домен (1.6 бакса в год вроде) на namecheap и прикрутить к aws тогда будут списывать 0.5-1 бакса в месяц, зависит от использования. ssl сертификат дают бесплатно на letsencrypt.
"Я задеплоил свои пет проекты на aws, зайдите на vasya-super.xyz/pet-project-one/" звучит лучше чем: "Дайте я вам тут своей сифилитичной флешкой потыкаю".
831 1445568
>>45503

>на флешке был сервер


Лучше не стоит, тем более нести это на собес. Если веб, то веб и никаких флешек.

>мог показать на собеседовании


Просто возьми любой бесплатный хостинг. Он ограничен обычно, но для портфолио - за глаза.
832 1445583
Какие минимальные требования нужны чтоб взяли на работу ?
833 1445595
>>45583
Сыры за 500.
834 1445613
>>45511
>>45568
балагадарю
835 1445620
Можно ли предотвратить SQL-инъекцию с помощью регулярного выражения?
836 1445633
text'; DROP DATABASE `2ch`;
837 1445664
>>45633
Лол.
hackerman.jpg91 Кб, 640x640
838 1445719
839 1445846
>>45583
Я пришел, сказал хочу у вас работать, нихуя не знаю, но научусь. Сижу вот теперь пилю бэкенды для мобилок.
840 1445953
Аноны, а используете ли вы в работе такую штуку как ТРЕЙТЫ?

Открыл для себя полгода назад. И бля, это просто охуенно.
Это горизонтальное наследование.
Теперь повсеместно использую, очень удобно.

Например. Есть приложение на фреймворке, зависимости подключаются через IoC.
Есть набор классов, которые использовать надо в разных других классах.
Я делаю трейт вида HuiDepenendencies, там подключаю зависимости и делаю геттеры.
Далее в других разных классах включаю этот трейд и вуаля - у меня зависимости описаны в одном месте и я получаю их везде, где это нужно в 1 строку.

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

Еще пизже то, что трейтов можно включать множество. И 2 трейта могут задавать один и тот же абстрактный метод как зависимость.
Короче, ты получаешь как бы универсальные кирпичики, которые можешь использовать где угодно, при этом сами кирпичики ДРУГ ОТ ДРУГА ВООБЩЕ НЕ ЗАВИСЯТ.

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

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

Вы можете возразить: "Да то же самое можно делать, и тупо включая один класс в другой как член" -ну, может быть, вот только нихуя блять.
Во-первых, это порождает гораздо больше пердолинга, чем с трейтами.
Во-вторых, трейт != класс, это упрощенная штука, которой на уровне языка запрещено много чего делать, что могут классы, и это заебись, ибо гарантированно защищает от проблем.
В-третьих, методы трейда включаются в класс НЕПОСРЕДСТВЕННО, тебе не нужно писать лишние костыли вида $class->secondClass->method(), ты пишешь просто $class->method().
В-четвертых, для стороннего кода методы из трейта являются полностью методами самого класса.
840 1445953
Аноны, а используете ли вы в работе такую штуку как ТРЕЙТЫ?

Открыл для себя полгода назад. И бля, это просто охуенно.
Это горизонтальное наследование.
Теперь повсеместно использую, очень удобно.

Например. Есть приложение на фреймворке, зависимости подключаются через IoC.
Есть набор классов, которые использовать надо в разных других классах.
Я делаю трейт вида HuiDepenendencies, там подключаю зависимости и делаю геттеры.
Далее в других разных классах включаю этот трейд и вуаля - у меня зависимости описаны в одном месте и я получаю их везде, где это нужно в 1 строку.

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

Еще пизже то, что трейтов можно включать множество. И 2 трейта могут задавать один и тот же абстрактный метод как зависимость.
Короче, ты получаешь как бы универсальные кирпичики, которые можешь использовать где угодно, при этом сами кирпичики ДРУГ ОТ ДРУГА ВООБЩЕ НЕ ЗАВИСЯТ.

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

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

Вы можете возразить: "Да то же самое можно делать, и тупо включая один класс в другой как член" -ну, может быть, вот только нихуя блять.
Во-первых, это порождает гораздо больше пердолинга, чем с трейтами.
Во-вторых, трейт != класс, это упрощенная штука, которой на уровне языка запрещено много чего делать, что могут классы, и это заебись, ибо гарантированно защищает от проблем.
В-третьих, методы трейда включаются в класс НЕПОСРЕДСТВЕННО, тебе не нужно писать лишние костыли вида $class->secondClass->method(), ты пишешь просто $class->method().
В-четвертых, для стороннего кода методы из трейта являются полностью методами самого класса.
841 1445954
>>45846
Сколько платят?
842 1445955
>>45633
Я так другу-говнокодеру сайт снес
843 1445965
>>45953

>Аноны, а используете ли вы в работе такую штуку как ТРЕЙТЫ


Дальше не читал. Как завещено, использую дерево if-ов, верстаю на таблицах. Все остальное - от лукавого
844 1445968
Анины, посоветуйте ide бесплатную. Юзаю notepad++, но хочу вырости в глазах сверстников и понаделать фоточек в инсту "я и моя среда разработки"
845 1445985
>>45968
Sublime Text 3.
Разве что окошечко будет выскакивать время от времени.
846 1446000
>>45954
Мало, мухосрань же.
847 1446204
>>15604 (OP)
Бамп годному треду
848 1446217
>>46204
Бамп за ваше здоровье.
849 1446336
Делаю задачку по Slim, возник такой вопрос по фреймворкам - нужно ли абсолютно все зависимости пихать в контейнер, или некоторые классы можно подключать по ходу работы контроллера (т.е зависимости зависимостей не обязательно в контейнере держать)?
850 1446396
>>45968
Передрочил кучу IDE и могу с уверенностью сказать, что из бесплатных, лучше Netbeans нет нихуя. Придется правда напильником поработать, чтобы плагинки поставить всякие. Единственный минус - отсутствует поддержка некоторых форматов например шаблонизатор блейд или vueJS.

А вообще чеб пхпсторм не крякнуть?
851 1446397
Решил я тут посмотреть уроки по VueJS. Вроде все хорошо, мне даж понравилось. Но меня ебет один сторонний вопрос:

Шоб оно все работало, надо написать в терминале: npm run dev

Как это автоматизируется на практике? Например на линуксовом сервере?
852 1446422
>>46397
Через bash сценарии/jinja2 питоновский/етц...
853 1446461
>>46422
т.е. нельзя без костылей добавить в сервисы как и любую другую хуйню? Надо пердолиться?
854 1446474
>>45985
>>46396

>А вообще чеб пхпсторм не крякнуть?


Спасибо за ответы, аноны. Да думал крякнуть, но внутри что-то сжимается, его же такие же двачеры писали, а у своих западло воровать. Там правда на сайте пишут, что для студентов и прочих дармоедов они бесплатно дают версию, но не понятно, нужно ли доказывать, слать им фото шараги или студ-билет
855 1446489
>>46474

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


Не-а. Нужно подтвердить почту с доменом сайта твоего вуза. Да, оказывается у каждого студента есть свой ящик на сайте вуза. Я пару месяцев назад так получил эту лицензию. Но phpstorm все равно не пользуюсь, привык к vscode уже.
856 1446494
>>46489
спасибо за информацию анон
857 1446521
>>46474
Ну хз, я уже не сперматозоид. В мое время крякать софт воспринималось как обыденный этап установки любой софтины. Сейчас смотрю на зумерков и шаблон трещит.

Я бы не платил даже еслибы у меня безлимит денег был, мне просто впадлу даже узнавать как там вся эта оплата происходит
858 1446522
>>46489

>vscode


Чем лучше?
859 1446529
>>46474
Крякнешь ты софт или не будешь его использовать - в любом из этих вариантов они денег не получат. Так что результат одинаков
860 1446608
Вопрос: пытаюсь заюзать get_browser(), но выдает ошибку
"browscap.ini directive not set in <путь>"
Скачал browscap.ini и скинул в нужную папку.
Прописал путь до нее в php.ini следующим образом
[browscap]
browscap = "F:\OpenServer\new_edition\OSPanel\modules\php\PHP_7.3-x64\browscap.ini" (без ковычек тоже пробовал)
сохранил. Перезапустил openserver. обновляю страницу - опять та же самая ошибка.
Подскажите тугодуму, что он делает не так.
33628441379346353055.21res500281.jpg86 Кб, 499x281
861 1446666
Оп проверь, пожалуйста.
Вектор: https://ideone.com/pEHFGH
862 1446782
>>46522
Не знаю, может и не лучше. Просто привык к нему уже за несколько лет, менять не хочется.
863 1446816
>>46529
Когда же вы перестанете выдумывать оправдания, халявщики. Ведете себя как дети. Почему нельзя просто взять и гордо сказать «Я ПИРАТ!»?
864 1446836
>>46336
Я туда только сервисы и внешние либы ставлю. Какой смысл прописывать туда внутренние модели самого приложения?
image.png698 Кб, 1280x720
865 1446847
>>46816

> ПИРАТ!

866 1446895
>>46836
Понял, спасибо!
867 1447006
Этот тред закрывается, переходите в новый тред >>1446969 (OP) . Я постараюсь глянуть непроверенные посты, но не помешает напомнить о них в новом треде.
805 - 825 868 1447008
>>44872

Я не знаю ответа, но ты не пробовал посмотреть документацию? Возможно, придется еще и по ВП почитать документацию тоже.

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

>>45025

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

Перед циклом один раз выполнится $i = $a * $a. Ок, пусть выполнится.

Далее, перед каждым шагом цикла проверяется условие $i <= 100. Ок, пусть проверяется.

Затем выполняется тело цикла, выводится 1 x 1 = 1. И затем команда $a++ увеличивает $a на 1. И снова проверяется условие, выполняется тело цикла. Но значение $i никто не обновляет. Ты на каждом шаге увеличиваешь только $a, но значение $i заново не вычисляешь и оно так и остается равным единице.

Тебе проще всего поставить вычисление $i внутрь тела цикла.

>>45503

Ищи бесплатный хостинг без рекламы.

>>45620

Вряд ли. Про инъекции у меня есть урок: https://github.com/codedokode/pasta/blob/master/security/sql-injection.md
869 1447013
>>47008

>Ну давай разберем твой код


Спасибо, но я уже и сам всё понял.
870 1447021
>>46816
Потомучто, если я так скажу - это будет означать, что я под этим подразумеваю какуют деятельность и считаю это чем-то важным. А мне просто похуй
871 1447033
>>47008
Спасибо
872 1447112
Там четвёртый Слим релизнулся, пачаны. Го доки курить.
873 1447271
>>47112
у них доки редкостное дерьмо
874 1447281
>>47271

>целый сайт, где разжёвано по каждому компоненту с примерами


>доки редкостное дерьмо


У меня для тебя плохие новости.
messenger.mp44 Мб, mp4,
1280x720, 0:34
someApprentice !EaaiHmIJms 875 1447890
>>40220

>- зачем нужна таблица participant, если есть conference_reference? Я не понимаю, чем таблица participant отличается от conference_reference.


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

Это подход обсуждался нами ранее:
https://phpclub.tech/pr/chain/1394587/#1389598

>>Когда пользователь впервые отправляет приватное сообщение другому пользователю, создаётся конференция, пара получателей и "копии" диалога для каждого пользователя. Но прежде чем это сделать, нужно проверить, действительно ли сообщение отправляется впервые. Для этого нужно проверить, что конференции между этими пользователями не существует. То есть нужно найти двух Получателей с одинаковым Диалогом и чтобы этот Диалог был приватным. Нужно сделать это (желательно) за один запрос.


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



>- не стоит ли сделать тип ENUM для message.type, чтобы ограничить список допустимых значений?


>- не стоит ли сделать message_attachment.type типом ENUM?


Да, я не знал про этот тип. Исправлю.

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


Исправлю.

>- возможно, стоит в conference_reference убрать id и использовать в качестве ключа пару (conference_uuid, user_uuid). Например, я вижу, что message_reference уже использует пару (conference, user).


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

>И еще, ничего, что тут приватный ключ лежит? https://github.com/someApprentice/Crypter/blob/master/wamp/.crossbar/key.priv


Удалю.

>И еще, не отдаем ли мы тут детали ошибки на сервере пользователю: https://github.com/someApprentice/Crypter/blob/master/wamp/AuthenticatorSession.py#L55


На ту строчку которую вы указали выдаётся ошибка о том что не предоставлен Bearer token. Об этом нужно выдать ошибку пользователю. А вот ниже там действительно обрабатывается любая ошибка, но это только потому что я не знаю как обработать отдельные ошибки https://github.com/someApprentice/Crypter/blob/master/wamp/AuthenticatorSession.py#L77-L78

>Тут, в тестах, возможно стоило сделать вспомогательную функцию для генерации токенов, так как в них легко опечататься и долго гадать, потому тест не работает: https://github.com/someApprentice/Crypter/blob/master/wamp/tests/authenticator_test.py


Тогда пришлось бы генерировать токен так как он генерируется в функции регистрации/логина. Не будет ли это положением теста на знание о том как генерируется токен?

>Также, немного неудобно, что приходится поддерживать 2 набора сущностей: в Питоне и в PHP.


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

>Что касается исключений при авторизации, мне кажется, их правильнее ловить в обработчике авторизации, а не тут: https://github.com/someApprentice/Crypter/blob/master/api/src/EventListener/ExceptionListener.php


Делать блок try/catch?

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


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

>Тут (https://github.com/someApprentice/Crypter/blob/master/api/tests/Controller/AuthControllerTest.php ) есть такой код:


>


>$client->request(


>$method = 'POST',


>$uri = '/api/auth/login',


>


>Так писать не стоит, это не keyword arguments из Питона и имена переменных не учитываются никак.


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

>В тестах авторизации ( https://github.com/someApprentice/Crypter/blob/master/api/tests/Controller/AuthControllerTest.php ) ты проверяешь что тебе выдана кука с определенным именем. Ты полагаешься на знание внутреннего устройства механизма авторизации. И наличие куки не гарантирует авторизации. Правильнее запрашивать какую-то страницу для проверки доступа к ней. Можно даже сделать специальный тестовый метод /test/whoami для этого.


Разве не нужно проверить что выдаются кукисы? Они ведь нужно для правильной работы приложения.

Проверка авторизации выполняется тестом проверки доступа к разлогиниванию https://github.com/someApprentice/Crypter/blob/master/api/tests/Controller/AuthControllerTest.php#L232-L242

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


Я как раз хотел спросить где хранить вспомогательные для тестов функции делать класс tests/Utils.php?

>Соответственно тесты будут вида canLoginWithValidPassword, cannotLoginWithWrongPassword.


Нужно разбить одну функцию на две?

>Далее, это ненадежный способ проверки, ведь речь тут о безопасности:


>


>> https://github.com/someApprentice/Crypter/blob/master/wamp/AuthorizerSession.py#L40


>> if 'private.message.to.' in uri:


>


>Не лучше ли использовать str.startswith() ?


Я не знал про эту функцию. Почему тот метод не надёжный?

>> regex = re.compile('^private\.message\.to\.([a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12})$')


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


Зачем компилировать регулярку в начале скрипта? Нужны разные компиляции регулировок в зависимости от uri по которому нужна авторизация. Их все нужно делать в начале скрипта?

>Также, я тут подумал, что для огромных конференций обновление через websocket может потребовать отдельную схему. У тебя, как я понял, при отправке сообщения в групповой чат на 1000 пользователей будет отправлено 1000 уведомлений private.message.to... и conference.updated.for.... Это будет нагружать вебсокет-демон. Логичнее для огромных чатов просто сделать канал updates.{conference_uuid} и слать туда одно уведомление. А клиент пусть отдельным запросом выясняет, что поменялось. Можно конечно слать и само сообщение, но надо убедиться, что кикнутые из чата, но не отписавшиеся от веб-сокет канала пользователи не смогут его получить.


М да, для группового чата так и нужно сделать. Вообще отправка 1000 уведомлений сделано, потому что, представим, пользователь очень популярен и каждый день получает 100 а может и 1000 новых сообщений от уникальных пользователей, и в итоге ему на всех нужно подписываться, что перенагрузит клиентское приложение. Гораздо лучше перенести эту нагрузку на серверную часть.

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


Так и планируется сделать.

Только мне кажется что менять ключ не обязательно, потому что пользователь всё равно не сможет ни получить ни отправить сообщения, потому что API/WAMP его не авторизует для этого.
messenger.mp44 Мб, mp4,
1280x720, 0:34
someApprentice !EaaiHmIJms 875 1447890
>>40220

>- зачем нужна таблица participant, если есть conference_reference? Я не понимаю, чем таблица participant отличается от conference_reference.


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

Это подход обсуждался нами ранее:
https://phpclub.tech/pr/chain/1394587/#1389598

>>Когда пользователь впервые отправляет приватное сообщение другому пользователю, создаётся конференция, пара получателей и "копии" диалога для каждого пользователя. Но прежде чем это сделать, нужно проверить, действительно ли сообщение отправляется впервые. Для этого нужно проверить, что конференции между этими пользователями не существует. То есть нужно найти двух Получателей с одинаковым Диалогом и чтобы этот Диалог был приватным. Нужно сделать это (желательно) за один запрос.


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



>- не стоит ли сделать тип ENUM для message.type, чтобы ограничить список допустимых значений?


>- не стоит ли сделать message_attachment.type типом ENUM?


Да, я не знал про этот тип. Исправлю.

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


Исправлю.

>- возможно, стоит в conference_reference убрать id и использовать в качестве ключа пару (conference_uuid, user_uuid). Например, я вижу, что message_reference уже использует пару (conference, user).


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

>И еще, ничего, что тут приватный ключ лежит? https://github.com/someApprentice/Crypter/blob/master/wamp/.crossbar/key.priv


Удалю.

>И еще, не отдаем ли мы тут детали ошибки на сервере пользователю: https://github.com/someApprentice/Crypter/blob/master/wamp/AuthenticatorSession.py#L55


На ту строчку которую вы указали выдаётся ошибка о том что не предоставлен Bearer token. Об этом нужно выдать ошибку пользователю. А вот ниже там действительно обрабатывается любая ошибка, но это только потому что я не знаю как обработать отдельные ошибки https://github.com/someApprentice/Crypter/blob/master/wamp/AuthenticatorSession.py#L77-L78

>Тут, в тестах, возможно стоило сделать вспомогательную функцию для генерации токенов, так как в них легко опечататься и долго гадать, потому тест не работает: https://github.com/someApprentice/Crypter/blob/master/wamp/tests/authenticator_test.py


Тогда пришлось бы генерировать токен так как он генерируется в функции регистрации/логина. Не будет ли это положением теста на знание о том как генерируется токен?

>Также, немного неудобно, что приходится поддерживать 2 набора сущностей: в Питоне и в PHP.


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

>Что касается исключений при авторизации, мне кажется, их правильнее ловить в обработчике авторизации, а не тут: https://github.com/someApprentice/Crypter/blob/master/api/src/EventListener/ExceptionListener.php


Делать блок try/catch?

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


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

>Тут (https://github.com/someApprentice/Crypter/blob/master/api/tests/Controller/AuthControllerTest.php ) есть такой код:


>


>$client->request(


>$method = 'POST',


>$uri = '/api/auth/login',


>


>Так писать не стоит, это не keyword arguments из Питона и имена переменных не учитываются никак.


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

>В тестах авторизации ( https://github.com/someApprentice/Crypter/blob/master/api/tests/Controller/AuthControllerTest.php ) ты проверяешь что тебе выдана кука с определенным именем. Ты полагаешься на знание внутреннего устройства механизма авторизации. И наличие куки не гарантирует авторизации. Правильнее запрашивать какую-то страницу для проверки доступа к ней. Можно даже сделать специальный тестовый метод /test/whoami для этого.


Разве не нужно проверить что выдаются кукисы? Они ведь нужно для правильной работы приложения.

Проверка авторизации выполняется тестом проверки доступа к разлогиниванию https://github.com/someApprentice/Crypter/blob/master/api/tests/Controller/AuthControllerTest.php#L232-L242

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


Я как раз хотел спросить где хранить вспомогательные для тестов функции делать класс tests/Utils.php?

>Соответственно тесты будут вида canLoginWithValidPassword, cannotLoginWithWrongPassword.


Нужно разбить одну функцию на две?

>Далее, это ненадежный способ проверки, ведь речь тут о безопасности:


>


>> https://github.com/someApprentice/Crypter/blob/master/wamp/AuthorizerSession.py#L40


>> if 'private.message.to.' in uri:


>


>Не лучше ли использовать str.startswith() ?


Я не знал про эту функцию. Почему тот метод не надёжный?

>> regex = re.compile('^private\.message\.to\.([a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12})$')


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


Зачем компилировать регулярку в начале скрипта? Нужны разные компиляции регулировок в зависимости от uri по которому нужна авторизация. Их все нужно делать в начале скрипта?

>Также, я тут подумал, что для огромных конференций обновление через websocket может потребовать отдельную схему. У тебя, как я понял, при отправке сообщения в групповой чат на 1000 пользователей будет отправлено 1000 уведомлений private.message.to... и conference.updated.for.... Это будет нагружать вебсокет-демон. Логичнее для огромных чатов просто сделать канал updates.{conference_uuid} и слать туда одно уведомление. А клиент пусть отдельным запросом выясняет, что поменялось. Можно конечно слать и само сообщение, но надо убедиться, что кикнутые из чата, но не отписавшиеся от веб-сокет канала пользователи не смогут его получить.


М да, для группового чата так и нужно сделать. Вообще отправка 1000 уведомлений сделано, потому что, представим, пользователь очень популярен и каждый день получает 100 а может и 1000 новых сообщений от уникальных пользователей, и в итоге ему на всех нужно подписываться, что перенагрузит клиентское приложение. Гораздо лучше перенести эту нагрузку на серверную часть.

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


Так и планируется сделать.

Только мне кажется что менять ключ не обязательно, потому что пользователь всё равно не сможет ни получить ни отправить сообщения, потому что API/WAMP его не авторизует для этого.
someApprentice !EaaiHmIJms 876 1447897
>>40220

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


>пользователь отсоединился и пропустил сообщение


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

Это касается только обновленных сообщений. Старые сообщения и новые сообщения в офлайне подхватываются с помощью API.

В чем ещё вебсокет может быть ненадёжен - я не знаю.

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


>> Было бы лучше если бы приватная конференция имела такой же id как и пользователь. И пользователь сам по себе как бы представлялися как приватная конференция. Тогда можно будет открывать диалог между двумя пользователями без создания отдельной конференция для них.


>


>Этот вопрос можно решить без изменений в БД, на уровне интерфейса. Мы можем, например, сделать URL вида /talk/{userId} и при его открытии смотреть: есть приватный диалог с этим пользователем или нет. Если есть - подгружать данные (либо редиректить на URL с id конференции), если нет - показать пустую страницу. То есть тебе не надо создавать что-то в БД только потому, что пользователь нажал на имя контакта.


>


>Есть ли какие-то недостатки у такого подхода?


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

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

Эту проблему действительно нужно решать на уровне интерфейса.

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

Всё очень просто:

Для приватной конференции мы используем URL 'u-{user_uuid}' и делаем метод API getConferenceByParticipant($user_uuid), и если её ещё не существует, то мы просто не запрашиваем сообщения, а после отправки сообщения и её создания нас уведомит об этом WAMP и мы её реактивно подхватим.
Для публичной конференции всё остаётся без изменений только открываем мы её по URL 'c-{conference_uuid}'.

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

>>40221

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


>


>Есть возможность в конфиге указать дополнения к pythonpath: https://crossbar.io/docs/Native-Worker-Options/ . Не подойдет ли это тут?


Наверно подойдёт. Я не знал про это опцию.

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


Текущая директория это какая? Я бы указал относительный путь к ./wamp/src

>> Можно ли перекодировать исходный файл в Uint8Array а затем обратно в файл, для его сохранения на диск/хранилище?


>


>Я не очень понимаю, зачем ты хочешь это сделать


Чтобы зашифровать голосовое/видео сообщение и сохранить его на сервер. Или не только сам контент сообщения, но и приложения к нему, например фотографию. Любая информация должна быть зашифрована.

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


Зашифрованные файлы весят больше?

Я поискал в интернете и вроде не очень.
https://security.stackexchange.com/questions/76568/does-encrypting-a-file-make-it-larger
https://security.stackexchange.com/questions/8245/gpg-file-size-with-multiple-recipients
someApprentice !EaaiHmIJms 876 1447897
>>40220

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


>пользователь отсоединился и пропустил сообщение


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

Это касается только обновленных сообщений. Старые сообщения и новые сообщения в офлайне подхватываются с помощью API.

В чем ещё вебсокет может быть ненадёжен - я не знаю.

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


>> Было бы лучше если бы приватная конференция имела такой же id как и пользователь. И пользователь сам по себе как бы представлялися как приватная конференция. Тогда можно будет открывать диалог между двумя пользователями без создания отдельной конференция для них.


>


>Этот вопрос можно решить без изменений в БД, на уровне интерфейса. Мы можем, например, сделать URL вида /talk/{userId} и при его открытии смотреть: есть приватный диалог с этим пользователем или нет. Если есть - подгружать данные (либо редиректить на URL с id конференции), если нет - показать пустую страницу. То есть тебе не надо создавать что-то в БД только потому, что пользователь нажал на имя контакта.


>


>Есть ли какие-то недостатки у такого подхода?


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

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

Эту проблему действительно нужно решать на уровне интерфейса.

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

Всё очень просто:

Для приватной конференции мы используем URL 'u-{user_uuid}' и делаем метод API getConferenceByParticipant($user_uuid), и если её ещё не существует, то мы просто не запрашиваем сообщения, а после отправки сообщения и её создания нас уведомит об этом WAMP и мы её реактивно подхватим.
Для публичной конференции всё остаётся без изменений только открываем мы её по URL 'c-{conference_uuid}'.

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

>>40221

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


>


>Есть возможность в конфиге указать дополнения к pythonpath: https://crossbar.io/docs/Native-Worker-Options/ . Не подойдет ли это тут?


Наверно подойдёт. Я не знал про это опцию.

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


Текущая директория это какая? Я бы указал относительный путь к ./wamp/src

>> Можно ли перекодировать исходный файл в Uint8Array а затем обратно в файл, для его сохранения на диск/хранилище?


>


>Я не очень понимаю, зачем ты хочешь это сделать


Чтобы зашифровать голосовое/видео сообщение и сохранить его на сервер. Или не только сам контент сообщения, но и приложения к нему, например фотографию. Любая информация должна быть зашифрована.

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


Зашифрованные файлы весят больше?

Я поискал в интернете и вроде не очень.
https://security.stackexchange.com/questions/76568/does-encrypting-a-file-make-it-larger
https://security.stackexchange.com/questions/8245/gpg-file-size-with-multiple-recipients
877 1448190
Чем отличается Table Data Gateway и Репозиторий?
878 1448286
>>48190

Давай почитаем определения от Мартина Фаулера (на сайте только выжимка, полные описания даны в его книге):

https://martinfowler.com/eaaCatalog/tableDataGateway.html

> A Table Data Gateway holds all the SQL for accessing a single table or view: selects, inserts, updates, and deletes. Other code calls its methods for all interaction with the database.



https://martinfowler.com/eaaCatalog/repository.html

> A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection. Client objects construct query specifications declaratively and submit them to Repository for satisfaction. Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes. Conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations performed over them, providing a more object-oriented view of the persistence layer.



Разница, на мой взгляд, в том, что TDG лишь содержит в себе набор методов со всеми SQL запросами к одной таблице. А Repository представляет таблицу как коллекцию с записями, в которой их можно искать, добавлять, удалять. При этом Repository используется как часть Data Mapper (который пытается представить набор записей в БД, как будто это граф связанных объектов, находящихся в памяти).

То есть TDG - просто набор методов и запросов для работы с таблицей, Repository - это как-бы коллекция объектов и используется обычно в рамках Data Mapper.

На практике, если мы возьмем ORM (Object-Relation Mapper) Доктрина, то вот класс встроенного в неё репозитория: https://github.com/doctrine/orm/blob/master/lib/Doctrine/ORM/EntityRepository.php

Видно, что он позволяет только искать данные, но не добавлять/удалять. И также очевидно, что он не является TDG, так как не содержит в себе все возможные SQL запросы для работы с определенной таблицей.

Тебе было бы полезно изучить все связанные с ORM паттерны (Data Mapper, Unit of Work, Identity Map), а также почитать документацию и может быть, код Доктрины. Это поможет тебе лучше понять как устроен ORM и какие паттерны в нем используются. Ну и знание Доктрины пригодится, если ты планируешь работать PHP разработчиком. Она сложная, но если изучать постепенно, то можно разобраться.

Задавай вопросы (в новом треде >>1446969 (OP) ), если что-то непонятно.
878 1448286
>>48190

Давай почитаем определения от Мартина Фаулера (на сайте только выжимка, полные описания даны в его книге):

https://martinfowler.com/eaaCatalog/tableDataGateway.html

> A Table Data Gateway holds all the SQL for accessing a single table or view: selects, inserts, updates, and deletes. Other code calls its methods for all interaction with the database.



https://martinfowler.com/eaaCatalog/repository.html

> A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection. Client objects construct query specifications declaratively and submit them to Repository for satisfaction. Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes. Conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations performed over them, providing a more object-oriented view of the persistence layer.



Разница, на мой взгляд, в том, что TDG лишь содержит в себе набор методов со всеми SQL запросами к одной таблице. А Repository представляет таблицу как коллекцию с записями, в которой их можно искать, добавлять, удалять. При этом Repository используется как часть Data Mapper (который пытается представить набор записей в БД, как будто это граф связанных объектов, находящихся в памяти).

То есть TDG - просто набор методов и запросов для работы с таблицей, Repository - это как-бы коллекция объектов и используется обычно в рамках Data Mapper.

На практике, если мы возьмем ORM (Object-Relation Mapper) Доктрина, то вот класс встроенного в неё репозитория: https://github.com/doctrine/orm/blob/master/lib/Doctrine/ORM/EntityRepository.php

Видно, что он позволяет только искать данные, но не добавлять/удалять. И также очевидно, что он не является TDG, так как не содержит в себе все возможные SQL запросы для работы с определенной таблицей.

Тебе было бы полезно изучить все связанные с ORM паттерны (Data Mapper, Unit of Work, Identity Map), а также почитать документацию и может быть, код Доктрины. Это поможет тебе лучше понять как устроен ORM и какие паттерны в нем используются. Ну и знание Доктрины пригодится, если ты планируешь работать PHP разработчиком. Она сложная, но если изучать постепенно, то можно разобраться.

Задавай вопросы (в новом треде >>1446969 (OP) ), если что-то непонятно.
Тред утонул или удален.
Это копия, сохраненная 5 августа 2019 года.

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

Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
« /pr/В начало тредаВеб-версияНастройки
/a//b//mu//s//vg/Все доски