«phpClub» — архив тем ("тредов"), посвящённых изучению PHP и веб-технологий.
Аноним 2019/04/23 14:29:20  №1387384 1
Нихуя не понимаю mvc, помогите долбоёбу
Аноним 2019/04/23 17:22:39  №1387455 2
image.png (97, 259x194)
194x259
>>1387384
Я вообще ничего не понимаю с этим долбанным SQL. Набираю уже где-то первую космическую на одной жопной тяге.

Правила меняются постоянно от запроса к запросу, от типа переменной к другому типу переменной. Заебало такое поведение уже. Где-то можно напрямую переменные в строку лепить - где-то нельзя.
С группировкой тоже возился долго и пришлось костыль писать, так потом выяснилось что мой костыль и не костыль вовсе. Оказывается в "GROUP BY" нельзя биндить переменную. Но везде можно. А тут нельзя - читайте документацию. Где-то там на триста-сраной странице пару строк написано про это. Или гугл доёбывайте, но на русском только шизики срут - трахайте по английский пожалуйста. Рады были вам помочь.
Ну охуеть теперь. И всем норм. Говноедство какое-то массовое.
Ответы: >>1387703 >>1394734
Аноним 2019/04/23 17:52:42  №1387469 3
>>1387384
я тоже не совсем понимаю
модель ладно, это база данных
вью понятно, это фронт-энд
контроллер... щито такое контроллер? бэкэнд с роутингом и запросами к базе данных? вроде логично, но фронт-энд, бэк-энд и база данных есть у большинства приложух, а мвк считается специфической композицией
Ответы: >>1387476
Аноним 2019/04/23 17:57:34  №1387476 4
>>1387469
>модель ладно, это база данных
Это бизнес-логика. То есть сама суть процесса, который ты программируешь. Там не только база данных.
>контроллер... щито такое контроллер?
То, что склеивает модель и представление. Она обычно трогает модель за разные места, а результат этого действия отдаёт представлению(вью).
Ответы: >>1387484
Аноним 2019/04/23 18:12:50  №1387484 5
>>1387476
как все сложно
я рад что есть спы, вот они точно по мне
Аноним 2019/04/24 08:07:46  №1387703 6
>>1387455
Ето и есть процесс обучения.
Ответы: >>1387794
Аноним 2019/04/24 11:49:42  №1387794 7
>>1387703
Да ето так.

Однако от этого не легче - довольно сложно работать с системой, в данном случае, MySQL, если она ведёт себя как девка на свидании и постоянно ломается и нарушает свои же правила.
Аноним 2019/04/24 23:04:25  №1388200 8
>>1387384
Model - тут логика, обработка данных, работа с БД.
View - всё просто. Шаблоны, вёрстка. В общем, всё что показывается пользователю тут.
Controller - звено между пользователем и логикой. Принимает данные, преобразует типа, собрать аргументы в массив и прочее по мелочи, передаёт в модель.
Аноним 2019/05/06 05:54:58  №1394733 9
>>1394590

> Есть класс WebReader

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

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

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

> Это будет нормально - передать ему исключение, на основе которого он либо изменит свойства класса (модифицирует запрос)

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

>>1394581

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

>>1394582

Несколько try/catch пишется, если ты знаешь, как обработать конкретную ошибку. Иначе пишется один общий обработчик ошибок на все случаи жизни.

>>1388385

В нем ничего не заменено, просто QUERY_STRING - это то, что идет ПОСЛЕ знака вопроса в URL (потому знака вопроса в ней нету) и она вообще может отсутствовать. Открой мануал и проверь: https://www.php.net/manual/ru/reserved.variables.server.php

Также, можешь прочитать урок про структуру URL на всякий случай: https://github.com/codedokode/pasta/blob/master/network/urls.md - там написано, что такое query string

>>1387384

Урок по MVC https://github.com/codedokode/pasta/blob/master/arch/mvc.md
Ответы: >>1394909
Аноним 2019/05/06 05:56:56  №1394734 10
>>1387455

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

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

>>1386695

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

>>1382988

php-fpm это менеджер процессов PHP, к которому nginx обращается по протоколу FastCGI. Он запускается как отдельная от nginx программа. Apache тоже поддерживает FastCGI и может с ним взаимодействовать.

Обычно схема такая: запросы идут на нгинкс, статические файлы он отдает сам, динамические запросы к страницам сайта передает в php-fpm, который выполняет php-скрипт.

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

>>1382148

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

\S+\s*...\s*\S+

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

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

Ну и покажи код, чтобы было можно что-то еще добавить.
Аноним 2019/05/06 19:18:00  №1394909 11
>>1394733
> вынести решение вопроса "что делать при ошибке" в отдельный метод
Вот это мне нравится. Вытащу тогда содержимое catch во вспомогательный метод типа tryToRepairTheRequest().
В родителе будет
protected function tryToRepairTheRequest(\ErrorException $e) {
// можем что-то сделать? если нет, throw $e;
}
В наследниках буду делать
private function tryToRepairTheRequest(\ErrorException $e) {
try { parent::tryToRepairTheRequest($e); }
catch (\ErrorException $e) { // специальный код для наследника, а если не вышло то опять же throw $e; }
}

>У тебя объект представляет один запрос и для нового запроса создается новый объект?
Нет. Запросы могут идти через один объект, а вот ответы - уже новые объекты.
$reader = new WebReader($defaultStreamContext, $maxQtyAttempts); // контекст стрима, который будет использован, если в get() никакой не указан, и кол-во попыток перезапросить при сбоях
$response = $reader->get('https://google.com'[, $streamContext]); // $response - объект класса WebResponse, содержащий ответ
$response2 = $reader->get('https://yandex.ru');

> что, если ты в процессе обработки одного запроса попытаешься через этот класс сделать другой?
Не понял. У меня нет никакой асинхронности и тредов. Вызвал get() - получи WebResponse или эксепшен.
>Свойства второго запроса затрут первый?
Ну, каждый запрос плодит по совершенно независимому WebResponse. WebReader при этом может оставаться один. Все, что он знает - какие хттп-заголовки и параметры стрима выставлять. $url нигде не запоминается и живет только внутри get(), который под капотом вызывает return $this->doRequest($url, $streamContext, $this->qtyAttempts), если ему нравятся переданные параметры. А doRequest() возвращает new WebResponse($http_response_header, $content), куда кладет всё полученное, если запрос удался.
Ответы: >>1398391 >>1402423 >>1402834
Аноним 2019/05/12 13:29:03  №1398391 12
ОПчик, ответь, пожалуйста, нормальная ли архетиктура в >>1394909
Аноним 2019/05/18 10:41:34  №1402423 13
>>1402419
Хочу узнать, нормальное ли у меня ООП в >>1394909
Аноним 2019/05/19 03:51:23  №1402834 14
>>1402686

Вообще, проще оставить все как есть, так как установка делается не так часто. Но если тебе хочется to go deeper ....

В composer на события можно повесить вызов функции или статического метода: https://getcomposer.org/doc/articles/scripts.md#package-events

При этом он получит объект события. Из него как-то можно попробовать выковырять название пакета: https://getcomposer.org/doc/articles/scripts.md#event-classes

Подробности придется искать в коде композера или в Гугле.

Также, хочу заметить, что твои скрипт не кросс-платформенны и работают только под Linux/Mac. Правильнее было бы повесить кроссплатформенный PHP-скрипт.

>>1394909

Ты как-то что-то усложнил. Давай спроектируем все с нуля:

Задача: дать возможность при ошибке поменять реквест и отправить запрос заново. Значит, нужна функция. Она может получать объект ошибки (не ErrorException, который соответствует PHP-ошибке, а например, HttpException) и объект Request. Она может вернуть либо null - не повторять запрос, либо вернуть тот же или модифицированный Request для повтора запроса, либо выбросить какое-то новое исключение:

function handleError(HttpException $e, Request $r): ?Response { ... }

Реализация по умолчанию, естественно, будет возвращать null.

Но тут есть подвох. Что, если мы хотим, например, в ответ на ошибку 503 сделать паузу в 5 секунд и сделать до 3 повторов запроса? Как нам хранить счетчик запросов? В данном случае - хранить его негде (если мы только не предусмотрели это в базовом классе).

Потому можно попробовать другой подход. Делаем переопределяемым сам метод отправки запроса - sendRequest(Request $req): Response. В наследнике просто оборачиваем его:

function sendRequest(...): ...
{
// любой код
parent::sendRequest()
// любой код
}

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

А еще более универсально будет обернуть выполнение запроса без наследования, обернув вызов метода get().

Также, можно посмотреть на архитектуру питоновской библиотеки urllib, где есть плагины (openers), но она наверно сложновата для твоего случая: https://docs.python.org/3/library/urllib.request.html#module-urllib.request

У тебя в коде ошибки:

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

Вообще, подход с оборачиванием проще, чем с обработчиком ошибок, как мне кажется.
Ответы: >>1402868
Аноним 2019/05/19 07:21:38  №1402868 15
>>1402834
> скрипт не кросс-платформенны и работают только под Linux/Mac.
Я не автор того скрипта, но не понял зачем давать такой совет. Под виндой бекенд обычно не разрабатывают, во многих компаниях наоборот распространена практика пересаживания всех на мак/убунту, чтобы проекты можно было быстрее поднимать по инструкции. Никогда не видел, чтобы в проекте было несколько параллельных инструкций для разных ОС. Зато часто видел древние проекты, которые не то что на винде запустить нельзя, их нужно запускать только под определённой версией PHP и только под апачем, так как на его rewrite правилах и includ'ах завязан весь код.
Ответы: >>1402920 >>1405044
Аноним 2019/05/19 09:35:10  №1402920 16
>>1402868
> бекенд обычно не разрабатывают
Net Core
Аноним 2019/05/22 23:52:06  №1405044 17
>>1403996

Ты ищешь сложное решение вместо простого. В случае использования элемента display: block и задания ему ширины, маргины вычисляются автоматически. Достаточно задать левый маргин, ширину и поставить auto для правого маргина.

Как плюс, это работает вообще во всех браузерах, в отличие от calc(), который пришел только с CSS3 и внедрен с ~2013 года: https://caniuse.com/#feat=calc

Обрати также внимание, что в части старых бразеров calc доступен только с вендорным префиксом. Изучи эту тему, и добавь нужные префиксы, если ты хочешь использовать calc(). Также, добавь в закладки или запомни сайт caniuse, он наверняка еще пригодится.

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

>>1403678

Вообще, я бы советовал просто прочитать цикл статей "создаем приложение на фреймворке X". Вот, например, например, первый попавшийся туториал по Symfony: https://auth0.com/blog/symfony-tutorial-building-a-blog-part-1/

А так, пожалуйста, сложное облачное хранилище файлов nextcloud: https://github.com/nextcloud/server

CMS Интернет-магазина Magento: https://github.com/magento/magento2

>>1402868

Я довольно долгое время под виндой работал, PHP и Апач там вполне работают.

На винду поставить несколько версий PHP проще простого - скачиваем zip-архивы и распаковываем в разные папки. А под линукс? Либо заморачиваться со сторонними репозиториями, которые перезапишут тебе libssl, либо использовать работающие с переменныем успехом скрипты вроде phpenv.