«phpClub» — архив тем ("тредов"), посвящённых изучению PHP и веб-технологий.
Аноним 2019/05/02 23:28:51  №1393255 1
>>1380485 (OP)
140к на руки с опытом 2,5 года в дс на пыхе - это успех?
Ответы: >>1393265
Аноним 2019/05/03 01:17:35  №1393265 2
>>1393255
Расскажи как устраивался на работу, какие вопросы были ? Что нужно знать/уметь делать чтоб устроиться ?
Ответы: >>1393335
Аноним 2019/05/03 08:23:54  №1393335 3
>>1393265
Учил пыху в этом самом треде (тут всё ещё тот же помогающий ОП? не верится, что столько времени прошло).

Без задней мысли после полугода аутирования в треде пошёл на собесы, спрашивали базовые вещи, про ООП, наследование, типы данных, sql.
На джуна ничего не надо УМЕТЬ, но надо знать, и главное, показаться ТОЛКОВЫМ.
всё изи:
1) принципы ооп
2) solid
3) паттерны GoF
4) кто-нибудь спросит про сортировки, но хз, надо ли тебе в такую контору (мейлсру и прочие спросят 100%, рога и копыта нет)
5) новые фичи php7+
6) базовый sql, простые запросы и джоины, про индексы могут спросить
Аноним 2019/05/03 10:11:50  №1393386 4
Объясните пожалуйста.
1) Как реализовать конструктор в классе, который реализует паттерн TableDataGateway? В примере ОП использует PDO и конструктор выглядит так:
public function __construct(PDO $pdo) { ... }
а я использую mysqli могу ли я написать
public function __construct($conn) { ... }?
Так же не понятно, что мне писать в самом конструкторе? Подключение к базе данных или что?
2)С исключениями я тоже не понял. Могу ли я их не использовать, а писать просто
$conn = new mysqli ($hn, $un, $pw, $db);
if($conn->connect_error) die($conn->connect_error);
?
Аноним 2019/05/03 10:26:27  №1393396 5
>>1393386
>а я использую mysqli
зачем? Юзай pdo
>Подключение к базе данных или что?
не смотрел пример ОПа, но в классе PDO коннекшн уже же будет установлен?
>С исключениями я тоже не понял. Могу ли я их не использовать, а писать просто
можешь. Зачем тебе только это? Твой die() выйдет из программы и всё, а исключение можно обработать и продолжать работать дальше.

Привыкай к ним, die и exit в реальном коде не встретишь
Ответы: >>1393514 >>1393514
Аноним 2019/05/03 10:40:30  №1393400 6
>>1393335
А на 140 к какие вопросы на собесе были? Что по английскому у тебя?
Ответы: >>1393617
Аноним 2019/05/03 10:51:53  №1393402 7
>>1393335
Как вообще рынок пыхи оцениваешь, свалить в другой стек не думал? Не надоело?
Ответы: >>1393617
Аноним 2019/05/03 11:49:12  №1393429 8
>>1393386
>а я использую mysqli могу ли я написать
>public function __construct($conn) { ... }?
Да просто оберни mysqli в класс и всё.
Я бы тогда ещё и интерфейс сделал, чтобы можно было как через ПДО ходить, так и через твою обёртку.
Ответы: >>1393514 >>1394575
Аноним 2019/05/03 13:01:28  №1393456 9
>>1393335
160к за год (точнее 11 месяцев)
Ответы: >>1393617
Аноним 2019/05/03 16:24:09  №1393514 10
>>1393396
>>1393396
>Юзай pdo
В книге, которую я читаю, используют mysqli. Мне его использовать удобней.
>PDO коннекшн уже же будет установлен?
Не понял
>Зачем тебе только это?
Да вот собственно вопрос. Оп пишет что исключение сокращает код, только у меня чет наоборот. Ну и нигде нормального объяснения про исключения не могу найти.
Так же видел, что нельзя использовать класс Exception. С классом Exception вопросы. Мне нужно создать свой класс, который унаследует Exception? А что в нем писать?
Ну и не понятно зачем отлавливать ошибку если можно вместо die
отправить HTML страницу с ошибкой. Но в задании этого нет, так что делать я этого не буду.

>>1393429
Во во, тоже вопрос. ОП вроде тоже писал про обертку mysqli или не он. Что это значит? Зачем нужно? Как реализовать я даже не спрашиваю. И что так mysqli не любят?
Аноним 2019/05/03 20:41:28  №1393617 11
>>1393400
>Что по английскому у тебя
с англ ок, на русском тех литру не читаю в принципе
>А на 140 к какие вопросы на собесе были
очень много вопросов по sql и по безумным джоинам. В остальном вопросы разные, от логических задачек в яндексе (не взяли) до вопросов про то, как реализован массив в ядре пхп
>>1393402
>Как вообще рынок пыхи оцениваешь
в рашке большой, но разный, серьёзное погромирование только на симфони и немножко лара, его мало, в остальном пхп рынок это дно уровня вордпресса и битрикса, это путь в никуда и дерьмо полное, не тратьте время. В европе он побольше, но всё равно так себе, слишком дурная слава у пыхи. Хотя язык хороший
>>1393456
не понял

>>1393514
>которую я читаю, используют mysqli
и что блядь, я говорю тебе, это дерьмо в приличном обществе даже не упоминают, а ты
>Мне его использовать удобней.
Просто погугли mysqli vs pdo php и почитай тонны текста.
>Оп пишет что исключение сокращает код
оп всё правильно пишет, любой новичок поначалу не понимает, зачем нужны исключения. Я тебе дал пищу для размышлений по поводу того, что die безусловно заканчивает работу программы.
>Ну и нигде нормального объяснения про исключения не могу найти.
exception почти в неизменном виде есть в Java/Php/C++/C#/js, написаны килотонны паст и разбито много копий, а ты не можешь найти объяснения. Главное качество погромиста - умение гуглить, запомни.
>зачем отлавливать ошибку если можно вместо die
вот прям так и загугли. Только не на русском, конечно

Аноним 2019/05/03 21:19:15  №1393636 12
Как выполняется код в пыхе при одновременном запросе? Представим ситуацию, что два пользователя(или больше) нажали одновременно одну кнопку, которая общается с базой данных. В этом запросе берётся ид последней записи(count всех записей), создаётся новая запись и берётся её ид. Возможно ли, что возьмётся ид второй созданной записи(тип сначала от первого юзера, потом от второго)? Или лучше самостоятельно присвоить ид +1 от последнего?
Ответы: >>1393656 >>1394575
Аноним 2019/05/03 22:07:10  №1393656 13
>>1393636
Пых сам не обрабатывет http запросы. Запросы обрабатываются сервером (apache, nginx) затем на каждый запрос создается (гурбо говоря) отдельный процесс php, которому через стандартный ввод stdin и переменные окружения передаются параметры запроса. Данные попадают в массив $GLOBALS. Все запросы обрабатываются независимо.

Пых сам не обрабатывет SQL запросы. Он соеденяется с СУБД и передает через сокет запрос. СУБД выполняет запрос независимо от процесса PHP

id записи в базе данных обычно автоматически инкрементируется при создании новой записи. На момент выполнения запроса к СУБД таблица блокируется на запись для других запросов (грубо говоря). Все изменения с таблицей будут последовательны.
Ответы: >>1394166 >>1394573
Аноним 2019/05/04 20:02:30  №1394148 14
image.png (14, 149x572)
572x149
Антошки, памагите. Есть два массива, оба ассоциативные. Смысл таков, что значения первого и ключи второго идентичны. Как скрестить таким образом, чтобы получился массив с ключами первого и значениями второго массива? Разумеется все лишние варианты просто игнорить за ненадобностью.
Ответы: >>1394160 >>1394185 >>1394571
Аноним 2019/05/04 20:12:33  №1394160 15
>>1394148
Тебе функций для работы с массивами что ли мало?
Ответы: >>1394162
Аноним 2019/05/04 20:13:21  №1394162 16
>>1394160
Их дохуя и нет ни одной нужной. По крайней мере единственная, что по описанию подходит - требует равное количество элементов в обоих массивах.
Ответы: >>1394174 >>1394200
Аноним 2019/05/04 20:15:55  №1394166 17
>>1393656
>Пых сам не обрабатывет http запросы. Запросы обрабатываются сервером (apache, nginx) затем на каждый запрос создается (гурбо говоря) отдельный процесс php, которому через стандартный ввод stdin и переменные окружения передаются параметры запроса.
Ваш пых совсем не умеет в демонизацию и асинхронность?
Ответы: >>1394178 >>1394181 >>1394569
Аноним 2019/05/04 20:33:54  №1394200 18
>>1394162
Жопой прочитал документацию, ищи еще.
Даю подсказку: решение в одну строку, используется две функции, обе array_*. И ты близок к истине: твой вопрос задан верно, что есть 50% успеха — одна из функций именно скрещивает массивы.
Ответы: >>1394202 >>1394240
Аноним 2019/05/04 20:58:27  №1394228 19
>>1380485 (OP)
Читая коменты повышаю самооценку.
Ответы: >>1394233 >>1394569
Аноним 2019/05/04 21:13:11  №1394240 20
>>1394200
Даже не приблизился. Что функции хоть делают? Мне даже приблизительно трудно представить как это действие на две части делить.
Ответы: >>1394245 >>1394248 >>1394261
Аноним 2019/05/04 21:28:20  №1394261 21
>>1394240
Одна меняет местами ключи и значения, другая ищет пересечения ключей в двух массивах.
Ответы: >>1394267 >>1394269 >>1394283
Аноним 2019/05/04 21:35:37  №1394269 22
>>1394261
Ты лучше скажи, как удалить все значения массива после конкретного элемента? Ваще похуй, можно от ключей отказаться и перевести всё в обычный массив или ещё как. Главное оставить в массиве определённое количество значений, с первого и до определённого. Допустим, двадцатого.
Ответы: >>1394273 >>1394569
Аноним 2019/05/05 00:47:51  №1394323 23
На какой стул сесть? Linux или vagrant?
инфибо опенсервер
Ответы: >>1394377 >>1394386
Аноним 2019/05/05 08:14:26  №1394386 24
image.png (52, 690x630)
630x690
image.png (105, 1193x693)
693x1193
>>1380485 (OP)
Помогите криворукому поставить тему на юйку (yii2)
делал по этому гайду https://medium.com/@jsnook_58598/how-to-use-a-bootstrap-4-theme-with-yii2-974a6dcca986
ошибка пик 1
бандл у меня пик 2
или отправьте читать тему в документации на которой я проебался
>>1394323
Да что удобнее то и ставь
вамп от лампа не прям чтоб особо отличается, по моему первому впечатлению по крайней мере
Ответы: >>1394569
Аноним 2019/05/05 11:12:49  №1394459 25
image.png (102, 1064x569)
569x1064
>>1393617
Не хотел засорять, но с исключениями остались вопросы
>и что блядь, я говорю тебе, это дерьмо в приличном обществе даже не упоминают, а ты
Ну так я это прочитал в бестселлере, который имеет 4 издание. Тебя в яндекс не взяли так что не знаю про какое общество ты говоришь. Но так как я не считаю яндекс каким то топовым местом и перейти на PDO мне не трудно

>оп всё правильно пишет, любой новичок поначалу не понимает, зачем нужны исключения.
Вот смотри как выглядит задача, которую я программирую(задача ОПа). Есть список студентов в БД. Мы должны к нему подключится. Если подключение не удалось я НИЧЕГО НЕ ДЕЛАЮ. Все, прога завершает свою работу. Естественно на боевом сервере нужно было бы вывести красивую ошибку, но сейчас не про это. Мой вопрос заключается вот в чем. Зачем использовать исключения, если:
1) Этот код занимает больше места чем тот вариант который я написал;
Сравни
try {
$dbh = new PDO('mysql:host=localhost;dbname=""', $user, $pass);
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}

и

$conn = new mysqli ($hn, $un, $pw, $db);
if($conn->connect_error) die($conn->connect_error);

Ну кстати первый вариант с pdo, а второй с mysqli. Я просто не знаю как можно сокращено написать с pdo. Где то их вооб
2) Так еще вместо die() если это нужно конечно можно было бы подключить файл с выводом той красочной страницы с ошибкой, мол НЕ УДАЛОСЬ ПОДКЛЮЧИТЬСЯ С БАЗОЙ ДАННЫХ, ПРИНОСИМ ИЗВИНЕНИЯ.

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


Я это все пишу не для того чтобы поспорить. Просто мне кажется так мы сокращаем строчки кода вроде бы без ущерба.
Ответы: >>1394511 >>1394569
Аноним 2019/05/05 15:26:47  №1394569 26
170-312

>>1394459

Твой код с try/catch написан неправильно. try/catch если и ставят, то только 1 раз, в самом начале программы, а не вокруг каждого вызова функции. Потому код там будет выглядеть так:

$dbh = new PDO('mysql:host=localhost;dbname=""', $user, $pass);

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

Глобальный обработчик исключений ставят либо с помощью set_exception_handler, либо с помощью try/catch в самом начале программы.

>>1394386

У тебя какая-то ошибка синтаксиса - какой-то лишний символ (например: неразрывный пробел), или какая-то слишком старая версия PHP, или какое-нибудь двоеточие вместо точки с запятой, или русская буква вместо латинской.

Попробуй этот файл вставить в ideone и проверить, будет такая же ошибка или же другая. Если такая же - то дело именно в символах.

>>1394269

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

Вот, читай список тут: https://www.php.net/manual/ru/ref.array.php

>>1394228

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

>>1394166

Для демонизации там есть php-fpm. Зачем нужна "асинхронность", если синхронный код писать проще и он понятнее, я не понял. Но если тебе хочется мучаться с промисами и евент-лупами, то ReactPHP к твоим услугам.

Синхронность это плюс: синхронный код проще. В отличие от языков вроде ноды, где код писать тяжело. То, что PHP умирает после каждого запроса, это плюс: у нас нет утечек памяти. В отличие от языков вроде ноды или руби, где (вроде бы) нет профайлеров памяти, по крайней мере бесплатных, и при утечке люди просто тупо прибивают приложение по крону, чтобы оно не отъедало всю память, так как не могут найти эту утечку.

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

И я не считаю, что нода это что-то плохое, но есть ситуации, где PHP просто удобнее использовать.

А еще, PHP хорошо оптимизирован, есть типизация и у нас готовят JIT.
Ответы: >>1394581 >>1394643
Аноним 2019/05/05 15:37:44  №1394581 27
>>1394569
>Твой код с try/catch написан неправильно. try/catch если и ставят, то только 1 раз, в самом начале программы, а не вокруг каждого вызова функции. Потому код там будет выглядеть так:
ну, кстати, тут я бы поспорил. Разные мнения на этот счёт, моё таково, что в try catch надо оборачивать каждый (в разумных пределах) вызов функции, где возможен выброс исключения, и которое ты планируешь обработать.
Ответы: >>1394582 >>1394733
Аноним 2019/05/05 15:38:38  №1394582 28
>>1394581
то есть несколько try/catch в одном коде это ок, особенно если разные исключения ловятся и они в разных местах возникают
Ответы: >>1394733
Аноним 2019/05/05 18:32:37  №1394643 29
>>1394569
>Твой код с try/catch написан неправильно. try/catch если и ставят, то только 1 раз, в самом начале программы, а не вокруг каждого вызова функции. Потому код там будет выглядеть так:
Так стойте, что это значит? А что тогда должен ловить try/catch?

>>1394513
Вот посмотри мой код, пожалуйста. Где тут ошибки. Мне нужно оборачивать запрос $dbh->query($query); в try/catch? Если да, то какую ошибку функция query() может выбрасывать? Тоже PDOException?

<?php
require_once __DIR__ . '/login.php';
try {
$dbh = new PDO('mysql:host=localhost;dbname=', $un, $pw);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
echo 'Подключение не удалось: ' . $e->getMessage(); //$e->getMessage() не нужно писать, получается?
}

$query = "CREATE TABLE student (
id SMALLINT NOT NULL AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
surname VARCHAR(50) NOT NULL,
gender ENUM('male', 'female') NOT NULL,
groupNumber VARCHAR(5) NOT NULL,
email VARCHAR(30) NOT NULL UNIQUE,
totalPoints SMALLINT UNSIGNED NOT NULL,
yearOfBirth YEAR NOT NULL,
localOrNonresident ENUM('local', 'nonresident') NOT NULL,
PRIMARY KEY (id)
)";

$dbh->query($query);
$dbh = null;
?>
Ответы: >>1394656 >>1394732
Аноним 2019/05/05 19:41:31  №1394656 30
>>1394643
Я не оп.
Популярное решение - это централизованный обработчик исключений в ядре твоего фреймворка, как можно ближе к точке входа. В зависимости от режима DEVELOPMENT/ PRODUCTION ты можешь выводить ошибки на экран или молча логировать в файл Собственно единая точка входа и для этого тоже нужна.
>>1394607
Я не оп.
Под хелперами обычно понимают методы/функции шаблонизатора, хотя зависит о терминологии конкретного фремворка.

Сервисы обычно имеют отношения к Dependency Inversion https://ru.wikipedia.org/wiki/Принцип_инверсии_зависимостей фреймворка. Предполанается что ты пишешь в ооп стиле. У тебя куча классов зависящих друг от друга наследованием и композицией (когда один инстанс класса содержит ссылку на инстанс другого класса). Чтобы инстанцировать класс тебе нужно, предварительно инстанцировать кучу других классов, от которых он зависит путем композиции. DI во фреймворке:
1 позволяет обобщеным образом описать зависимости между классами (иногда автоматически интроспекцией получается инстанцировать класс)
2 позволяет осуществлять замену классов зависящих от друг друга наследованием или наследующих один интерфейс

Ты дожен понять что DI это не дополнительный улучшизм, а основной метод содания объектов во фрейймворке. Сервисы это классы твоей бизнес модели как ты выразился. Если твой класс ниотчего не зависит то тебе ненужно вставлять его в DI Собственно ты приходишь к утилитам.
Аноним 2019/05/06 05:52:34  №1394732 31
>>1394643

> А что тогда должен ловить try/catch?

Ты урок про исключения прочел? Смысл исключений как раз в том, чтобы не писать кучу if или кучу try/catch.

> Вот посмотри мой код, пожалуйста. Где тут ошибки

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

В твоем случае надо либо использовать set_exception_handler, либо оборачивать все в огромный try/catch.

> Если да, то какую ошибку функция query() может выбрасывать? Тоже PDOException?

А в мануале ответа нету? Тут например: https://www.php.net/manual/ru/pdo.error-handling.php

Ошибки естественно могут быть: ошибка в SQL-запросе, ошибка связи с БД.

> Мне нужно оборачивать запрос $dbh->query($query); в try/catch?

Не нужно.

Что использовать: PDO или mysqli - не принципиально, они оба поддерживают исключения.

>>1394604

Померяй или погугли тесты.

Ответы: >>1394743
Аноним 2019/05/06 05:54:58  №1394733 32
>>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 06:46:42  №1394743 33
image.png (119, 1250x796)
796x1250
>>1394732
>чтобы не писать кучу if или кучу try/catch.
В смысле? На той же яве и в C++ try/catch нужно было на каждый чих ОТДЕЛЬНО устанавливать, а в PHP он как то по другому действует? Тип как try/catch может выглядеть ОДИН на всю программу?

>В твоем случае надо либо использовать set_exception_handler, либо оборачивать все в огромный try/catch
Я чет не понимаю. try/catch должен оборачивать что? ??

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

Ответы: >>1394746 >>1394747
Аноним 2019/05/06 07:01:29  №1394746 34
>>1394743
Короче, вот если так сделать, то что будет. Это кстати разработка БД, мне не нужно выдавать ошибку


<?php
set_exception_handler(function (Throwable $exception) {
//Код из мануала ОПа
error_log($e->__toString());

header("HTTP/1.0 503 Temporary unavailable");
header("Content-type: text/plain; charset=utf-8");

});
require_once __DIR__ . '/login.php';

$dbh = new PDO('mysql:host=localhost;dbname=', $un, $pw);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //И куда теперь эту штуку девать?
$query = "CREATE TABLE student (
id SMALLINT NOT NULL AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
surname VARCHAR(50) NOT NULL,
gender ENUM('male', 'female') NOT NULL,
groupNumber VARCHAR(5) NOT NULL,
email VARCHAR(30) NOT NULL UNIQUE,
totalPoints SMALLINT UNSIGNED NOT NULL,
yearOfBirth YEAR NOT NULL,
localOrNonresident ENUM('local', 'nonresident') NOT NULL,
PRIMARY KEY (id)
)";

$dbh->query($query);
$dbh
Ответы: >>1394749
Аноним 2019/05/06 07:01:39  №1394747 35
>>1394743

Пусть у тебя все запросы идут через index.php. Тогда можно написать в нем:

require_once '....error_handler.php';
initErrorHandler();

try {
require_once 'bootstrap.php';
$fc = new FrontContrller();
$fc->handleRequest();
} catch (Throwable $e) {
handleException($e);
}

Альтернатива:

require_once '....error_handler.php';
initErrorHandler();
set_exception_handler('handleException');
$fc = new FrontContrller();
$fc->handleRequest();

Соответственно, во всех остальных местах кода try/catch не нужен, так как исключение будет поймано в index.php. Объясни теперь, откуда у тебя идея, что его надо писать много раз?

В мануале специально дан такой пример, чтобы с помощью расположения try/catch показать, в каком месте выбрасывается исключение. Это не значит, что ты его должен копировать строка в строку. Более того, там объясняется, как отключить выброс исключений и использовать ERRMODE_WARNING, потому и try/catch так поставлен, чтобы исключение не вылетело наружу из кода. А у тебя цели "отключать" исключения нету. То есть ты нашел в мануале пример, который вообще отношения к твоей ситуации не имеет.

В яве и Си++ то же самое, не требуется везде ставить try/catch.

Видимо, я плохо в уроке про исключения это объясняю. Но тебе определенно надо изучить исключения получше.
Ответы: >>1394765
Аноним 2019/05/06 07:04:56  №1394749 36
>>1394746

Если это скрипт, который запускается вручную из консоли (командной строки), то вообще писать try/catch не нужно, так как PHP в этой ситуации при исключении выведет информацию о нем и завершит скрипт. И соответственно, header в консоли не имеет никакого смысла.

Если это не скрипт в консоли, а для веба, то надо делать, как я описал выше, либо set_exception_handler, либо все завернуть в единственный try/catch.
Ответы: >>1394772
Аноним 2019/05/06 08:09:22  №1394765 37
>>1394747
Еще больше запутался.
require_once '....error_handler.php';
Что это за многоточие и что это подключаем тут?

initErrorHandler();
И эта функция что делает?? Не гуглится

Скажи я правильно понял или нет, пожалуйста.
Берем главный файл index.php. В него входят две первые строчки, которые я не понял и дальше включаем try. В try идет подключение файла bootstrap. А bootstrap это толи модель, толи просто инициализатор в MVC. Там хранятся файлы:
1) Класс, который описывает сущность студент
2) Класс, который работает с базой данных(паттерн TableDataGateway)
3) Класс, который проверяет правильность ввода данных.
Так вот в тех классах исключения писать не надо? Мне не нужно в классе, который реализует паттерн TableDataGateway использовать отлов ошибок/исключение/try/catch?
Подключение к БД в каком месте идет? В TableDataGateway или в index?
Просто если в index, то что мне делать в конструкторе public function __construct(PDO $pdo) { ... } класса TableDataGateway? Взять данные из базы данных в массив?
И где мне тогда подключаться к базе данных? В try/catch до bootstrap?

$fc = new FrontContrller();
$fc->handleRequest();
Это я тоже не понял. Это шаблоны?

И почему в альтернативе не описана функция set_exception_handler('handleException')? Ты подразумевал, что она где то описана?
Ответы: >>1394771 >>1415600
Аноним 2019/05/06 08:26:49  №1394771 38
>>1394765
>А bootstrap это толи модель, толи просто инициализатор в MVC.
Это прелоадер называется. Там инициализируются зависимости, окружение и тд.
Аноним 2019/05/06 08:32:56  №1394772 39
>>1394749
Кстати я подразумевал, что этот скриgn будет использован один раз. То есть он нужен был для GITHub, чтобы можно было включить один раз и все. Он создал бы базу данных и больше не понадобился.
Ответы: >>1394785
Аноним 2019/05/06 09:05:23  №1394785 40
>>1394772

Лучше использовать для этого SQL-дамп. Просто создаем файл с расширением .sql и в него пишем нужные SQL-команды, с точкой с запятой в конце каждой. Дампы можно генерировать программами вроде mysqldump или phpmyadmin, но можно и писать руками (заодно поучишься SQL).

Загружается дамп через программу-клиент БД или через командную строку.

- http://www.mysql.ru/docs/man/mysqldump.html
- пример первого попавшегося, найденного в гугле, дампа: https://github.com/cymitty/Student-list/blob/master/studentlist.sql

Полезно писать дамп руками, чтобы освоить SQL и работу с дампами из командной строки.

Если же тебе надо что-то посложнее загрузки дампа, то надо сделать скрипт для командной строки. При этом делать страницу ошибки не требуется, и писать try/catch тоже, так как по умолчанию PHP выведет подробности ошибки сам.

Почитать про командную строку простыми словами: https://github.com/codedokode/pasta/blob/master/soft/cli.md
Аноним 2019/05/06 19:18:00  №1394909 41
>>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 42
ОПчик, ответь, пожалуйста, нормальная ли архетиктура в >>1394909
Аноним 2019/05/18 10:41:34  №1402423 43
>>1402419
Хочу узнать, нормальное ли у меня ООП в >>1394909
Аноним 2019/05/19 03:51:23  №1402834 44
>>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 45
>>1402834
> скрипт не кросс-платформенны и работают только под Linux/Mac.
Я не автор того скрипта, но не понял зачем давать такой совет. Под виндой бекенд обычно не разрабатывают, во многих компаниях наоборот распространена практика пересаживания всех на мак/убунту, чтобы проекты можно было быстрее поднимать по инструкции. Никогда не видел, чтобы в проекте было несколько параллельных инструкций для разных ОС. Зато часто видел древние проекты, которые не то что на винде запустить нельзя, их нужно запускать только под определённой версией PHP и только под апачем, так как на его rewrite правилах и includ'ах завязан весь код.
Ответы: >>1402920 >>1405044
Аноним 2019/05/19 09:35:10  №1402920 46
>>1402868
> бекенд обычно не разрабатывают
Net Core
Аноним 2019/05/22 23:52:06  №1405044 47
>>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.
170 - 590 Аноним 2019/06/13 04:11:39  №1415600 48
>>1394765

> require_once '....error_handler.php';
> Что это за многоточие и что это подключаем тут?

Многоточие - это путь к файлу, если он в какой-то папке. Файл содержит обработчик ошибок.

> initErrorHandler();
> И эта функция что делает??

Ее надо написать самому, это функция из error_handler.php. Она, как следует из названия, задает обработчик ошибок.

> А bootstrap это толи модель, толи просто инициализатор в MVC.

Это файл, который подготавливает код: например, задает автозагрузчик, создает нужные объекты (или описывает из в DI контейнере). Если он тебе не нужен, то можно его не использовать.

> Так вот в тех классах исключения писать не надо? Мне не нужно в классе, который реализует паттерн TableDataGateway использовать отлов ошибок/исключение/try/catch?

Да, не надо.

> Подключение к БД в каком месте идет? В TableDataGateway или в index?

Можно создавать объект PDO в bootstrap.php, можно в index. Это не очень важно, где именно. Объект PDO создается там же, где и другие нужные для работы кода объекты.

> Просто если в index, то что мне делать в конструкторе public function __construct(PDO $pdo) { ... } класса TableDataGateway? Взять данные из базы данных в массив?

Это DI. Прочитай урок по DI: https://github.com/codedokode/pasta/blob/master/arch/di.md

> Это я тоже не понял. Это шаблоны?

Это Front Controlller, погугли.

> Ты подразумевал, что она где то описана?

В мануале.

Если есть еще какие-то вопросы, уточняй.