«phpClub» — архив тем ("тредов"), посвящённых изучению PHP и веб-технологий.
Аноним 2019/05/06 06:02:15  №1394737
>>1380690

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

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

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

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

> Зачем? Количество записей ведь не изменилось.

Я вроде писал, так везде делают. Когда ты жмешь сортировку, ты хочешь увидеть САМЫЕ большие или маленькие значения, а для этого надо перейти на первую страницу. Иначе ты оказываешься где-то в середине.
Аноним 2019/04/14 08:29:05  №1380690
tmp23.jpg (125, 1173x382)
382x1173
Продублирую в новом ИТТ треде:


>>1380456
>У тебя как-то странно сделано, что параметры сохраняются в $this->get. Это значит, что если ты с помощью функции linkMaker() создашь 2 анонимных функции, то одна будет влиять на другую (параметры, переданные в одну, отобразятся в другой). Это неправильно.

>$this->get
Так ведь там весь массив гет из реквеста, а не просто место для сохранения. Параметры не столько сохраняются, сколько апдейтятся - меняется только один, за который отвечает ссылка, и она пересобирается с новым значением.
Ну и разные функции нет смысла создавать - всегда один гет-массив приходит в запросе и с ним работаем.
Вообще, задумка была такой, что замыкание передаётся в шаблон под каким-то именем, где просто вызывается как на пикрелейтед. Меняются только запрошенные параметры, остальные не остаются как были. Ну и пустой писанины чтоб поменьше.

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

>если мы меняем сортировку, то надо сбрасывать пагинацию
Зачем? Количество записей ведь не изменилось. Я вот со своей этой функцией поигрался - вполне юзабельно вроде. Страницы жмёшь - меняет страницы, сортировку меняешь - сортировка только и меняется, что нажали - то и выводит.
Ответы: >>1394737
Аноним 2019/04/14 08:24:17  №1380688
tmp23.jpg (125, 1173x382)
382x1173
>>1380456
>У тебя как-то странно сделано, что параметры сохраняются в $this->get. Это значит, что если ты с помощью функции linkMaker() создашь 2 анонимных функции, то одна будет влиять на другую (параметры, переданные в одну, отобразятся в другой). Это неправильно.

>$this->get
Так ведь там весь массив гет из реквеста, а не просто место для сохранения. Параметры не столько сохраняются, сколько апдейтятся - меняется только один, за который отвечает ссылка, и она пересобирается с новым значением.
Ну и разные функции нет смысла создавать - всегда один гет-массив приходит в запросе и с ним работаем.
Вообще, задумка была такой, что замыкание передаётся в шаблон под каким-то именем, где просто вызывается как на пикрелейтед. Меняются только запрошенные параметры, остальные не остаются как были. Ну и пустой писанины чтоб поменьше.

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

>если мы меняем сортировку, то надо сбрасывать пагинацию
Зачем? Количество записей ведь не изменилось. Я вот со своей этой функцией поигрался - вполне юзабельно вроде. Страницы жмёшь - меняет страницы, сортировку меняешь - сортировка только и меняется, что нажали - то и выводит.
Ответы: >>1388213 >>1388215
Аноним 2019/04/13 18:18:19  №1380456
>>1379833

У тебя как-то странно сделано, что параметры сохраняются в $this->get. Это значит, что если ты с помощью функции linkMaker() создашь 2 анонимных функции, то одна будет влиять на другую (параметры, переданные в одну, отобразятся в другой). Это неправильно. Лучше сделать так:

function makeLinkGenerator(array $basicParams): callable {
\treturn function (array $override) { ... };
}

Использование:

$linkGen = makeLinkGenerator(['sort' => 'name', 'page' => 3]);
echo $linkGen(['page' => 2]); // Меняем страницу
echo $linkGen(['sort' => 'score', 'page' => '']); // при смене сортировки сбрасываем пагинацию

Можно сделать аналогичную штуку с помощью объекта:

$linkGen = new LinkGenerator([....]);
$linkGen->makeLink([....]);

Можно сделать специализированные функции для разных видов ссылок:

$linkGen = new LinkGenerator([....]);
$linkGen->makePaginationLink(3);
$linkGen->makeSortLink('-name');

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

Можно вместо массива с базовыми параметрами использовать объект ViewParams/ViewFilter.

Также стоит предусмотреть такие вещи:

- если номер страницы равен 1, то его не надо добавлять в ссылку
- если мы меняем сортировку, то надо сбрасывать пагинацию

>>1379741

Возможно, у тебя там отступ (пробелы) перед END или какие-то лишние символы после.
Ответы: >>1380688 >>1380690
Аноним 2019/04/12 14:34:35  №1379829
>>1379804
Надеюсь я тебя правильно понял.

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

$orderBy = $_GET['orderBy'];
$orderDir = $_GET['orderDir'];

LinkHelper::generateLink($page, $searchQuery, $orderBy, $orderDir);

Должно получиться, что-то подобное

/?page=7&orderBy="name"&orderDir="DESC"
Ответы: >>1380001
Аноним 2019/03/28 15:32:26  №1371556
>>1371537

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

Чтобы выбрать только часть записей есть конструкция LIMIT/OFFSET: https://www.sqlite.org/lang_select.html

Обрати внимание, что LIMIT/OFFSET не входит в стандарт языка SQL и является дополнением, которое поддерживается только в некоторых СУБД вроде MySQL или SQlite.

Описание на русском есть тут на примере Postgres: https://postgrespro.ru/docs/postgresql/11/queries-limit (прочти внимательно).

Стандартные способы постраничной выборки данных есть в Википедии: https://en.wikipedia.org/wiki/Select_(SQL)#Limiting_result_rows

2) Я правильно понимаю, кто кнопки пагинации содержат в своих гиперрсылках информацию о текущей странице

Да, в в соответствие с буквой S (stateless) из REST.Сервер не "запоминает", какие параметры сортировки выбирал пользователь.

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

3) Страница шаблона должна быть в одном файле или можно их как-то объединять несколько?

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

> И еще, передача данных в шаблон передается массивом, что насчет быстродействия при передаче больших объемов информации?

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

Учись делать измерения с помощью microtime(true).

4) Ты интуитивно сделал правильное решение. Класс StudentsTable не должен думать, где взять "соединение" (на самом деле не соединение, а просто объект для связи) с БД, какие у него параметры. Он должен получать его снаружи через конструктор. Это называется DI и у меня есть урок про это на гитхабе.

Аноним 2019/03/07 00:13:51  №1360508
>>1359945
>Реестр - это паттерн, который описыв
Спасибо, исчерпывающий ответ. Написал бы ты всеобъемлющую книгу по всем этим аспектам. Они ведь не устаревают. Будет пользоваться популярностью.

>>1359946
>У меня просто времени иногда нет, последние пару недель адски загружен.

А можно узнать, чем ты занимаешься? В студии трудишься или в каком-нибудь банке софт ваяешь?

>Ни в коем случае. Идея DI контейнера - IoC - предполагает
Хорошо, проблему синглтона контейнер решает.
А вот еще вопрос. Создал я класс подключения к мускулу, сделал для него сервис-провайдер, где он создается, а потом внедряю его, куда нужно.

А вот, скажем, мне нужен не один объект, а нужно итеративно и с условиями получить много, тогда что? Нужно будет в контейнере хранить не объект, а класс, а потом внедрять этот класс и там создавать через new?

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

Спасибо, теперь все понятно.

>>1359948
Если у тебя используется дата маппер, то в нем и будет метод для загрузки моделек из БД.

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

>>1359949
> В задаче про студентов сортировку логично сделать аргументом в методе для получения студентов:

Спасибо за разъяснение особенно за последний абзац и за метод, ты сэкономил мне кучу времени.

>То есть перед выполнением нужных действий проверяем наличие логина. При отсутствии - редирект на форму логина с передачей текущего URL

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

>В твоем варианте пользователь может попробовать обойти авторизацию, вызвав напрямую метод "методПослеПосещения".

Но у него не получится, если я объявлю этот метод закрытым. Можно вообще все методы сделать закрытыми и вызывать их через indexAction, в котором сформировать настройки и всякие проверки. Сигнатуру формировать по маршруту. Получится эдакий фронт контроллер, только не физический файл, а метод. Но это что-то идиотское, да? Лол.

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

А это разве не проще, чем файлообменник? Там ведь просто идет редирект на реальный URI при обращении к твоей ссылке. За вечер-другой можно сделать.

>>1359951
>Обычно делают отдельно шаблон для "лейаута" (шапка/подвал) и "контента". Лейаутов может быть несколько - например, один для морды, другой для админки. Как передавать параметры для лейаута? Тут есть варианты:


Я придумал вот что. Я в контроллере общем создал контейнер обычный массив data, куда записываю данные со всех уголков контроллеров и приходящие данные из моделей. В контроллерах-родителях задаю общие данные, в контроллерах специфичные, в методах контроллеров данные еще специфичнее. Данные записываются не через переопределение свойств, а через методы суперкласса.
Потом этот контейнер передаю в вид и обращаюсь к нему из шаблонов типа $data['title'], foreach($data['posts'] as $key => $post) {}, ну и все в таком духе. То есть "лейаут" и "контент" получаются данные из одного глобального массива data, переданного в вид. Так нормально?

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

Ну я имел ввиду, можно ли несколько "контентов" подключать в "лейаут".

Спасибо за ответы, ты будто чистое знание вливаешь мне прямо в мозг. Я, бывает, что-то очень долго ищу, бывает, несколько дней занимает поиск ответа на какой-то вопрос, иногда бывает сам додумываюсь до ответа, но проблема в том, что я не знаю, правильный он или нет. Но вот так очень круто зайти сюда и прочитать ответы на все, что я задавал. Пасиба.
Ответы: >>1360509 >>1361818
Аноним 2019/02/21 01:12:24  №1351739
>>1351675
>>1351497

Генерацию ссылок лучше всего вынести в какую-то функцию. Не надо лепить костыли и разбирать GET-запрос. Тебе надо учиться разделять код на части, а ты пока это сделать не можешь и не можешь выделить отдельно функцию генерации ссылок и объект состояния фильтра.

От чего зависит ссылка?

- от глобальных параметров фильтрации
- от добавленных к ним локальных параметров

Ну так давай так и сделаем. Сделам функцию, которая принимает все эти параметры и выдает ссылку:

getSomePageUrl(string $section, string $sortBy, string $sortDir, ...): string

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

Соответственно, функция примет вид:

getSomePageUrl(Filter $filter, string $sortBy, string $SortDir)

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

Для сбора query string от URL удобно использовать http_build_query - она еще и кодирует данные процентным кодированием (урок про URL: https://github.com/codedokode/pasta/blob/master/network/urls.md ).

>>1351147

А что именно ты не понимаешь? Я, например, делать это задание целиком за тебя не буду. Задавай конкретные вопросы, и если ты не знаешь что-то из теории, может мы подскажем, что можно почитать.

Конкретно в задаче надо знать PHP и SQL.
Ответы: >>1352134
Аноним 2019/01/29 15:08:23  №1337481
Аноны, есть некоторый запрос в бд. Мне его нужно отсортировать по, пусть будет, именам. Я через bindParam привязываю переменную к ключу, но сортировка не происходит вообще, зато если я пишу точно такой же запрос, но без ссылки, то все работает. Для примера:
$stmt = $db->prepare("SELECT xui, pizda "
. "FROM twoja_mat "
. "ORDER BY xui DESC ");
И
$stmt = $db->prepare("SELECT xui, pizda "
. "FROM twoja_mat "
. "ORDER BY :xui DESC ");
$stmt->bindParam(':xui', $xui, PDO::PARAM_STR);
. Причем, если основываться на отладке, то и в первом и во втором случае происходит запрос к бд SELECT xui, pizda FROM twoja_mat ORDER BY xui DESC, но с той лишь разницей, что при привязке ключа, 'xuy' будет в кавычках. Что я делаю не так? Не гуглится нихуя
Аноним 2018/11/05 09:49:47  №1290010
>>1281726
Какая разница, что у тебя на домашнем компьютере?
>>1282306
А почему бы не делать сортировку по баллам дефолтно, если не задан параметр sort_by? Это намного логичнее, чем заниматься подстановкой параметров в ссылки.
>>1282527
Посмотри за Flux, его реализовали в React/Redux например.
>>1283377
Во-первых, студентам один год дают бесплатно, во-вторых можно всегда взять VSCode и настроить. Мне в компании хотели лицензию выдать, но я имаксер.
>>1289947
Лучше всего React/Redux, ибо порог вхождения минимален.
>>1289183
Slim/Silex.
Ответы: >>1290292