Добро пожаловать. Тут мы изучаем язык PHP (а также JS/CSS/HTML/SQL), решаем задачки и даже делаем простые сайты! Зачем? Кто-то хочет сделать себе блог, кто-то приобрести новую профессию, кому-то просто нечего делать.
Пожалуйста, пишите один большой пост вместо нескольких маленьких и не флудите не по теме.
Это тред для начинающих. Не написал за свою жизнь ни одной программы и имеешь тройку по математике? Ты наш человек.
Предыдущий тред был тут: >>1118555 (OP) . Остальные треды есть в архиве: https://phpclub.tech/ или ищутся в гугле по словам "клуб изучающих php" и в архиваче.
Мейлач лежит? Есть запасной тред на доброчане: /s/res/23225.xhtml#i46467
Что самое главное для программиста? Умение аккуратно оформлять код (как, написано во втором посте).
Правила: ведем себя воспитанно, помогаем новичкам, читаем учебники, решаем задачки, постим ссылки на решения, ОП их проверяет и дает советы и замечания. ОП заходит редко, где-то раз в 2-3 дня, у него мало времени, не жди его, решай задачки дальше. ОП отвечает на все вопросы по его задачкам и учебнику, а вот насчет каких-то других вещей - только если останется время. Но в треде немало анонимных экспертов разного уровня, так что вряд ли вопрос останется без ответа.
С чего начать
У нас есть свои уроки по основам PHP, они собраны и выложены по адресу http://codedokode.github.io/phpbook (вас отредиректит на другой домен, не читайте, не сохраняйте, не запоминайте его, он временный). Это учебник для изучающих с нуля, то есть если ты вообще ничего не знаешь, то можно начать с него. Он простой и понятный. Там есть задачи, их нужно решать (чтобы стать программистом, надо писать код — иначе никак). Пости ссылки на решения в тред, мы их проверим, напишем замечания и дадим советы по улучшению. С другой стороны, если этот учебник тебе не нравится, можно читать любой другой. Или официальный мануал. Или все сразу.
Устанавливать пока что ничего не требуется, разве что редактор кода вроде Sublime Text 3, Notepad++, Visual Studio Code, Netbeans PHP или PhpStorm (с ним будет удобнее).
Если не знаешь как решать, запости код, напиши в каком месте остановился и попроси подсказку.
Ты прошел весь учебник? Молодец, но это были лишь основы языка PHP, этого недостаточно. Вот что в идеале надо изучить еще: ООП, как работает веб-сервер, HTML/CSS, SQL, PDO, работа с таблицами в БД, работа с формами, MVC, git, composer, JS, фреймворки, автоматизированное тестирование.
Надо переходить к более серьезным задачкам, которые научат тебя всему этому.
Решения задач лучше показать мне, особенно на ООП,так как сам ты вряд ли увидишь все ошибки. Пости свой код на гитхаб и вкидывай ссылку в тред по мере решения. Я прокомментирую и укажу на ошибки.
Параллельно стоит подучивать английский, на первых порах можно без него, но по мере развития придется все чаще сталкиваться с англоязычными статьями, так что лучше не откладывать. Читать можно news.ycombinator.com - это что-то вроде их хабра. Также можно начинать смотреть фильмы и видео на английском.
Также, у нас есть задачи которые позволят тебе изучить или подтянуть до нормального уровня знания JS/HTML/CSS/SQL. Решай их параллельно с задачами выше.
Оформляй код аккуратно!!! — например пропусти через 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? — Да, однозначно. Посмотри любую вакансию.
Оформляйте код будьте людьмиАноним08/02/18 Чтв 23:41:29#2№1135054
Код нужно писать не как попало, а аккуратно и по правилам. Почему? Потому, что на неакуратно написанный код не хочется даже смотреть.
Если тебе лень выравнивать код руками, закачай его на http://beta.phpformatter.com/ и нажми «format». Робот исправит выравнивание и отступы в мгновение ока (да, прогресс не стоит на месте). Если ты используешь мощную IDE вроде PhpStorm, там тоже есть функция форматирования кода.
Вообще, в PHP долгое время не было единого стандарта оформления кода, все писали как попало и было много бардака, но сейчас дело лучше — есть стандарты PSR-1 и 2. Вот как надо оформлять код:
- переменные и функции пишутся с маленькой буквы, подчеркивание не используется, используется camelCase, пример: $x, $numberOfPeople, printResults() - Название функции начинается с глагола, в стиле «сделайЧтоТо» - не знаешь английский? Не беда, в 21 веке есть решение этой проблемы. Не пиши транслитом, открой лучше Гугл Транслейт или slovari.yandex.ru и найди название для переменной там - в именах классов используется CamelCase, первая буква большая, «_» может использоваться - мы предпочитаем подстановку переменных вместо конкатенации строк: "I am $age years old" — хорошо, 'I am ' . $age . ' years old' — плохо из-за обилия точек и кавычек - мы используем для отступов 4 пробела (можно настроить редактор, чтобы при нажатии Tab он вставлял 4 пробела)
Вот ссылка на стандарты, где все это описано подробнее и даны примеры оформления:
Разбор выражений делается с помощью синтаксического анализа. Он же применяется, например, при разборе компьютерных программ. Мы определяем "грамматику" (набор правил) и по ней делаем разбор.
Для записи грамматики есть разные стандартные способы:
Все эти грамматики определяют правила составления конструкций из минимальных неделимых кусочков языка (терминалы) и других составных конструкций. Например, для математического выражения терминалами могут быть числа и знаки арифметических операций, а составной конструкцией - "сумма", определенная как последовательность конструкций ЧИСЛО "+" ЧИСЛО.
Традиционно разбор выражения делают в 2 этапа:
1) В рамках лексического анализа лексер (токенайзер) разбивает выражение на массив токенов (лексем): "-(22 + 2) ^ 3 ^ 4" -> ['-', '(', '22', '+', '2', ')', '^', '3', '^', '4']. На этом этапе числа группируются в токен, удаляются незначащие символы. Токен может быть представлен строкой, массивом, объектом, в зависимости от задачи. Последовательность токенов можно представить в виде массива или объекта.
Дерево выражения удобно представлять в виде дерева из объектов-узлов разного типа (AST). Ну например, математическое выражение 10 + 2 + 3 ^ 4 можно представить в виде дерева объектов:
Имея такое дерево, мы можем вычислить выражение, преобразовать его, упростить итд.
Для твоей задачи самым простым будет метод "рекурсивного спуска". На вход алгоритм получает "поток токенов", на выходе выдает объект-корень дерева выражения (AST). С деревом потом можно делать что угодно.
Мы представляем поток токенов в виде некоей сущности tokens (это может быть объект, итератор, и тд), которая поддерживает по сути 2 операции: "подглядеть" текущий токен (peek) и "поглотить" (consume) текущий токен с переходом к следующему. Таким образом, парсер читает последовательность токенов за один проход и никогда не "отступает" назад. Это позволяет нам подсоединить выход лексера так, что мы не накапливаем массив токенов, а сразу же разбираем их по мере получения. Вот пример потока токенов, представленного в виде класса:
class TokenStream { // Возвращает текущий токен либо null, если они закончились public function peek(): ?Token { ... }
// Берет токен, проверяет, что он указанного типа, возвращает его // и переходит к следующему токену public function consume($type = null): Token { ... } }
Для начала, мы записываем "грамматику", то есть полный набор правил, по которым разбираются выражения, начиная с верхнего уровня. Я использую синтаксис ABNF ( https://en.wikipedia.org/wiki/Augmented_Backus%E2%80%93Naur_form , советую почитать также про BNF и EBNF):
-------
; Правила записываются в виде "конструкция = определение" ; Например, ниже "операнд" может быть одной из перечисленных ниже конструкций ; Знак / обозначает "или" ; ЧИСЛО - это один токен, который далее не делится на части (терминал) ; строки в кавычках вроде "(" обозначают соответствующие символы (скобку) операнд = ЧИСЛО / "(" выражение ")" / унарный-минус / унарный-плюс
; * значит, что выражение в скобках повторяется сколько угодно раз, включая ноль, ; то есть конструкция "степень" может содержать много операндов и знаков ^, ; а может состоять из одного операнда без знака ^ степень-или-операнд = операнд *( "^" операнд )
; произведение - это набор конструкций "степень", разделенный ; знаками деления и умножения произведение = степень-или-операнд *( ( "*" / "/" ) степень-или-операнд ) сумма = произведение *( ( "+" / "-" ) произведение )
выражение = сумма
-------
Читать правила удобнее снизу вверх (а писать - наоборот).
Эти правила по сути задают алгоритм разбора той или иной конструкции. Ну например, правило 'операнд = ЧИСЛО / "(" выражение ")" / унарный-минус / унарный-плюс' значит следующее:
Когда мы хотим разобрать конструкцию "операнд", мы должны:
- проверить, является ли токен ЧИСЛОм ? Если да - создаем из него узел и разбор закончен - является ли первый токен скобкой? Если да, поглощаем его, затем вызываем правило разбора "выражение", затем поглощаем закрывающую скобку - является ли первый токен минусом? Если да, разбираем конструкцию "унарный-минус" - является ли первый токен плюсом? Если да, разбираем конструкцию "унарный-плюс" - иначе, выдаем синтаксическую ошибку
Правило 'сумма = произведение *( ( "+" / "-" ) произведение )' надо читать так:
Конструкция "сумма" состоит из конструкции "произведение", за которой может идти любое число последоватльностей из знака плюс или минус и конструкции "произведение".
Эти правила можно записать и по-другому. Например, "степень-или-операнд" можно сформулировать так:
; правоассоциативное выражение степень-или-операнд = операнд "^" степень-или-операнд / операнд
; левоассоциативное произведение = степень-или-операнд ( "*" / "/" ) произведение / степень-или-операнд
Возвращаясь к методу "рекурсивного спуска". В нем мы для каждого правила грамматики пишем соответствующую функцию, которая его реализует. Она выглядит так:
function parseSomething(tokens): [Node, tokens]
Она получает на вход поток токенов, поглощает часть из них, возвращает соответствующий им узел дерева и измененный поток токенов. Возвращать на самом деле tokens не обязательно, можно договориться, что функция изменяет состояние переданного ей аргумента.
Если она не может распарсить поток токенов, она сигнализирует о синтаксической ошибке (например, выбросив исключение). Функция может вызывать другие функции для разбора конструкций (отсюда и название "спуск").
Опишу для примера алгоритм функции parseOperand(tokens):
- если текущий токен == ЧИСЛО, то создаем узел типа NumberNode и возвращаем его - иначе, если текущий токен = "(", то поглощаем его, вызываем parseExpression и поглощам идущий далее токен ")". И возвращаем получившийся узел. - если текущий токен - знак минус, то, вызываем parseUnaryMinus и возвращаем результат - если текущий токен - знак плюс, то вызвыаем parseUnaryPlus и возвращаем результат - сигнализируем об ошибке
Пример:
class Parser { ... function parseOperand(TokenStream $tokens) { $token = $tokens->peek();
if ($token->value == "-") { return $this->parseUnaryExpression($tokens); }
if ($this->value == "+") { return $this->parseUnaryExpression($tokens); }
$this->throwExpectedError("expected NUMBER, (, +, or -"); }
Мои правила предполагают, что узел может содержать не 2, а более детей. То есть для выражения "2 + 4 - 3" я создаю один узел SumNode с 3 детьми: 2, 4 и 3. Но это можно поменять и на узлы с 2 детьми, это не принципиально.
Я советую попробовать реализовать метод "рекурсивного спуска".
Если хочешь усложнить задачу, попробуй добавить в выражение: дроби (1/3), функции (sin(x)). Также, можешь попробовать сделать парсер какого-нибудь языка программирования, например, урезанной версии PHP, поддерживающей переменные, функции, конструкции if и for. Начать можешь с описания грамматики.
Ты, может быть заметил, что ключевой элемент парсера - это правила грамматики, а остальной код пишется по ним. Когда правил много, это превращается в скучную рутинную работу.
Потому для таких случаев придуманы генераторы парсеров. Довольно известный - ANTLR ( https://github.com/antlr/antlr4 ), он написан на Яве, но умеет генерировать парсеры на разных языках программирования. Для него, например, есть куча грамматик разных языков: https://github.com/antlr/grammars-v4.
Ты даешь им грамматику и они по ней генерируют код парсера. "Взрослые" парсеры для компьютерных программ делаются по такому принципу, так как вручную их писать долго и легко ошибиться.
еще вопрос: я правильно понимаю, что в QueryBuilder доктриновский (а именно в его метод where()) просто так не всунешь условие селекта типа '((ID = 10) OR (NAME = 'VASYA' AND ID < 5))' ну то есть которое в обычный sql бы переварил? и для этого там есть всякие методы типа expr()?
>>1135122 возможно ли вообще в некий свой метод типа filterNews('where ((id > 5 or (name = ... ))') в качестве аргумента подать подобное условие и на выходе каким-то образом получить queryBuilder, который подставляя свои методы-хелперы такую логику реализует? или лучше использовать доктриновский query() для таких целей?
Вопросы такие: Как правильно добавлять данные с формы в таблицу? Допустим форма регистрации. Не забивать же каждое поле в переменную? В массив, а потом этот массив запихивать в бд?
Как правильно упаковать запись в таблицу с помощью pdo? Есть два файла: index.php, pdo.php. В индексе, в шапке, инклуд файла pdo.php, и сама форма с кнопкой. В файле pdo.php - простой коннект к бд. Пишу корявый prepare вместе с bindParam(допустим без массива, а данные с поля - попадают в переменную) - нихуя не происходит. В то время как форма по загрузке файла, с добавлением в бд инфы по нему - рабочие. Что за магия?
try { $dbh = new PDO('mysql:host = localhost;dbname = $dbname', $user, $pass, array(PDO::ATTR_PERSISTENT => false)); // само подключение
$addUsr = $dbh->prepare("INSERT INTO user (group, name, pass, salt, email) VALUES (:group, :name, :passwd, :salt, :email)"); $addUsr->bindParam(':group', $group); $addUsr->bindParam(':name', $usrName); $addUsr->bindParam(':passwd', $salted); $addUsr->bindParam(':salt', $salt); $addUsr->bindParam(':email', $email); // подготовленное выражение
Допустим на подобном ублюдском примере с "значение поля = переменная". После условия формы, в индексе, стоит $addUsr->execute();
Ну и вариант "красивой" передачи, пожалуйста. Пробовал, кстати, $dbh->exec в начале скрипта, с болванистыми данными, которые должны забиваться при отработке скрипта, но ему похуй. В бд ничего не появляется. Как так, ёбаный в рот? Вопрошал в факе, но там всем настолько похуй, что нихуя вообще не написали.
подскажите, кто шарит. есть доктрина и симфони. есть некие входные данные (прилетают по апи), в которых лежит sql-условие where типа "(name='ABC' AND (category1 = 'X' OR category2 = 'X' OR category3 = 'X') AND price > 10)" в виде строки. оно всегда валидное, т.к. проверяется до попадания и может быть очень сложным с большим уровнем вложенности. задача - отдать выборку по нему.
оно всегда относится к выборке одной и той же сущности. как это условие скормить доктрине?
Вопрос: делал приложение на Symfony c Doctrine, понял, что зря создавал отдельные сущности, так как в будущем их слишком много может быть и не понятно, как потом поддерживать. Сейчас думаю сделать все же одну сущность Product, одну Appearance и одну Variant, ну и Category общую тоже. Однако не понял, как хранить разные характеристики, ну есть, конечно, json, ну как по нему условия, читай фильтры в каталоге, делать. Сейчас у меня есть <select> и в нем все размеры кроватей, все размеры матрасов, где надо, чекбоксы всякие и так далее. Какой есть современный удобный подход. Может, тут даже и Doctrine не нужна.
>>1135464 А вот никаких. Данные в переменные передаются, проверял. Оно просто не пишет в базу. Я хуй знает чому. Скрипт отрабатывает и... пусто. Попробую ещё параноидальный режим ошибок ебануть, чтоб на каждый пёрд выводилось, посмотрю. поле id имеется, оно автоинкрементируемое, его, я так понял, в запросе можно не указывать - оно само ложится. По крайней мере то что мне файл в бд кладёт - так и делает
По тестам. Их лучше вынести в отдельную папку (например, /tests), и классы в отдельный неймспейс, чтобы отделить продакшен-код от тестов. Написать для них отдельное правило автозагрузки в autoload-dev, чтобы оно не применялось на продакшене.
Тестировать код можно на разных уровнях. Можно тестировать отдельный метод, класс, группу классов или все приложение в сборе. Что касается юнит-тестов, ими можно протестировать не любой код. Если, например, код вызывает die(), то его через юнит-тест не протестировать.
Вот, например, твой роутер явно не проверить юнит-тестом, так как он может подключать контроллеры, делать там кучу вещей. Это ведь по сути фронт-контроллер, который занимается роутингом и вызовом контроллера страницы. Как можно его протестировать? Есть разные подходы:
- можно попробовать изолировать его от остального кода, подсунув ему моки вместо настоящих контроллеров. Если бы он не создавал контроллеры сам, а брал их из контейнера, можно было бы передать ему контейнер с моками. Но это, по моему, очень плохое решение, так как оно требует сложной настройки и всегда можно что-то упустить, плюс при правках роутера наша сложная схема может перестать работать. - можно попробовать переделать код роутера, сделать его более тестируемым, вынеся отдельно компонент, который никаких контроллеров не вызывает, а просто разбирает URL. И тестировать этот компонент - ну и наконец, можно перейти на другой уровень, и тестировать роутер вместе со всем приложением. То есть поднять тестовый веб-сервер, вызывать на нем разные URL и смотреть, что придет в ответ.
На мой взгляд, тут разве что третий вариант подходит. В фреймворках вроде Симфони контроллеры лучше поддаются тестированию: там используются объекты Request (вместо $_GET, POST) и Response (вместо вывода страницы напрямую), и там мы можем создать Request, вызвать контроллер и проверить Response. У тебя, к сожалению, это невозможно и контроллер можно тестировать только через end-to-end тесты.
Вдобавок, у тебя в тесте ошибка: REQUEST_URI почти всегда начинается со слеша (еще я видел вариант, когда он начинается с вопроса), а не с букв.
Для readJson() можно было добавить еще позитивный сценарий: чтение файла с правильным путем и извлечение из него какой-то строчки. Файл можно положить в папку вроде assets, resources или создать перед тестом во временной папке (наверно, не стоит).
Далее, если мы посмотрим на testCheckCSRFToken(), то видим, что тут явно не очень удобный для тестирования код. Он не принимает входные параметры явно, а берет их из каких-то глобальных переменных. Тестировать код, который работает с объектами вроде Request было бы конечно удобнее.
Тут конечно в тесте заложено знание подробностей работы защиты от CSRF: тест знает, какие куки проверяет код, какой алгоритм он использует. Если в алгоритме защиты что-то поменять, тест может сломаться. Это можно было бы попробовать исправить, организовав тестирование по-другому:
- вызвать setCSRFToken() и записать выставленные им куки (это было бы удобно делать, если бы он не работал с setcookie(), а записывал бы куки в объект Response), сохранить возвращенный токен - сформировать объект Request с запросом от формы, подставить туда полученный токен и выданные куки - вызвать проверку
Но это требует добавления Request/Response. Еще один вариант - использовать end-to-end тест - сделать тестовую страницу с формой и защитой от CSRF, поднять временный веб-сервер, зайти на страницу, заполнить форму, отправить, проверить ответ. Опять же, требует значительных усилий.
Но зато оба этих варианта могут дать более надежные тесты.
Есть разные точки зрения по организации тестов, но мне кажется, что удобно делать один тестовый метод на каждое требование. Ну то есть, мы думаем, какие мы требования предъявляем к коду проверки CSRF?
- если дан токен в POST и кука, то проверка проходит - если дан токен и кука, но они не совпадают, проверка не проходит - если токен в POST пустой, проверка не проходит - если куки нет, проверка не проходит
На каждое требование можно написать свой метод: testCheckSuccessWIthCookieAndToken, testCheckFailsWithInvalidToken, checkTestFailsWithMissingToken, итд. Для надежности, сам токен можно генерировать с помощью setCSRFToken, чтобы он был гарантированно правильный. Это потребует немного больше писанины, но зато:
- при падении тестов позволит увидеть, что именно не работает - сделает сами функции маленькими и простыми, в них будет легче разобраться, если тест упал и надо его поправить
То же можно сказать и про тест валидатора. Можно было бы тестировать каждую проверку в отдельности (testInvalidEmailFails, testInvalidNameFails и тд). Также, если бы у тебя валидатор не был заточен только на проверку студентво, а был бы разбит на компоненты (отдельно метод или класс проверки email, отдельно имени), то их тоже можно было бы тестировать по отдельности.
Но конечно, и тот тест, что есть, уже полезен и может обнаруживать проблемы.
Также, в тесте testStudentValidation() у тебя есть одно слабое место - там ведь есть проверка уникальности email, и если в БД есть email [email protected], то она может провалиться. Можно наверно этим пренебречь, а можно попробовать придумать email, которого в базе точно не может быть. Тем более, что этот же email используется в тесте вставки студента.
https://github.com/moabit/student-list/blob/master/app/Tests/StudentDataGatewayTest.php#L30 > public function testCountStudents() > { > $this->assertNotFalse($this->studentDataGateway->countStudents()); Этот тест полагается на то, что в тестовой базе есть хотя бы один студент. Можно избавить его от этой проблемы, например, добавив студента в тесте и проверив, что количество увеличилось на один.
> public function testGetStudentsWithWrongField() > { > $this->expectException(\PDOException::class); > $this->studentDataGateway->getStudents('wrongOrderField', 'asc', 15, 0); Этот тест полагается на знание внутреннего устройства StudentGateway. Что, если ым там поменяем PDO на mysqli? Решить это можно, сделав специальный класс исключений на такой случай или взяв одно из SPL исключений: http://php.net/manual/ru/spl.exceptions.php
В README: > To add more students uncomment addStudents function in index.php file лучше написать про вызов cli-скрипта
> echo "Please enter a number of students you want to add to the database:\n"; > $input=intval(fgets(STDIN)); В CLI-скриптах обычно параметры передают как аргументы командной строки, то есть пишут
getopt довольно примитивный (он например не умеет формировать подсказку по аргументам), потому для более сложных случаев ты можешь захотеть поискать какие-то библиотеки для разбора аргументов. Как минимум, такие классы есть в компоненте Symfony Console, ну и наверно есть отдельные библиотеки для этого.
Также, ты в cli скрипте почему-то не подключил ErrorHandler.
https://github.com/moabit/student-list/blob/master/app/Helpers/Authorisation.php Вот этот класс обладает состоянием. Было бы логичнее в контейнере пометить его ,чтобы при каждом обращении создавался бы новый экземпляр. А иначе, представь что ты попробуешь обработать 2 запроса подряд: обработчик первого запроса поменяет состояние объекта и это может повлиять на обработку заипроса от второго пользователя.
Также, метод getStudent возвращает объект студента, но signIn() принимает токен, а не студента. Было бы лучше и тут сделать аргументом студента и таким образом скрыть подробности авторизации (какие поля используются) внутри класса. Это позволит нам менять алгоритм авторизации, не трогая остальной код.
Класс pager назван не очень удачно, он же не только за пагинацию отвечает. Лучше назвать его ViewParams, TableParams или TableFilter. И тогда можно добавить туда методы вроде isSearchActive() вместо {% if pager.search is not null %}.
Получается между таблицами связь один-ко-многим: у каждого заказа может быть ни одного, одно или несколько свойств, которые указаны в поле param таблицы orders_properties. На мой взгляд, решение странное, но такая таблица уже есть, с ней ничего не сделать.
Как из этого сделать сущность Доктрины?
Типа такой: class Order { private $id; private $created; private $height; private $weight; private $length; private $color; ... }
Чтобы оно обновлялось само и значения брались из orders_properties либо были пустыми, если там нужных нет.
>>1135541 Пошел по твоему пути (но не совсем), сделал так:
В классе сущности написал private $weight;
public function getWeight(OrderRepository $repo) { return $repo->findWeightByOrder($this->getId()); }
Затем в классе репозитория: public function findWeightByOrder(int $id) { $conn = $this->getEntityManager()->getConnection(); $sql = 'SELECT o.value FROM orders_properties o WHERE o.param = \'weight\' AND o.order_id = :id'; $stmt = $conn->prepare($sql); $stmt->execute(['id' => $id]); return $stmt->fetch(); }
Плюс тут в том, что не надо заморачиваться с привязкой поля типа ENUM к сущности, т.к. он по дефолту в Доктрине не поддерживается (хотя если бы это была единственная заморочка, было бы заебись), но у меня есть ощущение, что это пиздец костыли и можно как-то намного лучше и изящнее.
Короче целый день проебался с этой Доктриной и понял, что там невозможно вменяемым путем объединить две таблицы в одну сущность. Печально, что для такой хуйни придется делать сущность с названием OrderProperties
>>1135482 Да, я помню что в ПЕДЕО надо отдельно включать обработку ошибок. В общем че я выяснил:
- каким-то хуем я указал путь до файла с подключением в относительном виде "./pdo.php", вместо просто "pdo.php" - начало мне ошибки выводить; - ошибка такая: > Warning: PDOStatement::execute(): SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near
По гуглению понял, что из формы данные по POST не экранируются и получается пиздос. Но я сонный и нихуя не понял. Данный из формы жкранировать отдельно? Форма загрузки файла не предполагает введённые данные, а только путь до файла.
алсо, как, всё-таки, более правильно формочки такие ебенить? По минимуму и аккуратно. В массив всё подбивать?
Чем лучше слить содержимое чьего-то твиттера и сделать из него новости на своем сайте? Guzzle? Twitter Api client? Может есть какой-то бандл для Symfony?
Хочу вкатиться в symphony, стоит сразу переходить в 4 версию? Посоветуйте годный курс, можно платный. Пока только нашел на английском https://knpuniversity.com
>>1135827 в симфони без английского делать вообще нечего. если хочешь на русском, иди битрикс учи.
основные источники начальной инфы - это документация, потом их демо-проект, этот knpuniversity и исходники. другой я пока не нашел (сам учу около месяца). конечно было бы круто посмотреть на код какого-то реального большого опенсорс приложения на 4.
кстати на knpuniversity платно только видео, а оно везде дублируется бесплатным текстом, даже где видео само по себе скрыто. то есть, тебе бесплатно доступны ЛЮБЫЕ уроки. я думаю, там люди платят, чтобы поддержать проект (другая ментальность мол).
>>1135827 алсо, все эти материалы (особенно мануал) знать нужно, но они достаточно базовые. самый лучший курс - это взять на хх.ру какое-нибудь тестовое задание на симфони мидла-удаленщика и попробовать его решить в срок.
>>1135741 потому что надо сначала ее переопределить. иначе это динамически объявленная переменная, что считается плохой практикой из-за своей неявности
Аноны, я вкатываюсь, но у меня видимо какой-то стандартный вопрос. Вот я написал скрипт на пхп, который перебирает 100 миллионов значений (допустим, там только массив и цикл перебора, ничего более) и тратит на это 1 минуту. В течении этой минуты я хочу запустить другой скрипт с этого же домена (допустим test.localhost), но второй скрипт не запускается до тех пор, пока не отработает первый, перебирающий значения. Из-за чего это? Сессий внутри скрита нет, но второй всегда ждет выполнения первого? Какова "природа" этого явления и как по возможности это обойти?
>>1136015 >cli-cкрипт? Нет, скрипт я запускаю через сервер, например так: запускаю test.localhost/1.php и он выполняется минуту, параллельно в другой вкладке я запускаю test.localhost/2.php и он не "отрабатывает" до тех пор, пока первый не завершит работу.
>>1136025 Как именно ты понимаешь, что ждет завершение первого скрипта? Работаешь ли ты с какими-то файлами в этих скриптах? Что в процессах у тебя в этот момент происходит? Сколько процессов php висит\запускается?
>>1136025 Уверен, что браузер не использует тот же коннект к серверу? Попробуй, запустить второй скрипт в другом браузере параллельно. Или вовсе вызвать через какой-нибудь wget
>>1136027 >Как именно ты понимаешь, что ждет завершение первого скрипта? Да я же на тестовом серве делаю на тестовых скриптах. Запускаю первый скрипт, он выполняется, вертится "загрузка" на вкладке. Параллельно запускаю второй скрипт во второй вкладке, в нем одна строка "echo 1", но он выполняется и выводит "1" только после того, как первый скрипт закончит перебирать массивы отработает. Если я запускаю второй отдельно (то есть, первый на этот момент не запущен), то он сразу мне выдает в браузер"1", выполняется он меньше секунды. Короче, я делаю вывод, что он ждет выполнение первого. >Работаешь ли ты с какими-то файлами в этих скриптах? Нет, там просто огромный цикл, который перебирает миллионные массивы несколько раз, он вообще выполняется дольше минуты (почти 2). >>1136032 Если запускаю в другом браузере - то он выполняется сразу, то есть, второй скрипт не ждет выполнение первого.
>>1136037 >Если запускаю в другом браузере - то он выполняется сразу, то есть, второй скрипт не ждет выполнение первого. Поясняю. Причины может быть две. Одна - браузер использует одно и тоже соединение до сервера, а так как ты не написал\не заточил сервер для такого юзкейса, то он ждет, и поэтому все тсопорится. Гугли http 1.1вот это все.
Вторая - браузер может использовать для рендеринга вкладок на одном домене один и тот же процесс с целью оптимизации, в заивисмости от браузера и его настроек. Поэтому у тебя просто стопарится рендеринг, пока не будут получены результаты от первого.
>>1136049 А какая причина наиболее вероятная? Мне кажется, что первая. И где можно поподробнее почитать про это? Или если нагуглю http 1.1 - то понимание придет?
>А какая причина наиболее вероятная? Замени во втором скрипте echo на file_put_cintents в какой-нибудь файл. И смотри, если файл появился сразу, до завершения первого скрипта, значит дело в рендеринг. Если после, значит в запросах.
>>1136085 Он же написал, что неиспользует сессии. И ко всему прочему, мы выяснили, что при одновременном запросе из разных браузеров, все отрабатывает нормально. Так что дело либо в общей песочнице webview, либо в кип-аливе.
пацаны, а что это за такой архитектурный ход, когда ты mysql-таблицу делаешь таким образом attributes(param enum('param1','param2','param3'), value varchar)
зачем так делать? какая выгода? как связывать такие сущности с другими в контексте ОРМ?
В браузере есть ограничение на число параллельных коннектов к серверу, но оно в районе 6-8. Правда, там еще есть HTTP/2, у которого все как-то по другому.
>>1135048 >Также, открою секрет за 1 евро в мес. можно у арубы арендовать. Благодарю, так и сделал. Единственное что мне не понравилось у арубы - это плохой дизайн. Я ожидал выбор датацентра в процессе создания, а оказалось (потом), что выбор был вкладками в личном кабинете. Поднял OpenVPN - всё отлично, пинг правда 200 (Италия по умолчанию, хотел Германию).
Такой вопрос, ОП у тебя нет статей по настройке рабочего окружения через системы виртуализации?
>>1136224 >>1136225 Меня не сами юникс-системы интересуют, скорее процесс развертывания проектов на докере и для чего он. Я работаю на win10, на vbox у меня ubuntu17.04, в /var/www я примаунтил проекты. Удобно, так как IDE работает с локальными файлами, а сам проект поднят на апаче убунту. Встречал в интернете упоминания о том, что на докере/вагранте разворачивают себе рабочее окружение и мне стало интересно насколько это будет удобнее (и будет ли)
Аноны, изучаю laravel и не понимаю некоторые моменты в маршрутизации. Сайт состоит из разных статей и их разделов. Например, при переходе к статьям articles_IT, в раздел PHP выводятся данные из таблицы БД - articles_it, где в записи указана секция PHP. И в итоге есть 4 вида статей articles_X, в которых разное количество их секций. Главное, что в итоге модель узнает, что это за статьи и их секции, и в итоге выполняет необходимое действие исходя из этих данных. Меняется по факту только один лишь запрос к БД. Сейчас написал действие только для главной страницы, в роутах вызывается метод контроллера: Route::get('/', 'MainController@showArticle'); Этот метод возвращает вид, с данными из модели Article: return view('index', ['article'=> Article::loadArticle()]); В модели формируется одна запись из рандомных статей, рандомной секции. Так как передать модели вид статей и их секцию исходя из запроса, как правильно описать в этом случае роут? Посмотрел в документации, дошёл до параметров роутов, но плохо понимаю, как их применять.
>>1136361 запись в одну строку - это что имеется в виду? я не очень понял.
>вопрос по контексту ORM неясен. если у нас есть доп.таблица user_attributes(age, sex) то мы сущности User (которая лежит в таблице users) можем задать поле $sex, которое по связи OneToOne будет ссылать на столбец sex из таблицы с аттрибутами.
а если у таблицы структура users_attributes(param enum('age','sex'), value), то мы так сделать уже не можем.
можно было бы сказать, что так мы можем добавлять любое количество параметров без изменения таблицы, но это не так - все равно придется менять столбец param - добавлять в него разрешенные значения.
короче я не понимаю, в чем плюсы. может, это во времена динозавров так делали
>>1136361 а еще тебя ждет огромное веселье, если нужно в одном запросе сделать where по произвольному количеству этих param. попробуй напиши автоматизацию where с подготовленными запросами. чтобы на вход подавать условие типа 'age = m AND age >= 18' а на выходе получать соответствующие сущности.
>Используй математику. Есть 2 функции для разделения чисел на части, $x % 1000 - берет 3 последние цифры, floor($x / 1000) - отбрасывает 3 последние цифры.
А если я не знаю, что там за число? Допустим, я подобрал для сотен тысяч форму слова, отбросив по три цифры с концов, а на деле число оказалось миллиардом. Остальные шесть цифр не переведутся же. Или нужно делать сперва проверку, не будет ли делимое меньше делителя?
Изучи Query Builder. Symfony Expression может превратить строку в AST (дерево выражения). Ты должен обойти это дерево и составить соответствующее ему условие для Query Builder:
Планирую по работе не айти создать приложение для расчётов. Выбрал js, небольшой опыт имеется. Так вот, есть несколько вопросов: 1. Можно ли расчёты будет сохранять в каком-нибудь формате прямо из браузера, а потом их туда загружать? 2. В чем сейчас актуально рисовать? Канвас или уже что-то лучше и новее есть? Может существуют библиотеки для построения простых чертежей/эскизов в браузере? 3. Не ошибся ли я с выбором джс? Сейчас считаем в экселе.
Если тебе надо работать с чертежами, может тебе лучше писать скрипты для какого-то CAD приложения? Ну там автокад, компас, или какой-нибудь из открытых CAD ( https://opensource.com/alternatives/autocad )?
А так, трудно прокомментировать, не зная задачу. Сам по себе JS неплохой, и к нему много библиотек есть.
>>1136840 Это была бы хорошая идея, если бы потом за программой не должно было бы сидеть пол офиса дамочек. И каждой ставить автокад, хехмда. Я там один его знаю, мне нужно чтобы канвас или что-то подобное само отрисовывало картинку на основе 3.5 введённых данных, чтобы дамочки могли распечатать и сохранить на будущее. Эксель норм, но там нельзя адаптивно рисовать. Плюс нужно расширить функционал, и я подумал, что сделать уже нужно нормально.
сап аноны, у меня такой вопрос, можно ли создать регулярку типа как 0-9 или а-яё, только чтоб она искала символы? В самом гайде я видел про поиск только одного символа
>>1136855 С задачей идеально справитс php. Сам писал подобное. Данные в файле (а лучше в майскул базе), отрисовку делает пхп (вместе с расчётами), а отображение в браузере на хтмл+цсс+жс.
краткость записи чего? явно не селекта, если ты хочешь прописать алиас колонке из такой таблицы.
также если для тебя уже все несложно, расскажи как в доктрине запись из таблицы users_attributes с енамами, допустим 'param = age' указать в качестве поля $age сущности User(@ORM\Table(name="users"))
>>1137100 для работы здесь и сейчас yii2, т.к. его используют только в легаси и динозавры-тимлиды, которым лень переучиваться. они не будут обновляться еще 10 лет.
а для будущего развития более современные и актуальные фреймворки.
>>1137166 проблема двощей в том, что долбоёбы-вкатывальщики 2010+ тут имеют какое-то анонимное мнение, хотчя из приличных контор их гонят ссаными тряпками, ха
>>1137166 я с симфони работаю и мне заебись. через месяцок перекатимся на четверку, а ты дальше сиди и правь легаси. сказочки про жестокую реальность и проверенные технологии рассказывай на вебмастер.ру
> Чем отличается инструкция error_reporting(-1) от error_reporting(E_ALL)? В error_reporting передается число. Функция преобразует его в двоичную систему счисления (двочичные числа - это числа, состоящие только из цифр 0 и 1 вроде 001011001, подробнее http://www.reshinfo.com/dvoichnaya_systema.php ). В этом двоичном числе каждый разряд соответствует виду ошибок, и если он установлен в 0, то PHP игнорирует этот вид ошибок. А если в 1 - то не игнорирует и сообщает о них.
Вообще, мне очень не нравится сама эта идея, что можно игнорировать какие-то ошибки и мне кажется, это очень вредная опция. Но оставим мое мнение в стороне.
E_ALL - это константа, в которой для всех видов ошибок стоит единица (ее значение можно увидеть тут http://php.net/manual/ru/errorfunc.constants.php ). -1 в двоичной форме выглядит как число из всех единиц (то есть единицы стоят даже там, где это не требуется). Зачем писать -1 вместо E_ALL? В старых версиях PHP была такая проблема, что E_ALL раньше не включала в себя определенный вид ошибок (E_STRICT), несмотря на название. Потому люди начали писать -1, чтобы гарантированно все ошибки и предупреждения были включены.
Сейчас конечно писать -1 нет никакого смысла и можно просто использовать E_ALL.
> Создавать класс-валидатор, который будет смотреть сколько файлов было отправлено, их размер и т.д. , или все это через middleware можно сделать? Миддлвеар не для этого. Оно для вмешательства в процесс обработки запроса (оно может менять Request или Response), например:
- ограничение доступа (требовать пароль для доступа в админку) - шифрование и подпись содержимого кук - логгирование обрабатываемых запросов - модификации HTTP-ответа, например, поддержка gzip-сжатия - кеширование страниц целиком
Во-вторых, полученные данные надо вставиь в БД. Для этого достаточно подготовить запрос с помощью PDO, а затем выполнить его с данными из формы. Это описывается в любой статье про PDO.
Также, наверно не надо ловить исключения и выводить их содерждимое пользователю. Логичнее логгировтаь подробности ошибки в лог, а пользователю показывать страницу-заглушку. Описано например тут: https://github.com/codedokode/pasta/blob/master/php/exceptions.md
> зря создавал отдельные сущности, так как в будущем их слишком много может быть и не понятно, как потом поддерживать. А в чем проблема? Я не понимаю. Никак специально их поддерживать не надо.
> Однако не понял, как хранить разные характеристики, ну есть, конечно, json, Есть паттерн EAV.
> ну как по нему условия, читай фильтры в каталоге, делать. По JSON - если БД поддерживает разбор и индексацию JSON (например Postgres), то ещ можно что-то сделать, если нет то EAV. Хотя у тебя с десятком кроватей проблем с производительностью в любом случае не будет.
Если получать weight напрямую неэффективно или невозможно (у тебя тысячи свойств на один заказ), и тебе надо работать с репозиторием, то метод getWeight придется перенести в репозиторий тоже:
public function findWeight(Order $order)
> не надо заморачиваться с привязкой поля типа ENUM к сущности, т.к. он по дефолту в Доктрине не поддерживается Ставится string и вроде как все работает.
> и можно как-то намного лучше и изящнее. Можно взять в Order свойства заказа, перебрать их и найти то, которое отвечает за weight. Хотя я не понимаю, зачем это свойство сделано через EAV. Если оно есть у всех товаров, его проще было просто как поле сделать.
У тебя ошибка в синтаксисе SQL-запроса. Значения из формы тут вряд ли при чем. Попробуй такой же запрос руками в консоли выполнить и посмотреть, что будет.
Потому что в теле класса нельзя писать код вроде $this->var = '2ch';, а можно писать только определения констант, полей и методов. А вот уже в методах писать код можно. Класс это не функция.
Если что, у нас есть в шапке учебник и там есть глава про ООП.
> Вторая - браузер может использовать для рендеринга вкладок на одном домене один и тот же процесс с целью оптимизации, в заивисмости от браузера и его настроек. Маловероятно. Браузеры делаются, чтобы грузить страницы параллельно, единственное, если загрузка одной вкладки как-то умудряется подвесить процесс, то тогда возможно такое.
Проверить можно, открыв инструменты разработчика (Ctrl + Shift + I) на вкладке Network и посмотрев, где висит. Также, можно попробовать strace на сервере посмотреть, где ждет php-fpm/apache.
Я все же подозреваю, что у него где-то спрятан session_start про который он забыл - симптомы указывают на него.
Производительность при такой схеме с монтированием файлов не очень высокая может быть.
Вагрант пытается решить проблему настройки окружения для проекта. Современные горекодеры это слово я сам придумал пишут такой код, что он ломается даже от смены минорной версии библиотеки (не говоря о смене дистрибутива или, упаси, замене ОС на винду), потому они придумывают способы как-то зафиксировать конфигурацию системы, в которой проект точно работает, и запускать приложение именно в этой системе. Разработчики языков вроде Го тоже любят периодически ломать совместимость, что добавляет мотивации.
Вдобавок, если у тебя несколько проектов, то они могут требовать разные версии программ, а в линуксе (в отличие от виндоуз) поставить параллельно разные версии программ сложно - попробуй поставь без компилятора несколько версий PHP или mysql. (линуксоиды делают пакетный менеджер nix/guix, который должен решить эти и другие проблемы и вообще хорош, но им никто не пользуется).
В принципе, ничего плохого в этом нет. Мы ведь используем менеджер пакетов composer для указания зависимостей. Логично, что серверный софт вроде mysql или nginx это тоже зависимости приложения и их стоит описывать. Но почему для этого нужна целая виртуальная машина?
В моем понимании, хватило бы просто строчки в ридми apt-get install php mysql nginx. Не знаю, почему другие так не могут. Для моих проектов обычно этого хватает.
Мне все это не нравится, так как оно скорее всего тормозное, особенно на виндоуз. Требует много места на диске. Но может у тебя этих проблем не будет, а места предостаточно, кто знает.
Вагрант - позволяет настраивать виртуальную машину (virtual box) с помощью конфига на Руби. Обычно используется для описания среды для разработчика. При этом в конфиг можно включить установку в ВМ нужных программ. Про плюсы надо наверно читать документацию. Ну например, плюс то, что новый разработчик не должен мучаться с поиском и установкой программ, а просто выполняет одну команду и получает работающее окружение.
Как я понимаю, идея в том, что разработчик кладет в проект конфиг с описанием ВМ, а ты скачиваешь проект, запускаешь вагрант, он гудит пару часов и ты (если все хорошо и использованные пакеты не удалили из репозитория ОС) получаешь настроенную ОС в виртуалке, в которой проект 100% (а может и не 100) работает. Из минусов, как я понимаю, то, что там например может быть не тот дистрибутив, который тебе нравится, там может быть vi вместо нормального редактора, то есть все настроено не под тебя (как разработчик захотел, так и настроил). Плюс, виртуалка может работать медленно, занимать много места на диске. Ну например, вместо маленького дебиана кто-нибудь засунет туда многогигабайтный центос или десктопную убунту. Также, у тебя может быть например 3 Гб памяти, а кто-нибудь пропишет для виртуалки 2 Гб и она съест всю память.
Докер решает ту же проблему, описание зависимостей, но с кое-какими отличиями. Во-первых, под линуксом используется не виртуалка, а контейнеры, которые просто изолируют процессы от остальной системы и не снижают производительность. Но это только в линуксе - в винде или маке там виртуалка. Во-вторых, докер предлагает запускать контейнеры не только у разработчика, но и выгружать их на продакшен. Таким образом, разработчику теперь не нужен админ, он сам ставит любой софт путем модификации конфига докера. В-третьих, докер поддерживает кое-какие средства для генерации множества связанных контейнеров с прицелом на масштабирование на много серверов. Еще докер умеет оптимизировать хранение образов. Если у тебя есть базовый образ ОС, и ты добавляешь в него нгинкс, то он не создает новый огромный образ, а лишь сохраняет разницу между ними.
Также докер упрощает взаимодействие контейнера с хостом - тебе не надо руками пробрасывать папки, TCP-соединения, он все это делает сам.
Выглядит это так же, в репозиторий кладется конфиг, разработчик запускает докер и через какое-то время получает либо контейнер(ы) с запущенным в нем приложением, либо виртуалку.
Из плюсов - там есть хранилище готовых образов (Docker Hub).
Минусы те же, что и у вагранта. Образ могут настроить не так, как тебе нравится (и скорее всего так и будет). Плюс, не знаю, как сейчас, а раньше демон докера работал из-под рута.
Некоторые пытаются использовать докер как песочницу для запуска недоверенного кода, хотя в документации написано, что такой функицонал не предусмотрен.
Докеру есть альтернатива - lxc. Это свободный инструмент для запуска линукс-контейнеров. Плюсы в том, что его пишут не хипстеры на Го, а серьезные дядьки из Интел и они не навязывают какие-то паттерны использования, минусы в том, что когда я его последний раз пробовал, там многие вещи не работали вообще. Ну и фич меньше чем у докера.
Ансибл - позволяет на основе конфига (они называются плейбуки) настраивать по SSH сервер или группу серверов, можно использовать для деплоя (когда серверов много), для настройки серверов. Ну например, админ может сделать плейбук "поставить nginx, php, postgres" и в одну команду сконфигурировать чистый сервер или несколько серверов вместо того, чтобы заходить на каждый и что-то там править руками.
Хотя мне он не нравится тем, что ему нужен inventory файл и нельзя просто IP сервера в командной строке указать. Плюс, не работает под виндой нормально и под cygwin. Я хотел сделать на его основе playbook, который разворачивает VPN на произвольной чистой машине, но из-за inventory это не удобно и я вернулся к bash скриптам, у которых конечно корявый синтаксис, но нет такой проблемы.
> Встречал в интернете упоминания о том, что на докере/вагранте разворачивают себе рабочее окружение и мне стало интересно насколько это будет удобнее (и будет ли)
Я не очень понимаю, как что у тебя сделано, но конечно, тут надо использовать параметры роутов, чтобы был роут вроде /articles/{topic}/, то есть где раздел задан параметром. Контроллер смотрит на параметр и находит статьи из нужного раздела.
Если у тебя 2 уровня категорий, разделы и секции, то нужен еще роут /articles/{topic}/{section}/
Если тебе непонятна документация, дай ссылку и напиши, какая именно фраза непонятна. Так я вряд ли что-то могу подсказать.
Также, если я верно понял, у тебя несколько таблиц со статьями, это все дурь, и хватит одной таблицы статей. Плюс, таблица разделов и таблица секций. Но тут еще стоит подумать об объединении их в одну таблицу с деревом категорий. Так как интуиция мне подсказывает что это просто категории.
Ты, к сожалению, так описал вопрос, что я ничего не могу понять:
- Чем раздел отличается от секции.
> Например, при переходе к статьям articles_IT Что такое "статьи articles_IT"? Название роута? Название категории статей?
Твой вопрос какой-то странный. Давай лучше рассмотрим товары. Правильно было написать "Есть таблица товаров, товары разной категории, у них бывают разные свойства. В чем плюсы/минусы EAV в сравнении с просто добавлением полей в таблицу с товарами (single table)". И как разные варианты реализовать с помощью ORM.
Вообще, надо начать с формулирования задачи. А она ставится так: есть сущность товар, есть разные варианты товаров, у каждого варианта есть свои наборы свойств (у телевизора - размер экрана, у стиральной машины - число оборотов).
Это называется "наследование таблиц", и там есть разные паттерны:
То, что ты предлагаешь, добавлять колонки в одну таблицу - это как раз паттерн Single Table Inheritance.
Два других паттерна плохо работают для товаров, так как потребуют много таблиц, по числу категорий товаров. Тут-то на помощь и приходит EAV.
ORM тут надо рассматривать во вторую очередь, так как нормальный ORM большинство этих паттернов поддерживает.
Сравниваем:
Плюсы EAV:
- в EAV новые свойства можно добавлять не меняя схему базы данных (не делая ALTER TABLE). Менеджер может делать это через админку, не привлекая программиста. В случае ORM, надо еще переделывать код при добавлении новых свойств. - в схеме с single table (когда у нас есть одна таблица товара с кучей колонок), если свойств много, то колонок тоже будет очень много - сотни, и мы упремся в разные ограничения БД и потери производительности. В случае ORM, у нас еще будет гигантский класс с сотней полей, с которым неудобно работать. - в single table, если свойств много, то большинство колонок будут хранить null и просто зря расходовать место - в single table никак не определено, какие свойства могут быть у той или иной категории товара. В EAV это можно определить через связи. - в single table для эффективного поиска надо создавать огромное число (десятки и сотни) индексов, что негативно скажется на производительности и требует кучу места
Минусы EAV:
- запросы будут с джойнами и в неумелых руках могут работать медленно - вытягивание данных по одному или нескольким товарам может быть чуть медленнее - поиск по нескольким условиям потребует нетривиальной комбинации джойнов (чем больше условий тем больше джойнов) и могут быть проблемы с производительностью.
Если появляются проблемы с поиском, то проще всего подключить поисковый демон вроде сфинкса, который будет держать внутри данные в денормализованном и удобном для поиска виде.
Если ты знаешь еще минусы, напиши. Но я смотрю на список плюсов/минусов и не понимаю, где выигрыш в использовании Single Table Inheritance.
> если у нас есть доп.таблица user_attributes(age, sex) То не очень понятно, зачем она нужна и что мешает эти колонки сразу поместить в таблицу users. Не понятно, зачем вы городите EAV для таблицы пользователей, которые явно отличаются от товаров. Ради производительности?
> то мы сущности User (которая лежит в таблице users) можем задать поле $sex, которое по связи OneToOne будет ссылать на столбец sex из таблицы с аттрибутами. Не можем. Мы не можем в одном классе замапить поле на колонку из другой таблицы. Мы можем только связать поле с другой сущностью (user_attributes).
> а если у таблицы структура users_attributes(param enum('age','sex'), value), то мы так сделать уже не можем. Доктрина так не работает. Она мапит таблицы на классы так, что одна таблица обычно соответствует одному классу, а колонки в таблице - полям класса. Нельзя в один класс замапить колонки из разных таблиц.
Но это и не нужно. Ты в сущности User можешь получить атрибуты и найти в них то, что тебе нужно.
> можно было бы сказать, что так мы можем добавлять любое количество параметров без изменения таблицы, но это не так - все равно придется менять столбец param - добавлять в него разрешенные значения. Это у вас не EAV. В EAV для разрешенных значений обычно делают таблицу.
> короче я не понимаю, в чем плюсы. Скорее всего там у пользователя много атрибутов, большинство их не заполняет и им не хочется хранить NULL. Но вообще, почему так сделано, надо спрашивать у тех, кто это делал.
> Допустим, я подобрал для сотен тысяч форму слова, отбросив по три цифры с концов, а на деле число оказалось миллиардом. Остальные шесть цифр не переведутся же.
Если тебе нужно число тысяч (от 0 до 999) то ты сначала берешь 6 последних цифр числа, потом отбрасываешь 3 последние цифры. И остается ровно 3 цифры, больше 1000 там никогда не получится.
Если тебе нужно число единиц, ты опять же, берешь только 3 последние цифры и больше 999 там не получится.
Плюс, в условии задачи вроде стоит ограничение, что число меньше миллиарда. То есть оно разбивается на 3 группы по 3 цифры каждая. Миллионы, тысячи и единицы. Можешь для надежности сделать 4 группы - добавить миллиарды.
АПИ это не твоя база данных и оно не позволит тебе быстро получать данные по тысячам пользователей. Сначала оно будет тормозить, а потом ты получишь бан за превышение квоты. Я бы советовал перенести информацию об аватарках в базу данных.
Иначе тебе придется делать полноценный планировщик запросов, который должен формировать SQL запросы, запросы к API и объединять их результаты. Попробуй написать выражение посложнее чем A AND B и ты увидишь, как там все запутанно.
Тебе надо формировать условие из того, что предлагает Query Builder, все эти $expr->equals(...).
Сокеты тут зачем? Тут же не чат. Тут просто пользователь меняет параметры и у него должна обновиться картинка. Сокеты тут не нужны и только все осложнят. Хватит аякса. А может даже это все можно рендерить на стороне браузера не дергая сервер.
> с которыми шикарно работает РНР Если ты про ReactPHP, то он на мой взгляд не шикарный. Работа с исключениями там сломана везде - в промисах, в потоках. Как и в ноде, впрочем.
А вообще, Докер стал популярен с развитием облачных платформ. Чтобы сделать приложение независимым от используемой платформы и чтобы его можно было легко развернуть.
Особенно если у тебя какое-то масштабируемое приложение и тебе надо автоматически добавлять новые сервера.
Проблемой докера еще называют сложности с обновлением - в том же докер хабе может быть куча старых образов с незакрытыми уязвимостями.
я не могу назвать минусы EAV, так как только что о нем узнал. по минусам той таблицы, которую мне дал работодатель, я могу сказать, что там все равно менеджер не добавит без программиста новое поле, т.к. там названия полей добавлены в колонку с типом enum, ее все равно надо будет менять. но, как ты сказал, у тут не EAV.
>>1137301 >придется делать полноценный планировщик запросов ну это тестовое задание в одну контору, там таблицы уже даны и менять их нельзя. предполагается (видимо), что будет написан этот самый планировщик с приоритетами запросов, а обращение к тысячам пользователей неактуально.
>Попробуй написать выражение посложнее чем A AND B
>>1137393 Львиная доля работы, у меня, проходила только в нотпаде. Его хватало с головой. А так, есть ещё Brackets, от Adobe. Сорта говен. Когда пд рукой тяжелые проекты, то потребуется какая-нибудь IDE, чтоб проводник в интерфейсе был, да и наглядность проекта не страдала.
Хватит конечно, даже меньше. Майскул будет потреблять столько, сколько ты ему пропишешь в конфиге, если база маленькая, то сотни Мб хватит. PHP скрипты обычно потребляют в районе 50 Мб, но композер с большим числом пакетов может иногда и гиг откушать - тут вся надежда на своп.
>>1137577 ЗЫ редирект надо на то место на странице, откуда был произведен переход. Т.е. скроллю страницу, клацнул линк, перешел и что-то сделал, затем обратно.
Собираюсь учить по 5 часов в сутки / 5 дней в неделю. Будут ли шансы при таком режиме устроиться джуном в конце лета? Первый яп, в универе только бейсик и матлаб ковыряли. Кун с тех вышкой, не ит
Это плохой вариант, плюс нет никакой проверки что в реферере, и есть ли он вообще, лучше явно указывать ?from=feed для указания, куда надо вернуться. Естественно, надо этот параметр тщательно проверять, чтобы не отправить юзера по какой-то плохой ссылке.
Текущих знаний мне хватает чтобы спарсить каждую строчку с помощью str_getcsv($s, "\n"), и затем вручную преобразовать массив с помощью регулярных выражений Это лучший способ и данная функция не предусматривает лучших решений?
- разделитель полей (по ум. запятая) - ограничитель поля, символ кавычки (то есть символ, в который можно заключать строки с пробелами и запятыми внутри) - экранирующий символ (по ум. бекслеш). Он позволяет например вставить кавычку внутрь строки как \" Я не вижу его в RFC, может это какое-то дополнение. В RFC написано что кавычка вставляется как 2 кавычки и значит экранирующим символом должен быть не бекслеш, а кавычка.
> Что такое ограничитель поля? Символ, в который можно заключить значение поля. По ум. двойная кавычка.
> И от чего и что будет экранироваться? Если у тебя есть строка в кавычках "xxx" и тебе надо внутрь нее вставить кавычку, то можно писать "xx\"x" c использованием экранирующего символа. Я не вижу этой особенности в RFC, наверно это какое-то дополнение. В RFC экранирующий символ это кавычка и надо писать "xx""x"
Не знаю, это как-то само собой получается. Наверно учиться, читать документацию, ковырять код, расширять кругозор, читать хабр, news.ycombinator.com. Вот кстати, если ты все задачи из шапки решишь, думаю, получится неплохое начало.
Ну и я не так и много знаю - на Хаскелле написать программу не смогу и рассчитать нейронную сеть тоже вряд ли.
>>1137790 Пиши на ваниле. Потихонечку захочется согласованности данных, инъекций зависимостей, реактивности и прочего. В результате через пару лет напишешь свой гуляр, только кривой. Сложный он потому, что сложен из множества решений, которые необходимы для больших команд и длительной поддержки. А тебе они не очевидны потому, что у тебя таких потребностей не возникает пока.
>>1137807 >Счас бы вк написать. Это как пример большого весьма сложно SPA, написанного без хайп-фреймворков. И работающий, заметь, быстрее чем те же фейсбук и инстаграм на реактах.
>>1137301 >Какие именно символы? Я имел ввиду всё, кроме букв и цифр, но сейчас внезапно сам во всём разобрался оказалось достаточно было написать \\D вместо \D
если у меня в доктрине есть две сущности, Article и Tag (связь many-to-many), то как мне выбрать теги с сортировкой по количеству статей, с которыми они связаны?
Вконтакте не SPA. Там используется штука вроде pajax, то есть оно перехватывает клики по ссылкам, отправляет аякс-запрос и обновляет DOM. По сути только экономит немного времени на перезагрузке страницы. Он не хранит данные локально, не работает в оффлайне, итд.
Не надо так писать. У нас к анонам нет требований, чтобы они знали английский. Изучать PHP можно и без его знания.
Но, конечно, когда ты показываешь код другому, этот транслит в именах переменных или функций бросается в глаза. Потому, что так сложилось, что переменные называют по-английски, и не нам эти правила менять. (хотя сам PHP позволяет использовать кириллицу в именах: $месяц = 1; например).
Потому стоит в таких случаях открывать translate.google.com и подбирать нужный перевод. Так. даже не зная английского, можно давать удачные имена переменным.
Ну и конечно, анону, если он не знает английский, стоило бы потихоньку начинать его осваивать. Наверняка на собеседовании про знание английского спросят, и знать какие-то основы лучше, чем ничего. Уроков для начинающих, я думаю, в интернете полно.
У тебя в условии цикла for стоит $mesyac <=0 то есть цикл выполняется только ПРИ УСЛОВИИ ЧТО месяц меньше или равен нулю. Это условие не выполняется и цикл потому не выполняется не разу.
>>1138091 Что прекратить? Ну не знаю я английский и денег нет пойти на курсы. >>1138101 Спасибо, частично заработала. >>1138102 Отдельное спасибо тебе за гайд с примерами, ты молодец! :3
>>1138209 >какие блядь курсы? Alibra School например, в прошлом году хотел пойти туда, но денег нет (они простят 30к за 9 месяцев обучения). В интернете тяжело учить, пробовал duolingo, но мотивации не хватило и обучение мне показалось сомнительным.
>>1138224 не знаю, я начинал с того, что смотрел симпсонов на английском, а щас вообще не употребляю русский контент (кроме двачей, конечно). правда я этой хуйней много лет занимаюсь
>>1138224 у меня просто пунктик такой, мол стыдно английский не знать. поэтому я всегда если незнакомое слово встречаю, не подаю вида, а потом бегу в словарь смотрю.
Нужно реализовать такую вещь: есть сайт, на нем нужно сделать GUI реализацию смены бэкграунда по css. То есть есть кнопка - жмем, загружаем на сервак файл и этот файл применяется как фон сайта. Всяко разно пробовал гуглить, но не нашел
>>1138462 Ну а хули тут сложного, анонче? Нужно css загружать, да, чтобы он заменял собой исходный? Ну, я бы сделал так. Написал бы форму, которая отправляла бы css на сервер и упаковывала его в отдельную папочку. Путь к этому новому файлику прописывался бы куда-нибудь (в базу, например). В базе (опять же, например), указано какой из файлов является в данный момент активным. Вместо пути к статическому файлу в ссылке можно указать ссыль на файл-обработчик, типа ttps://site.ru/getcss.php Там файл бы отдавал нужный (активный) файл, указывая необходимые заголовки. Ну или тупо заменять один файл другим, если старый не нужен.
Я не уверен, что правильно понял твою задачу, анон, но она, в любом случае, не сложная. Тут не гуглить нужно, а включать воображение. Решить можно разными способами.
>>1138462 Две части задачи: загрузка файла на сервер и изменение css По первому куча примеров в гугле. По второму, в принципе, тоже. Изменение css - это что-то типа вот этого кода (вытащил со своего проекта, суть, думаю, понятна): $('#overlay').fadeIn(400, function(){ $('#popup') .css('display', 'block') .animate({opacity: 1, top: '50%'}, 200);});
>>1138472 >$('#overlay').fadeIn(400, function(){ $('#popup') >.css('display', 'block') >.animate({opacity: 1, top: '50%'}, 200);}); Как я понимаю это окошко для загрузки и правило его анимации. Я полный нуп, крайне сложно вникать в это все.
>>1138477 Я в своей cms-ке сделал настройку темы через GUI (ну там, размеры шрифтов, цвета основных элементов, отступы и пр.) самым тупым способом - все данные храняться в базе в одном поле, которое сериализовано (количество полей статично, поэтому undefined index не будет), но в html-ке вся эта залупа выводится в теге style после подключения основных css. Ну что-то типа
Да, довольно нубски, но какая разница? Работате же.
В противном случае, может есть шанс при загрузке генерировать отдельный css для background-image? Дополнительный css для фонового изображения типа. Там тупо вставляешь строку, дополняя путем до новой имаги.
>>1137790 Попробуй Vue.js, он проще и совместим с jQuery правда, это бед практис
И вообще SPA можно и на jQuery написать
Вопрос в тему, на чем лучше попробовать написать фронтенд для браузерной игры?
>>1138224 В /fl есть годные гайды по изучению английского. В этом, как раз главное погружение, та что когда пишешь код представляй что ты флюент и используй только английский.
Сап народ, хочу оседлать yii2, до этого на другом языке использовал другой фреймворк, но не суть. У меня есть 2 модели, товар и категории товара. Модель категории содержит поля - id name, модель товары содержит поля, id, name, category_id - связанное с моделью категории. В greedview товары я вывожу id, name, category.name, при создании нового товара вместо category.name приходится указывать category_id. В идеале хочу добиться чтобы в форме создания было выпадающее меню с именами категорий.
Подскажите, будет ли такая конфигурация htaccess (пикрелейтед) безопасной.
По умолчанию открывается доступ ко всему, но все, кроме статики (js, css, картинки и прочее) редиректится на /index.php, где уже будет парситься REQUEST_URI и выдаваться 404-ошибка как для несуществующих файлов, так и для запрещенных к просмотру.
Есть ли у такого подхода какие-нибудь изъяны по сравнению со стандартным, когда с помощью htaccess закрывается доступ к папкам и файлам?
У тебя небольшая проблема в том, что за счет break мы выходим из цикла и надо бы после цикла поставить echo с выводом итога. Вот это важная вещь, не забывать, что требовалось найти в задаче и вывести ответ. Если ты забываешь, то после написания программы перечитай задачу и проверь, дает ли твоя программа нужный ответ. Перечитай внимательно условие задачи сейчас.
Также, если ты почитаешь урок, то там было написано, что действия вроде
a = a + b;
можно записывать короче с помощью оператора
a += b;
Это может тут пригодиться.
Также, если ты посмотришь, то в шапке цикла стоит условие $total <= 1000000. Раз оно есть, то if с break не очень-то и нужен. Единственное, в условии неточность - если у нас уже есть ровно миллион, то цикл продолжать не надо. Выполнять цикл надо только пока денег меньше чем миллион.
Вместо того, чтобы закрывать доступ к каким-то файлам, лучше его не открывать с самого начала. Выдели отдельную публичную папку, и сделай ее корневой для сервера (как именно, зависит от используемого веб-сервера, обычно это настраивается в конфиге) так, что за ее пределами файлы вообще не могут быть доступны.
Какие-то простые вещи сверстать или поправить существующую верстку - конечно. Кстати, в ОП посте есть набор задач по HTML/CSS, после прохождения которого как раз будет нужный уровень.
Давай посмотрим на код. Вот у меня ощущение, что ты там некоторые вещи писал не осознанно, а просто наугад, в надежде что заработает. Так не надо делать, сейчас ты учишься и у тебя главная цель не решить задачу как можно быстрее, а разобраться в материале.
Для начала можно попробовать написать алгоритм словами (используя только простые команды, не допускающие двойного толкования). Команд у нас в распоряжении всего несколько:
$x = ... - создает переменную или меняет значение существующей echo ... - выводит строки и числа, в том числе переменные if (условие) { действия } - выполняет действия, если выполняется условие for (...) { ... } - выполняет одни и те же действия много раз в цикле break - немедленно выходит из цикла
Если ты забыл эти команды, перечитай предыдущие уроки или мануал PHP.
Если мы посмотрим на твой код, то мы увидим там куски, которые не имеют никакого смысла, например:
($rubley < 1000000);
Эта строчка проверяет, меньше ли $rubley чем указанная сумма, но с результатом проверки ничего не делает - она не сохраняет результат в переменную и не использует его в конструкции if. То есть она бесполезна.
Далее, если мы посмотрим сюда, то увидим другую ошибку:
$rubley = ($seychas * $procent) + $rubley;
Здесь справа использована переменная $seychas, но на момент выполнения команды такой переменной еще не существует. Строчка, которая ее создает, расположена ниже.
Ну и непонятно вообще, зачем тут для обозначения суммы на счете используется 2 разных переменных.
То есть выглядит, увы, не как осознанно написанный код.
Вернемся к алгоритму. Как бы его записать, используя только перечисленные выше команды? Ну например, так:
------
пусть суммаНаСчету равна 10000; пусть процент равен 1.1;
меняем возраст вкладчика от 16 до 108 лет с шагом 1 год, выполняя каждый год {
увеличить суммуНаСчету на процент;
если (на счету миллион или больше) { выйти из цикла; }
увеличить возраст вкладчика; }
вывести ответ к задаче;
------
Ну а дальше надо переписать это с помощью команд выше.
Вообще, тут ключевое место алгоритма еще можно записать по-другому, более красиво:
пока (на счету меньше миллиона) { увеличить сумму на счету; увеличить возраст на 1; }
Но как эту конструкцию "пока" перевести в код? Тут есть такой вариант:
for (; $sum < 1000000 ;) { ... }
(если ты забыл,что это значит, перечитай урок про циклы внимательно). Мы не пишем в шапке цикла начальное действие и действие, которое выполняется после каждого шага, а оставили только условие продолжения. Но для таких случаев есть более короткая запись - цикл while:
while ($sum < 1000000) { тело цикла выполняется до тех пор, пока условие вверху выполняется; }
Пока еще не все, надо, чтобы выводился тот ответ, который требуется в задаче. А у тебя только какие-то отладочные данные, и непонятно, где окончательный ответ.
Анон, проблема с JS помоги.я немного туп window.onload = function() { btn.onclick = function() { var test = document.getElementById('test'), btn = document.getElementById('btn'), my_img = document.createElement('img'); my_img.src = 'picture134.jpg'; test.appendChild(my_img); что мне тут пофиксиить, чтобы появлялась только одна картинка и чтобы была пауза 5 секунд перед появлением.
Нужно ли использовать функцию addslashes? Для работы с базой данных используются ведь специальные функции типо real_escape_string или плейсхолдеры. Могут ли неэкранированные строки нанести какой-то вред в самом php-скрипте или экранирование нужно исключительно для работы с бд?
Прочитал шапку, не нашёл рекомендованного списка литературы. Мне нужен учебник по пхп, по которому я могу ВЫЗУБРИТЬ основные моменты (список функций для массивов и строк, арифметические действия, типы переменных и прочая справочная информация). Нужно для собеседований.
Внезапно возник такой вопрос, можно ли в регулярку запихать переменную? К примеру если мне надо в тексте перебрать каждую букву по отдельности, то надо тупо копировать код овердахуя раз?
>>1139239 Мне уже второй интервьюер (или как там их называют) втирает про то, что мне НАСТОЯТЕЛЬНО надо прочитать какую-нибудь книжку, потому что там "подробно разбирают сложные моменты" и "дают базу". >"вопросы с собеседований". Уже. Но там короткие ответы, а мне кроме них нужно потихоньку подтягивать "базу", чтобы отвечать более осмысленно.
>>1139373 На простейших. Не помню html тег для нумерованного списка. Не помню название функций "переворачивания" массива и строки. Знаю, что они есть, но на память не помню. В общем, нужно именно зазубривание. Так-то уже начал с общей справочной информации, но в книгах ведь и правда более структурированный подход обычно.
>>1139452 Это нет смысла зубрить, это тупо. Важно именно знать возможность наличия того или иного функционала в языке. Обычно это приходит с практикой. Я вот вообще плохо помню точные имена функций или тегов, всегда гуглю что бы перепроверить и всегда гуглю перед тем, как пилить какой либо свой велосипед.
По моему все книги это просто переписывание документации, ещё и пропущенной через автора, который сам мог многого не знать.
Можешь попробовать https://www.codewars.com, это сборник задач, есть много базовых и 'классических', как раз в том же PHP многие решает одна функция или так может показаться, можно нарешать кучу задач и подтянуть эту базу.
>>1139529 >Это нет смысла зубрить, это тупо. Согласен. >Важно именно знать возможность наличия того или иного функционала в языке. >Обычно это приходит с практикой. Без пройденного собеседования нет практики. Я пилю свои проекты, но этого мало. Сегодня что-то использовал, а завтра уже забыл. Во всяком случае я забываю. Память плохая.
>в самом php-скрипте Имеешь в виду, можно ли так исковеркать вводимые данные, чтобы выйти из строки и поменять логику скрипта? Нет. Строка - это переменная, которая содержит последовательность байтов. И поебать вообще, что ты там напишешь. Проблемы начинаются, когда одна строка соединяется с другой. Для генерации SQL-запроса, например.
>в самом php-скрипте Имеешь в виду, можно ли так исковеркать вводимые данные, чтобы выйти из строки и поменять логику скрипта? Нет. Строка - это переменная, которая содержит последовательность байтов. И поебать вообще, что ты там напишешь. Проблемы начинаются, когда одна строка соединяется с другой. Для генерации SQL-запроса, например.
>>1139539 Што за долбоебизм? Невозможно помнить всё, да и не получится. Всё равно использовать 100% возможностей того или иного инструмента ты постоянно не будешь, что-то ты будешь помнить лучше, что-то хуже. Знать, безусловно, нужно. Но знать нужно не названия функций, а возможности, которыми располагает тот или иной инструмент. Я тоже не помню названий некоторых функций, но если мне понадобится, я за 15 секунд их найду, т.к. знаю что мне нужно.
Хороший интервьюрер будет проверять именно твое мышление, т.к. способность находить выход из трудных ситуаций, способность решать нестандартные задачи и пр. А не дрочить названия функций и тегов.
Я бы советовал тебе сделать тесты. То есть сделать массив всех возможных фраз, и для каждой вписать правильный ответ. Затем в цикле брать каждую фразу, подавать ее на вход твоему коду и сравнивать ответ с правильным.
Так ты будешь всегда знать, насколько хорошо работает код, где он делает ошибки, улучшилось ли что-то после изменений.
Сап, как делать бэкап БД, при возможной потере самой бд? Скажем есть совсем совсем плохой сценарий при котором я потеряю доступ к бд и вообще серверу. Как в таком случае делать бэкапы? Засылать дамп изменений на почту в конце каждого рабочего дня? Или на FTP? Или как-то так?
Кто шарит в Симфони, подскажите, как по уму сделать.
Допустим, у меня есть сайт с новостями, там на главной странице слева новости, а справа теги, допустим.
Я на ShowIndex() на ретурн подаю что-то типа return this->render('index.html.twig', ['news' => $someNews, 'tags' => $popularTags]);
Далее у меня есть еще ShowArticle(), где в основной части страницы уже другая инфа - одна новость с комментами, а справа те же теги.
В итоге можно сделать так: return this->render('article.html.twig', ['article' => $someArticle, 'tags' => $popularTags]);
но получается, если у меня 50 разных разделов, будет 50 раз дублироваться код получения тегов и код вставки этих тегов в шаблон. Более того, этот код может быть в разных контроллерах
Как принято избавляться от такого дублирования? Ведь на каждой странице может дублироваться инфа типа свойств аккаунта, всяких виджетов и еще кучи говна
Я пока придумал только что-то типа return this->render('article.html.twig', ['article' => $someArticle, 'tags' => $this->getPopularTags()]);
и наследовать контроллер от своего базового (который наследуется от симфоневского AbstractController) в котором в защищенные методы вынести эти обращения к доктрине. Есть еще варианты?
>>1139361 возможно интервьюер говорит тебе о книжках по программированию независимо от языка, а не про книжки на пхп.
не стремись вызубрить ответы на "вопросы с собеседований". стремить выучить сам язык и на практике попробовать как можно больше его возможностей. я перед первой работой зубрил про всякие статические переменные, передачу по ссылке и т.д., но не понимал зачем оно нужно и поэтому в момент стресса все забыл. сделай свой проект, дай местным анонам на проверку. пытаться выучить определения бессмысленно, тебя все равно спалят, поверь.
нормальных книг по пхп нет, забудь про них. тебе никто не разжует и не вложит в голову инфу как стать программистом с нуля. только всякие высеры котеровых с кодом типа if($peremennaya = '2') echo '<b>'.$_GET['ADMIN'].' вы админ!</b>';
>>1140224 братюнь, я читал. в контроллере получаю теги - это занчит обращаюсь к репозиторию, который занимается получением. тонкий контроллер как раз это и делает - обращается к модели за данными и отдает их представлению.
у меня контроллер из 5 строк состоит и тем не менее, там есть это дублирование.
Также, если речь о данных для шапки, сайдбара, подвала, то есть того, что есть почти на каждой странице, то тут есть разные варианты:
- базовый контроллер, который выставляет глобальные переменные для твига (глобальные переменные конечно не очень хорошо): http://symfony.com/doc/current/templating/global_variables.html - то же самое, но вызывающееся не через базовый контроллер, а через события kernel вроде before request или before controller. То есть перед вызовом контроллера вызывается твой код и что-то передает в твиг (опять же, глобальные переменные) - специальный "хелпер", который передается в шаблон и из которого в нем берутся нужные данные (вроде {% set tags = pageHelper.getPopularTags() %}) - сделать функции получения данных как расширение к твигу и писать там {% set tags = getPopularTags() %}. Минус - эти функции скорее всего ничего не "знают" о запросе, непонятно как передавать в них какие-то параметры. - заменить объект твига на расширенный, который дополняет переменные нужными данными
>>1140238 под практикой я имею в виду работу в нормальной конторе с аудитами, отгрузками и прочим. без битриксов с версткой и прокладываний витой пары.
>>1135053 (OP) ОП, не знаю, говорили тебе тутошние антоны или нет, но большое тебе спасибо за всю информацию в этом тредике. Очень грамотно и развернуто
Пилю свой бложик, хочу что бы категории в шапку сайта выводило прям из бд. код: https://pastebin.com/0zsCzrkQ Вся страница завалена первым значением из массива.
> $menu_array = mysqli_fetch_assoc($menu_query) Если переместить эту конструкцию в цикл то все работает. Не могу догнать, разве не одно и тоже записать в цикле $menu_array = mysqli_fetch_assoc($menu_query) и $menu_array ?
Я комментирую строчку $date->modify("+{$matches[1]} day"), которая находиться в ложном условии, которая не должна выполниться, и к датам не добавляется астрономическое значение.
Нубо-вопрос: на пикрелейтед "делаю что-то 2" всегда ли гарантированно выполнится только после полной отработки функции check() ? Или нужно обернуть "делаю что-то 2" в if?
Посоветуйте, как вообще делать такой алгоритм, где в одной функции вызывается много проверок
>>1140636 "2" не выполнится только если в ф-ции check будет выброшено исключение throw new Exeption() или где-нибудь там встретится ф-ция exit, die. Еще мог бы быть вариант, если ф-ция check() асинхронная, но в php такого нет, там все выполняется последовательно, даже запросы к удаленным серверам.
>>1140577 Починилось после того как каждой новой итерации создавалась новая дата. Но почему при первой, всё равно, выполнялось ложное условие, и добавлялось астрономическое число?
>>1140636 Да, анон. Когда вызывается функция, управление передается именно ей, а также в стек добавляется адрес возврата, там же существует локальная область памяти для данной функции. Функция выполняется, сохраняет данные в определенном месте, а затем управление передается вызывающей функции, которая получает адрес в памяти данных, которые вернула функция.
Но даже если функция ничего не возвращает, то в любом случае сначала полностью выполнится функция, затем выполнение пойдет дальше.
>>1140636 >Посоветуйте, как вообще делать такой алгоритм, где в одной функции вызывается много проверок
Я всегда делаю в таком йоба-стиле. Если нужно сделать множество проверок внутри какой-то функции, вместо кучи вложенностей, отбрасываю неудачные варианты. Хз красивое это решение или нет.
Во-первых, не стоит совмещать 2 действия в 1 строке. Во-вторых, ты нарушаешь правило приоритетов операторов - !$result = ... эквивалентно (!$result) = ... и некорректно. Это просто в PHP стоят костыли, которые такое разрешают.
Помогач, помоги! Нужно подгрузить скрипт в зависимости от выбранной страницы. Скрипт для страницы/2/ отказывается работать. Как я понял — загвоздка скорее в wordpress, а не в пхп.
32 года, полтора года назад решил перекатиться из своей предыдущей профессии в ойти. начал учить пхп, прошел курсы, сделал несколько учебных проектов, через какое-то время пошел на свою первую работу в одну крупную контору. прокачки было дохуя, но там платили как бомжу (меньше 40к, контора в дс). отработал чуть меньше года и ушел. решил, что нужно учить фреймворк и работать конкретно по нему. начал учить симфони, там как раз подоспела четверка. параллельно фрилансил, учил базы данных, всякие редисы и прочее говно, коммитил в опенсорс. недавно решил потестить свои знания, по приколу нашел мидловские вакансии по удаленке, связанные с симфони, чтобы взять там тестовые задания. выполнил первое, потом мне сказали мол "давайте созвонимся попиздим с эйчаром и техническим директором", попиздели мне прислали оффер на удаленку 100к мидлом плюс пиздатый стек. пригодился и мой предыдущий опыт (задавали вопросы из серии "что вы будете делать, если", а я как раз решал эти вопросы на прошлой работе), и в меру наполненный активностью гитхаб.
пользуясь случаем, хочу сказать ОПу огромное спасибо за его пасту и подробные ответы на вопросы. я, к сожалению, не сделал ни одной его задачи (кроме вводных, когда начинал учиться), но надеюсь найти время и сделать, чтобы послушать его советы.
пусть я буду примером всяким вкатывальщикам, которые ссут и медлят. я, кстати, никогда не задавался вопросом "поздно ли, не поздно ли". мне кажется, если хочешь вкатиться, надо вкатываться, а не сомневаться и слушать чьи-то мнения.
алсо, могу сказать, что на работе по предыдущей специальности я получал больше, чем 100к, но в любом случае 100к больше, чем 40, лол.
>>1141133 конечно пока не заслуживаю. этапы карьеры не перескочить, очевидно, что сразу синьором не стать и я радуюсь каждому небольшому достижению. к чему призываю всех анонов.
если ты ждешь 500к в месяц, чтобы начать радоваться, мне тебя жаль. хотя я сомневаюсь, что у тебя в принципе есть реальный опыт работы.
Я вообще не понимаю тех кто переживает что им уже аж целых 30 лет. Вы в 30 лет на пенсию что ли выходите, или у вас руки в 30 лет отваливаются? Люди на заводе и в 30, и в 40, и в 50 бодро работают. Вот исполнится вам 50-60, тогда и можете жаловаться
то есть считается корректным совмещать return и что-то иное, а также переменной присваивать последовательный результат выполнения каких-то типовых несложных (чаще встроенных) функций. и еще какие-то вещи, щас не вспомнить их, но это и не принципиально.
но в примере >>1140793 в одной строке даже не 2, а 4 действия и все абсолютно разноплановые. налицо желание анона изобрести свой велосипед и всех наебать вместо того, чтобы открыть какой-то реальный код (из того же symfony) и посмотреть, как там сделано. тот же код можно посмотреть для ознакомления с такой штукой как PSR-1/PSR-2
https://ideone.com/hEJMlZ Застрял на задании в строках с массивами и стихотворением. Проблема следующая: я изначально делал задание не через array_rand (так же, как и предыдущие), потому что не понял как это в принципе работает. Мануал читал, в английский могу, но я не въехал, как сделать так, чтобы он выбирал случайное число и при этом выводил из массива его значение. В мануале же описано по сути перемешивание значений и вывод случайного через соотв. команду (echo $input[$rand_keys[1]]), или я что-то не так понимаю? Короче, решал через mt_rand, нашел решение в гугле. Но если с предыдущими заданиями это прокатило, то тут первая и вторая строки (где значения из 1, 2 и 3 массива) получаются абсолютно идентичными. Подскажите плз, можно ли это решить таким путем, чтобы строки были разными или поясните за array_rand, или я вообще все не так делаю, и там нужно использовать что-то другое?
Я написал несколько классов-мапперов для сохранения и получения объектов из базы данных, а также мапперы для трансформации этих объектов в JSON объекты. Поскольку их нужно тестировать, я подумал что это хороший случай, чтобы разобраться с phpunit. И как всегда у меня есть несколько вопросов: 1. Что курить кроме Зандстры и доков phpunit? 2. С чего начать? 3. Как организовать тестирование мапперов для ДБ и JSON, чтобы в дальнейшем при добавлении новых связок "сущность-мапперДБ-мапперJSON" создание тестов не требовало много усилий?
>>1141356 >1. Что курить кроме Зандстры и доков phpunit? Хабр >2. С чего начать? С написания тестов, очевидно же! Для преобразования в JSON функции протестируй. Это не маппер как ты называешь, а сериализатор (php объект -> json обьект). >>1141356 >3. Как организовать тестирование мапперов для ДБ и JSON, чтобы в дальнейшем при добавлении новых связок "сущность-мапперДБ-мапперJSON" создание тестов не требовало много усилий?
Не нужно писать тесты на каждый свой пердёж. Тестируй только то что будешь переиспользовать. Добавление НОВЫХ сущностей вообще ничего не должно менять, это ведь тоже самое что и другие сущности, просто в них информация другая. А вот если ты добавил функционал в базовый класс, то этот функционал уже можно (по идее нужно) тестировать, чтобы эта йоба не ломалась при добавлении новой йобы.
Писать тесты заебывать пиздец, нудное и не интересное занятие. Ещеесли напишешь кучу ебланских тестов, то их тоже придется ПРАВИТЬ, лол.
Дальше, ты должен решить, что и как ты будешь тестировать. Для этого мы берем каждый класс (или группу классов, работающих вместе) и определяем требования к ним. Что они должны уметь делать? Каждое требование будет проверяться тестом. Затем придумываем, как это требование проверить (тут может потребоваться смекалка) и пишем код тестов.
Кстати, самый просто тест - это просто вызвать ту или иную функцию. Это уже позволяет нам проверить, что код не падает на ровном месте и лучше чем ничего.
Но обычно сценарии тестов строятся по схеме "Дано - Если - То". Ну например, "ЕСТЬ пустая база данных, ЕСЛИ вызвать метод подсчета числа записей в ней, ТО он вернет ноль".
Сценарии бывают позитивные и негативные, позитивные проверяют, что при правильных входных данных функция работает, а негативные проверяют ее поведение при неправильных входных данных.
Не всегда конечно очевидно, как проверить то или иное требование, потому задача написания тестов может потребовать креативности, поиска неочевидных решений.
Рассмотрим пример составления сценария тестирования.
Например, у тебя есть класс для сохранения и получения объектов из БД. Какие к нему есть требования? Ну очевидно, первое что в голову приходит:
- маппер должен уметь сохранять объект в БД - маппер должен уметь загружать объект из БД
дальше там могут быть дополнительные требования вроде "маппер должен присваивать id создаваемым объектам", "маппер должен уметь считать число объектов в БД", это ты должен наверно знать, из описания не ясно.
Как проверить требования выше? Тут могут быть разные идеи. Например:
- загрузить в базу данных дамп с известными сущностями - попробовать загрузить одну из них - проверить, что данные загруженные данные соответствуют ожидаемым
А можно чуть схитрить и проверить обе функции сразу:
- сделать пустую БД - вызвать функцию вставки сущности в БД - вызвать функцию загрузки сущности из БД - проверить, что данные вернулись корректные
Как-то так.
Помни еще, что тесты должны быть независимы и не полагаться на очередность вызова, или на то, что другой тест вообще будет вызван.
Привет, возник вопрос о том, как лучше будет выбрать 3 последних ответа каждого треда? Решил, что можно сделать как на пике(union'ы склею потом). Может, есть какое-нибудь более лучшее решение? Буду благодарен.
> Писать тесты заебывать пиздец, нудное и не интересное занятие. Проверять руками ещё нуднее, особенно с ростом приложения. Верно, что править тесты нужно, если они слишком много знают о внутренностях тестируемого кода, тогда при изменении внутренностей нужно будет править тесты. Ещё хорошо юнит-тестируется только код с нормальными разделением ответственности, то есть появляется хоть какая-то объективная метрика хорошего кода - сложно написать тест, значит код скорее всего запутанный.
Подскажите, что можно почитать по алгоритмам и структурам данных для гуманитария. Я накачал седжвика и всяких книжек типа алгоритмы на джава скрипте. Код, который там опубликован, и его логику я понимаю, но теорию не очень. Может есть совсем что то простое?
3 неделю назад я попробовал вкатиться в это ваше погроммирование, ибо сижу на шее у мамки вот уже 28 лвл. Полная залупа оказалось! Буду дальше смотреть аниме и пить пиво и кушать пончики, которые мне принесла бабка. Удачи, ботаны!
Хосспаде! Оно не работает! Оно не живо! Оно мертво! https://ideone.com/9P02fe Оно даже ошибок не выдаёт! Оно пусто! Что я не так сделал? Очевидно же, что проблема в spellSmallNumber. Но где? Я кусочек этой функции запускал отдельно, оно работало. Господи, горе мне!
А ещё PDO истязает мою и без того измученную душу. Как в PDO заменить mysql_real_escape_string так, чтобы оно работало? Нужно при неверном наборе символов перенаправлять на другую страницу с помощью header. Без строки PDO:Quote, которую я пытался использовать, всё работает, но как только я её вставляю, оно не перестаёт переходить, а лишь перезагружает текущую страницу без вывода чего-либо. Отправившись на покорение просторов интернета, я попытался использовать и с try и с prepare, но это было неверным действием. Вот так. Я не понимаю, где моя ошибка?
На первых трёх пиках мои скверные письмена, на последнем, четвёртом, рабочий вариант, но с mysql.
>>1135053 (OP) Аноноимусы, что можете сказать о книге "php быстрый старт" ? стоит ее прочесть, чтобы быстро освоить основы языка и приступать к практике, которая есть в шапке? парочку яп я знаю, но вебом не занимался никогда Кстати, что можете сказать про "php в подлиннике" ? Везде ее нахваливают, но объем ее меня очень отталкивает, так как печальный опыт чтения книг по яп на 1000+ страниц есть
>>1141963 Да, учебник из шапки я просматривал, поэтому и спрашиваю о альтернативах, в виде настоящих книг, хотелось бы поближе познакомится с ооп в пхп, связку с sql и так далее.
>>1141976 Чувак, я тебя не понимаю. Если тебе просто не нравится оформление ОП-а, то можешь взять http://php720.com/ , например.
В общем, учебник ОП-а самодостаточен для первого этапа. "Настоящие" книги мне не нравятся из-за долгого вступления и всяких расшаркиваний, которые НАХУЙ не нужны нубасу, который впервые учится кодить на чем-то кроме ХТМЛ.
>>1142208 главное сразу учить то, что потребуется потом на нормальных работах - ооп, тестирование, фреймворки, бд, линукс и пр. чтобы через два года не оказаться с навыками, подходящими только для дизайн-студии какой-нибудь. все, что у ОПа есть в пасте, грубо говоря, надо выучить (кроме фронта и верстки, лол)
>>1142313 с другой стороны ты не объявляешь функции, классы или константы в этом файле, так что формально ИМЕННО ЭТО не является нарушением именно этого пункта пср. но смешивать логику с представлением - плохая практика.
>>1142399 я тебе так скажу, по этим самым стандартам нужно использовать например твиг с набором дополнительных расширений к нему (которые ты напишешь сам), которые будут заниматься всякой логикой типа получения путей для картинок и т.д. в твиге (или другом шаблонизаторе) можно легко выводить списки, таблички по три ячейки в столбце и т.д.
а в этом коде прям чувствуется, что подпихивали-подпихивали костылей по одному и в итоге все достаточно запутано.
>>1142479 Ммм. А можно на пальцах? Допустим, создал я формочку, где есть чекбокс сортировки по цене или алфавиту. Запросы в БД будут вида order by name asc order by name desc или order by price asc order by price desc
Или ты предлагаешь сразу выгружать всю категорию? Но сортировать по условиям все равно придется - но уже массивы, в которые выгружена таблица.
Сокеты в PHP доступны, так что ты можешь открыть сокет и принимать коннекты. Но в 1 поток. Чтобы сделать асинхронность, как в node, нужны неблокирующие сокеты и библиотека вроде ReactPHP. Но скажу честно, что с ней не все работает асинхронно: тот же PDO синхронный и блокирующий.
>>1142492 Сортировка - это одно. Я говорил именно про выборку товаров.
Хорошо. Попробую рассказать подробно.
Смотри, у тебя есть категория "Мобильные телефоны". В админке у тебя есть возможность добавить атрибуты, которые присущи мобильным телефонам. Ну, пускай, например, это будет цвет, операционная система и ёмкость батареи.
Хорошо, админ это всё добавил. В этот момент в таблице attributes появилось три записи. Каждое из них содержит, как минимум свой айдишник, айди категории и название значения.
Теперь у нас есть товары. У каждого товара должны быть эти атрибуты (но это необязательно). Какие именно значения должны быть? Допустим у нашего мобильного телефона значения такие: черный, iOS, 3200.
После того, как админ всё это добавил, у нас в таблице values появились три записи. Каждая из них содержит в себе как минимум четыре значения: айдишник свой, айди атрибута, айди товара и имя.
Разумеется, между таблицами лучше сделать связи.
Теперь поиск.
Открываем страницу, в которой у нас выпадают все товары из таблицы "Мобильные телефоны". Одновременно с этим подгружаем все атрибуты и, что не менее важно, значения атрибутов.
То есть мы загружаем все те значения, которые у нас есть в таблице и которые принадлежат каким-либо товарам, что исключает вероятность пустого поиска.
Теперь мы чекбоксами отмечаем необходимые значения и клацаем "отфильтровать".
У меня сделано через ajax, но в простейшем случае это можно сделать обычной формой. В сгенерированном URLe (мы отправили форму методом GET) содержаться айдишники значений.
Теперь дело за малым - найти те товары, у которых есть подобные значения атрибутов. И всё. Как реализовать последний шаг - думай сам. Я делаю так:
1. Подсчитываем количество значений в запросе (то есть количество чекбоксов, которые юзер отметил).
2. Далее делаем выборку товаров по данным чекбоксам и отсеиваем те, количество которых не совпадает с количеством чекбоксов.
Но это мой способ, никто не говорит, что всё так и нужно делать. Я пришел к такому решению, оно меня устраивает - работает быстро и надежно.
"имхо" - это дело привычки. Там по факту, как я понимаю, каких-то принципиальных плюсов и минусов нет, это просто дело вкуса. Чтобы бардака в коде не было, в PHP решили принять за основу взятый из Явы стиль с кемелкейсом. Если ты на него перейдешь, он тебе станет таким же привычным.
И не спеши огорчаться. Это ведь возможность получить новые навыки - навыки рефакторинга. В некоторых IDE есть функции рефакторинга, в том числе переименование методов (в идеале, при этом переименовываются все упоминания этого метода). С поддержкой IDE это все делается намного быстрее. Я думаю, это точно есть в PhpStorm (платный) и вроде как есть в Netbeans (бесплатный).
Если вдруг IDE не поддерживает такое, освоишь поиск/замену в файлах.
Ковыряюсь с загрузкой файлов. В PHP есть такая странная фича - если добавить в форму поле <input type="hidden" name="PHP_MAX_SIZE" value="кол-во байт">, то пхп сам проверит, умещается ли файл в эту цифру, иначе ошибка загрузки, как я понимаю. Конечно, это ни разу не безопасно, ведь число передать можно любое. Есть хоть какие-то профиты от этой дырявой фичи? Например, может, пхп не будет грузить целый гиг, а сразу после 10мб - если лимит таков - выдаст ошибку?
Сап давч. Пытаюсь сделать схему бд для хранения инфы о загруженных файлах. В идеале это всё использовать через доктрин орм просто чтобы потрогать. Создал я в общем сущность файл с полями название и вес файла. Унаследовал её сущностью картинка, которая имеет так же поля ширина и высота например. И тут я понял что я нихера не понимаю как это реализовать в mysql. По идее мне нужно две таблицы, таблица картинка будет иметь внешний ключ таблицы файл, но файл может быть и не картинкой, тогда поля картинки будут null или что? А если добавить еще таблицы типа аудио/видео, там же вообще дичь будет твориться. Мне эти связи в бд даются крайне трудно.
>>1142529 Не нужно переписывать. Есть php-cs-fixer, который сам всё поправит, использовать через консольную команду php-cs-fixer fix path/to/project
Некоторые люди идут дальше - делают precommit hook - скрипт который срабатывает при попытке создать коммит - этот скрипт в автоматическом режиме фиксит кодстайл. Во многих библиотеках на гитхабе такое тоже используется, ещё там можно настроить бота (Style CI), который автоматически будет слать пулл-реквесты в репозиторий с кодстайл фиксами.
С объектами работать проще, чем с суперглобальными переменными, так как в коде становится видно зависимости, что облегчает юнит-тестирование и подмену таких зависимостей. И еcho ведь не всегда нужен, если я хочу просто отредиректить пользователя на другую страницу, то я выставлю HTTP заголовок 301 без тела HTTP ответа.
Сап пехепач, в последнее время испытываю сложности с проектированием архитектуры приложения. Простейшее мвс приложение могу построить с роутингом и мини орм, но код выглядит как то убого, не знаю как описать даже. Нету в нем завершенности, удобности. У меня небольшой опыт, хотелось бы понять как быть дальше. Читал банды четерех, может я тупой, но я вообще нихера не раскурил, куда мне себе все эти патерны вставлять. Тоесть я понимаю как работает синглтон, но когда его лучше использовать? Так же и с интерфейсами, фабриками. Я напилил кучу интерфейсов, сижу и путаюсь в них, мне кажется смысл был в другом же? Что бы все понятно было. Когда пишешь объектно, код становится каким то неуклюжим, трудно изменяемым, хотя пытаешься применять di, ioc, solid dry kiss. Но в итоге ты углубляешься в код ради кода, а не ради решения задачи. О великий гуру пхп треда, помоги как мне быть.
Блядь, вот я охуеваю. КТО СКАЗАЛ ЧТО ГЛОБАЛЬНЫЕ ПЛОХО? Кто-то пёрнул и ты тоже перди, мол, эта плохо, хотя всё на них и работает, блядь. Область видимости притащили, используй. Но кто-то со времён 2007го года тащит эту хуйню и оно идёт и едет.
Потом эти пидарасы, с шаблонизацией мозга. ЛОГИКА И ПРЕДСТАВЛЕНИЕ НЕ ДОЛЖНЫ СМЕШИВАТЬСЯ - на каждый чих твиги прикручивают, всякие тупорылые смарти и прочую хуйню. А шаблонизатор тоже предоставляет ЛОГИКУ и простые условия и прочую хуйню. Ну и нахуй мне логика в логике? Нахуй мне ещё пердолить какие-то тупорылые, блядь шаблонизаторы, когда в Yii всё работает адекватно и никто туда лезть не должен, сука. SaaS дохуя?
Из за таких пидарасов вкатываение становится проблемой. Припрутся, пёрнут, что всё плоха и всё. На пике кусочки кода, которым похуй на шаблонизацию. НЕТ, БЛЯДЬ. ДАВАЙ ПРО НЕЁ ПОПИЗДИМ. Уходи из треда и не возвращайся. Ты тут не поможешь ни чем, если будешь в таком же ключе отвечать людям и предлагать твиг вкорячивать.
>>1142655 >куратор тхреда Сука, я проиграл на весь дом. Представил как куратор заставляет детишек писать на PHP, даёт задание запилить магазин, а потом в новостях его показываю как он заставил 2000 детей писать на PHP. Как же я проиграл
>>1142661 > заставляет детишек писать на PHP Есть >даёт задание запилить магазин Есть, но только это файловый обменник >а потом в новостях Пока что нету, ждем на ньюсаче.
>>1142682 Ты еще банду 4х скажи почитать и скажи: "а там дальше разберешься". Это вопервых, во вторых в этих фремворках напихано оверхеда дохуя. Я читал и симфони и ларавель и юи. И теперь я могу тебе сделать говносимвони, шмаравель и хуюи, своим кодом, только это мне не помогло научится объектно что ли делать, хз как объяснить. Иногда тебе надо применить ооп, на некой бизнес логике или каком либо сервисе, но тут уже попадаешь в тупик, так как это не скопировать просто структуру приложения от крутых дядек, а надо понимать самому, как сделать удобнее. Поэтому я хоть и смотрел другие фреймворки, но все равно после этого не особо получается собрать все мысли в кучу, и написать что то более менее читабельное и понятное.
>>1142695 Дали задание: написать запрос к API и взять необходимые данные. Сервак отвечает в JSON. Вот мне и нужно записать код, чтобы при его запуске скрипт опрашивал сервак и забирал с него данные.
>>1142591 >КТО СКАЗАЛ ЧТО ГЛОБАЛЬНЫЕ ПЛОХО много кто, лол. в том числе, ОП. почитай в инторнете, если интересно
>Но кто-то со времён 2007го года тащит эту хуйню и оно идёт и едет кто-то на дельфи пишет и оно все едет
>шаблонизатор тоже предоставляет ЛОГИКУ не нужно воспринимать буквально. под "логикой и представлением" имеется в виду "логика МОДЕЛИ и представление".
>когда в Yii всё работает адекватно лол, codeigniter еще вспомни
>Ты тут не поможешь ни чем, если будешь в таком же ключе отвечать людям и предлагать твиг вкорячивать не передергивай. я такого не предлагал. меня спросили "как согласно современным стандартам должен выглядеть этот код". а нужно ли приводить код к стандартам или нет - это вопрос, на который только тот анон знает ответ
каждому свое - кому прикручивать шаблоны к вордпрессу, а кому работать в современных проектах. если ты агитируешь вкатывальщиков за первый вариант, а я за второй, то почему я должен уходить, а не ты?
пиши дальше простыни кода с глобальными переменными, mysql_query и евалами, другим даже лучше. чем больше таких динозавров как ты, тем проще адекватным анонам устроиться на нормальную работу на нормальный фреймворк за приличную зп.
Привет анон. Только начинаю вкатываться. Хочу вкатится в админство. Уже могу в телнет и настройку свичей, управление/мониторинг l2 l3 l4 уровнями. Хочу вкатится еще глубже в админство. Так понял надо знания php, mySQL. В каком порядке стоит учить ? знания php на уровне работы с массивами. SQL на уровне создавал запросики для лаб в универе.
>>1142711 >твиги прикручивают, всякие тупорылые смарти лол, слышал звон не знаю где он. твиг используют все, в т.ч. его часто используют на Yii2, а смарти - это мамонт из того же 2007, откуда и ты вылез.
Котятки, как можно автоматизировать синхронизация локальных файлов с теми, что на сервере валяются? Вручную делать как-то долбоебично, ибо нужно помнить какие файлы ты отредактировал и всё такое, что неудобно.
>>1142810 очень жаль, потому что в шторме это делается одним кликом
а так можно коммитить в удаленный репозиторий и по сценарию сборки автоматом прогонять тесты и загружать их на сервер. но это достаточно заебно в настройке
>>1142867 Через netBeans тоже можно такое настроить. Я покурил гугл, вроде что-то нашел.
Но а как это делают вообще все нормальные белые люди, не использующие phpStorm?
>а так можно коммитить в удаленный репозиторий и по сценарию сборки автоматом прогонять тесты и загружать их на сервер. но это достаточно заебно в настройке
По совету форумчан (>>1142437) решил установить bbcode. Почитал, посмотрел. В итоге час просидел в неудавшихся попытках установить это ссаное расширения PECL. Есть только для пхп 5.6. Пытаюсь ее пропердолить, вылазит ошибка php5ts.dll. Что делать? опен сервер, винда 7
>>1142892 >Но а как это делают вообще все нормальные белые люди, не использующие phpStorm? таких не существует лол
>Так что ли? вообще это разные вещи. одна чисто деплой файлов, вторая это контроль версий и все увязано около него
обычно простой деплой файлов используется для работы с дев-сервером, где у разработчика своя папка и свой хост, а сценарии сборки применяются для деплоя на продакшн или всякие стейджы.
>>1143039 Порыскал на гите, есть отличные решения, но больно громоздкие для нескольких требующийся мне тэгов. Если что можно и на регулярках пописать в регулярки вообще не знаю, лол
>>1142805 использовать FTP/SSH клиент. Например, CuteFTP. Но он будет перезаливать все файлы. Для выборочной заливки нужно поставить на сервер SVN и использовать svn-клиент на своем компе.
>>1142559 не надо пытаться впихнуть паттерны, потому что прочитал о них. открой код какого-нибудь компонента симфони (ОП рекомендует symfony form) и посмотри, как там сделано.
синглтон признан антипаттерном и вместо него следует использовать DI.
>>1143083 А как вообще лучше проектировать, Например у меня есть какое то стороннее апи отдающее жсон. И разные типы запросов и ответов. Как спроектировать сервис на пхп? с какой стороны подойти? Выделить объекты и установить связи между ними?
>>1142591 >вкатываение становится проблемой Ну если ты будешь себя так вести и так писать код, то для тебя проблемой станет работа и собеседования. И вообще, не тролируй.
>>1143096 да легко, возьми существующую библиотеку для работы с АПИ, например google php api client и посмотри как там сделано.
ты иди от задачи, а не от того какие классы нужно написать. напиши сначала все в одном классе, а потом отрефакторь.
обычно нужно сделать классы, отвечающие непосредственно за коннект и работу с данными (сам Client, всякие коннекторы, менеджеры паролей и т.д.), условно Request, и классы, которые представляют сущности того АПИ, с которым ты хочешь работать, условно Entity. а дальше нахуярить еще много всяких вспомогательных. короче смотри реальный код из библиотек.
>>1143105 по ssh конечно. фтп - небезопасный протокол.
>>1143114 почему же, это типичная позиция какого-нибудь битрикс-программиста. мол все эти твиги и прочую бесовщину используют только хипстеры из кремниевой долины лол, а настоящий код он такой, страшный но работающий, с глобальными переменными и на 5.3.
представляю какой шок его ждет, если он узнает, что существуют конторы, где покрывают код тестами.
С одной стороны, ты правильно делаешь, что пытаешься изучать разные готовые решения (паттерны). В веб-приложениях ничего нового изобретать не надо, все уже придумано до нас. Но с другой стороны, ты неправильно делаешь, что пытаешься обязательно использовать в коде какой-то паттерн. Это говорит о том, что ты в них не разобрался и не понял, для чего они нужны, когда их используют.
В программировании (как и в вообще в инженерных науках) для каждого решения есть обоснование. Почему мы хотим сделать так, а не иначе. Чаще даже есть не одно решение, а несколько, мы сравниваем плюсы и минусы и выбираем то, что лучше подходит. Вот например, если у тебя есть свободное время, ты можешь почитать отчет о разработке радиопередатчика для первого спутника (он длинный): http://russianspacesystems.ru/wp-content/uploads/2017/10/Otchet-o-razrabotke-bortovoy-radiostancii-pervogo-sputnika.pdf . В этом отчете формулируется задача, разбираются разные варианты ее решения, и каждый раз обосновывается, почему выбран тот или иной вариант. Например, почему были выбраны лампы, а не транзисторы. Вот в идеале у тебя в голове должен происходить такой же мыслительный процесс. Начинающему, может, это и сложно, но со временем надо к этому стремиться.
Если ты сомневаешься, то можно по умолчанию выбрать самое простое решение. Такое решение, которое требует минимум затрат времени и усилий. Не уверен, нужен ли тебе ORM? Ок, не используй. Но если потом ты заметишь, что пишешь много однотипных SQL запросов, то может быть стоит все же подумать про ORM.
Ну например, я могу для решения какой-то задачи написать просто скрипт на 200 строчек без ООП (и иногда даже без функций), а потом по мере надобности добавлять объекты, библиотеки, итд.
То есть должно быть так: возникает потребность в чем-то и ты применяешь какое-то решение. А не так, что просто подключаешь в проект библиотеку, потому что о ней написали на Хабре. И здесь, конечно, полезно умение замечать эту потребность, видеть, что в коде что-то не так. Ну вот например, ты замечаешь, что получается много однообразного кода и думаешь, как это исправить.
Также полезно, когда ты смотришь чужой код, думать, а почему тут сделано так, а не иначе. Какие еще были варианты? Это поможет тебе научиться инженерному мышлению.
> Простейшее мвс приложение могу построить с роутингом и мини орм, но код выглядит как то убого, не знаю как описать даже. "выглядит убого" - это не критерий. Ты должен подумать и сформулировать, чем именно плох код. Если никаких мыслей нет, запости кусочек, может более опытные аноны что-нибудь подскажут.
> Тоесть я понимаю как работает синглтон, но когда его лучше использовать?
Когда надо сделать невозможным существование более одного экземпляра объекта ни при каких обстоятельствах. На практике это редко когда нужно, и это неудобно (например, при тестировании мы хотим создавать временные независимые объекты, а не менять свойства этого синглтона), мне так в голову ничего не приходит.
> Так же и с интерфейсами, фабриками.
Про интерфейсы есть урок - https://github.com/codedokode/pasta/blob/master/php/interfaces.md - там есть немного, но в общем интерфейсы мы используем, когда хотим дать возможность писать новые классы, с которыми сможет работать существующий код. Ну например, интерфейс логгера PSR-3 - мы используем в коде интерфейс, а не название конкретного логгера, и благодаря этому можем подключить любой логгер. Почитай про PSR-3 как пример использования интерфейсов, если не знаком с ним.
Фабрика - это класс, создающий объекты. Может использоваться в такой ситуации: есть какая-то библиотека, которая создает объекты. И мы хотим дать пользователю возможность влиять на создание этих объектов. Код библиотеки он править не может, потому мы выносим создание объектов в фабрику и разрешаем пользователю написать и передать библиотеке свою фабрику.
Из примеров использования фабрик я могу вспомнить разве что https://github.com/symfony/form - там есть класс FormFactory (он создает объекты форм и полей в формах - и те и другие там называются Form). Я, кстати, советовал бы тебе разбрать эту библиотеку, в том числе код, и нарисовать диаграмму классов в ней - там много интересного.
Но ты должен добавлять фабрики и интерфейсы только когда ты почуствуешь потребность в них. А не просто добавлять, чтобы были.
> Я напилил кучу интерфейсов Зачем?
> Что бы все понятно было. Да, так и должно быть.
> Когда пишешь объектно, код становится каким то неуклюжим, трудно изменяемым Может ты не очень хорошо разобрался в ООП? По идее, применение ООП как раз позволяет упростить код, так как он разделяется на отдельные классы, каждый из которых решает свою задачу. Ну и почитай статью про хлеб выше, она как раз про это.
> Но в итоге ты углубляешься в код ради кода, а не ради решения задачи Хорошо, что ты это понимаешь. Попробуй тогда использовать более простые подходы, может для твоей задачи хватит 10-20 функций без ООП? Или может быть не надо так много разных классов.
> помоги как мне быть. Так как ты не описал свою задачу и не показал куски кода, которые тебе не нравятся, то я могу только дать общие советы.
Ты хочешь написать сервер API (раздавать данные всем), или клиент (получать данные из стороннего сервиса)?
Ты можешь попробовать "выделить объекты", но попытайся сначала сделать минимальный вариант, просто решающий задачу. Может для твоей задачи даже не нужны объекты, а хватит просто массивов (хотя сомневаюсь, что это удобно). Ну и наверняка для твоей задачи уже есть какие-то готовые библиотеки - для преобразования в JSON точно что-то должно быть.
> синглтон признан антипаттерном и вместо него следует использовать DI. Я бы лучше сказал так: использования синглтона вместо DI - это антипаттерн. Вполне возможно, что есть какие-то случаи, где полезен синглтон.
Можешь потом написать итоги своих поисков для других анонов.
FTP точно использовать не надо, так как он не защищен и позволяет атакаующему просматривать и подменять информацию. Как замена FTP, есть SCP и SFTP - они работают через SSH. Правда, не так много программ, которые их поддерживают.
Ну а вообще, я обычно стараюсь автоматизировать деплой. Глупо тратить время на выделение файлов, нажатие кнопок в GUI, когда можно написать скрипт. В простой ситуации - bash-скрипт (программа на языке bash) с использованием утилиты rsync (он поддерживает передачу файлов по SSH), в сложной - плейбук для ansible. Учти, что многое из этого плохо работает или вовсе не работает под Windows.
Есть еще вариант "деплой через git" - git позволяет выгружать коммиты в удаленный репозиторий на другом сервере.
Ну если тебе лень изучать утилиты linux, ты ведь программист, что тебе мешает написать программу копирования файлов на PHP? Или поискать готовую. Или как-то настроить программу, чтобы деплой делался одной кнопкой.
Хотя конечно скриптами автоматизировать такие вещи удобнее, на мой взгляд.
Пока не думал, да и не уверен, что найдется много желающих что-то мне заплатить. Сейчас ОПу можно помочь, например, отвечая на те вопросы в треде, на которые ты знаешь ответ.
И изучаем все, что написано. Обычно это работает так:
Если ты используешь дебиан, то сначала ищешь расширение в apt-get (менеджере пакетов Дебиана), если там его нет, то ставишь через pecl (pecl сам скачает исходники расширения, скомпилирует его и установит). Это просто и удобно, хотя, если будут какие-то ошибки, то конечно без понимания процесса сборки разобраться будет трудно.
Ну и судя по истории релизов, оканчивающейся в 2010 году, с PHP7 это расширение вряд ли совместимо.
Гугление по "bbcode php7" выдает проект - https://github.com/esminis/php_pecl_bbcode - но там нет сборок под винду, то есть там дан только исходный код и надо его самому собирать. В принципе, наверно, это было бы неплохим опытом для тебя, попробовать собрать расширение под виндой, но рассмотрим еще другие варианты.
В документации написано, что есть аналог расширения в виде библиотеки на PHP - http://pear.php.net/package/HTML_BBCodeParser . Он ставится через PEAR - это менеджер библиотек, который умеет их скачивать и устанавливать, но сначала придется научиться им пользоваться, например, найти статью про него или изучить документацию. Но это точно проще, чем компилировать.
Также, есть еще другие разметки, кроме BBCode. Берешь список тут https://en.wikipedia.org/wiki/Lightweight_markup_language изучаешь каждую и проверяешь, есть ли для данной разметки php-библиотека. Например, поиском в packagist.org (репозиторий библиотек для композера).
Изучи linux, bash, основные утилиты. По PHP - от админа требуется только умение его установить и может чуть подправить php.ini (почитав мануал), по MySQL - установить и настроить, и на сайте MySQL есть 2 раздела специально для администраторов:
Может у тебя отключен их вывод через опцию display_errors в php.ini? Или включено их игнорирование через error_reporting? Проверь настройки (с помощью phpinfo()) и изучи логи, может там есть ошибка.
Я выше расписал, что лучше всего начинать с самого простого решения и добавлять какие-то усложнения по мере надобности. Почитай статью про выпечку хлеба.
А еще, если вдруг ты не очень уверен в ООП, то у меня еще есть пара задач - про Гостиницу и Агенство - не хочешь хотя бы глянуть? https://phpclub.tech/pr/chain/1108694/
> во вторых в этих фреймворках напихано оверхеда дохуя. А ты не думал, что это может быть сделано по какой-то причине? Вряд ли у них есть цель просто так увеличивать объем кода.
Что такое "легкие потоки"? LWP? Если тебе хочется использовать треды, то наверно можно найти какую-нибудь библиотеку под линукс и взять потокобезопасную версию PHP. Но подозреваю, там будут подводные камни, так как я не слышал, чтобы кто-то это использовал.
> КТО СКАЗАЛ ЧТО ГЛОБАЛЬНЫЕ ПЛОХО? Вот ты бы разобрался сначала. Конечно, глобальные переменные плохо, если у тебя скрипт больше 200 строчек. Потому что их можно изменять из любой точки кода и понять, что в них находится в тот или иной момент времени, не изучая весь код, сложно. Более подробно про них ты можешь прочесть кусочек в пасте про DI: https://github.com/codedokode/pasta/blob/master/arch/di.md#Чем-плохи-глобальные-переменные
В реальных проектах могут быть тысячи файлов и миллионы строк кода, и в таком объеме конечно с глобальными переменными работать невозможно. Так как тебе надо перерыть весь миллион строк, чтобы попытаться понять, кто и что туда пишет и когда. Это нереально.
> Область видимости притащили, используй Так у глобальных переменных глобальная область видимости - они доступны везде (внутри функций импортируются через global) - что ты хотел сказать-то?
> ЛОГИКА И ПРЕДСТАВЛЕНИЕ НЕ ДОЛЖНЫ СМЕШИВАТЬСЯ Конечно, не должны. Тяжело же читать код, когда идет 5 строк HTML кода, потом SQL запрос на 10 строк, потом разбор результатов этого запроса, потом еще 10 строк HTML и так далее. Удобнее в одном файле получать данные, а в другом выводить их на страницу. Особенно когда у тебя сложные страницы, содержащие много разных блоков и сложная логика получения данных. Почитай урок про шаблоны https://github.com/codedokode/pasta/blob/master/php/templates.md
> твиги прикручивают Чем твиг лучше встроенного в PHP шаблона, подробно и доходчиво объясняется на главной странице сайта твига: https://twig.symfony.com/ - пробовал почитать?
> А шаблонизатор тоже предоставляет ЛОГИКУ Логику представления, а не получения данных.
> вкатываение становится проблемой. Проблема скорее всего в тебе и твоем восприятии. Заходи чаще в наш тред, проходи задачи из ОП-поста и может быть, ты все же сможешь разобраться, зачем нужна та или иная библиотека. У нас тебе всегда этого готовы объяснить.
"вкатиться" это значит "устроиться на работу"? В шапке же написано, ищешь вакансии на сайте вакансий, отправляешь отклик, проходишь собеседование и тд. Или тебя что-то конкретное интересует?
Если вопрос "что изучать", то опять же, надо изучить почти всю шапку - серверный язык программирования, SQL, итд.
> И тут я понял что я нихера не понимаю как это реализовать в mysql. Есть 3 паттерна наследования: Single Table Inheritance, Concrete Table Inheritance, Class table inheritance - погугли их для начала и потом задай вопрос, если непонятно.
Учти, что не все паттерны могут поддерживаться в Доктрине, потому глянь еще ее документацию.
Также для удобства пользователя можно добавить код на JS, выдающий предупреждение при превышении размера, чтобы пользователь не тратил время и трафик на загрузку файла зря.
В Слиме используется подход, когда "контроллер" получает на вход объекты Запроса и пустой Ответ, и должен заполнить этот Ответ данными (кодом статуса, телом страницы, заголовками, и всем, что HTTP позволяет возвращать в ответе). Есть еще немного другой подход - в Симфони контроллер получает на вход HTTP-Запрос и должен создать и вернуть HTTP-Ответ.
Зачем? Ну, тут есть несколько причин:
- логичность. Теперь у нас контроллер не создает какие-то побочные эффекты (что-то выводит, создает заголовки, куки), а возвращает на выходе результат свой работы - HTTP-Ответ. Логично же, получаем Запрос, обрабатываем и возвращает Ответ - взаимодействие с middleware. В Слиме есть middleware - обертки, которые могут модифицировать Запрос до его получения контроллером и модифицировать Ответ после того, как он создан, но до того, как он отдан в браузер пользователя. Очевидно, что для этого контроллер должен именно возвращать Ответ. Вывод через echo можно конечно перехватить (и он перехватывается), а вот выставленные через функцию header() заголовки перехватить нельзя и middleware их не получит и не сможет с ними ничего сделать. - тестирование. Мы можем в тесте создать Запрос, вызвать контроллер, получить Ответ и проверить его правильность. Опять же, в случае использования echo/header напрямую, это невозможно. - многоразововость. Мы можем в ходе работы скрипта вызвать контроллер(ы) несколько раз и получить несколько Ответов, и что-то с ними делать, как-то их использовать. Можно например сделать несколько контроллеров, каждый из которых отвечает за свою часть страницы.
Аноны, а вы не хотите это перевести на англ и законтрибутить в документацию Слима? А то мы пошлем человека читать документацию, а объяснения там нет.
В ОП посте упомянуты книги Зандстры и Шлосснейла(?). Единственный недостаток - староватые, но зато учат в правильном направлении. Ну и php the right way.
Ты вбросил в тред код - получил ожидаемую критику. Такие правила этого треда. Но, конечно, важно писать о недостатках корректно. Наша цель ведь не доказать, кто умнее, а обучить.
> Очевидно же, что проблема в spellSmallNumber. Но где? Плюс кода с функциями в том, что мы можем вызывать каждую по отдельности и проверять, правильно ли она работает (дать ей какие-то значения на вход и вывести, что она вернет). Ты можешь как раз это сделать. Заодно натыкать echo в исследуемую функцию, чтобы видеть значения всех переменных в ней. Попробуешь протестировать все свои функции по отдельности? Ты хотя бы найди примерно где проблема, а дальше я могу подсказать, если непонятно.
> Как в PDO заменить mysql_real_escape_string так, чтобы оно работало? Оно там не нужно, используй плейсхолдеры для вставки значений в запрос. Прочти ты уже любую статью про PDO, где объясняются плейсхолдеры.
По другим картинкам - я бы советовал шаблоны выносить в отдельный файл. И прочитать мой урок про шаблоны с гитхаба.
По поводу архитектуры - я бы советовал прочесть урок про MVC ( https://github.com/codedokode/pasta/blob/master/arch/mvc.md ), заметь что он не требует ООП и ты можешь получить его, просто вынеся часть кода (например, получение данных из БД) в отдельные функции. Это, например, облегчит повторное использование кода (сейчас у тебя код получения данных вплавлен в шаблон и его нельзя вызвать из другого места) и тестирование.
Код у тебя правда плохой, видимо ты учился по какому-то устаревшему учебнику.
Призывать использовать ООП или переходить на фреймворки я тут не буду, не нужно этого делать, пока ты сам не почуствуешь потребность в этом. А вот уязвимости оставлять недопустимо.
Вот такой вот у них подход. В Руби он рейлс, которым они вдохновляются, так же. Мне тоже интересно было бы почитать аргументацию за/против, если кому-то еще интересно, нагуглите и напишите тут.
Может они так пытаются упростить код, избавившись от DI? Так там внутри вроде как есть DI конейнер, просто эти статические "фасады" скрывают его наличие.
> Мануал читал, в английский могу, но я не въехал, как сделать так, чтобы он выбирал случайное число и при этом выводил из массива его значение. Тут есть 2 момента, на которые ты видимо не обратил внимание:
- array_rand возвращает не значения элементов, а их ключи. Тебе надо самому получить значение из массива по ключу (подсказка: для этого есть квадратные скобки: $value = $array[$key]). - если попросить 1 ключ, array_rand вернет его. А если 2 или больше - то вернет массив ключей. (это плохой подход, возвращать результат в разных форматах, не делай так). Потому в мануале там использованы квадратные скобки.
> то тут первая и вторая строки (где значения из 1, 2 и 3 массива) получаются абсолютно идентичными. А это потому что у тебя код в стиле:
- взять случайное слово и записать его в переменную $rand1 - вывести в первой строке $rand1 - вывести во второй строке $rand1
Очевидно, что строки будут одинаковые. Тебе нужны разные переменные для первой и второй строк. Либо же использовать цикл из 2 шагов (на каждом шаге генерируем и выводим одну строку).
Аноны, сам Господь спустился с небес и отвечает нам!
Спасибо большое, отпишусь. Я делал на PHP клонирование части логики с одного сервера на другой, когда выстраивал систему обновления сайта. Там по одной кнопочке запаковывался архив с .php файлами, отправлялся просто по https, далее там уже распаковывался и всё такое. Разумеется, все с использованием хеша от (данные + секретный ключ), так как с этим нужно осторожнее быть. Но я отказался от этой системы, т.к. боюсь, она не слишком надежная.
>>1143242 и еще пара вопросов 1. подскажите обязательно ли заключать переменные находящиеся в echo внутрь скобок {}, пробовал без них все работает. Зачем они нужны? 2. Что выделено на пике является дурным тоном в написании кода? html так вставлять нельзя, как я понял.
>>1142743 >>1142711 ЯСНА ВСЁ. Не передёргивай, говорит, а сам передёргивает. Смарти ему из 2007го... а условий, операторы и прочее в твиг не завезли, да? Ладно, ты уточнил на счёт отделение "логики". Но ведь её и отделяют. Модели и пр. Какая, нахуй, разница - видишь ли хтымыло вместе с пшп, или видишь свой ебучий твиг?
> пиши дальше простыни кода с глобальными переменными, mysql_query и евалами Ниче ты ПЕРЕДЁРГИВАЕШЬ
>>1143114 >>1143220 Я насмотрелся уже на хипстеров, которые работая над одним говносайтом, накручивают на него твиги и ебашат его через ГИТ, просто потомушто модно. А если туда надо прикрутить пару процедурок, которые он ниасилил в ходе понимания seo, то ОБЯЗАТИЛЬНА ДАВАЙ ЧЕРЕЗ ГИТ, МНЕ ВАЖНА, НИКТО НИРАБОТАИТ С МАИМ САЙТАМ, НО Я ПАСТАЯННА ГИТПУШУ И ГИТАПДЕЙТЮ И ТЫ ТАК ДЕЛАЙ, НА ХАБРЕ ТАК СКОЗАЛИ.
Про читаемость они мне будут тереть. Научите тут лучше людей классы писать, вызывать всё это, а свои советы про твиги уносите. Принесут догматы про глобалы, твиги, ТЕСТЫ... в тред начинающих, гиты свои прилепят, со словами ТАК НАДА, и рады, ёпт.
>>1141364 >>1141452 >>1141859 Думаю превращение экземпляра класса PHP в JSONAPI объект нельзя назвать просто сериализацией, т.к. мы не только сериализуем класс, когда получаем JSON объект, но предварительно трансформируем класс в объект JSONAPI, например resourceObject, который в свою очередь имеет определенную структуру с обязательными свойствами. И обратная трансформация в большинстве случаев невозможна, т.к. resourceObject не содержит методов класса.
>>Мапирование (иногда маппинг, маппирование, мэппинг, но не путать с маппингом игровых уровней) — определение соответствия данных между потенциально различными семантиками одного объекта или разных объектов. Термин понимается очень широко от отображения одной последовательности элементов на другую последовательность до банальной конвертации файлов. Мапер / мапирование норм слово для этого случая.
Плохо ли хранить JSON в SQL и если да, почему? Я тут пришел джуниором в реальный проект с хайлоадом, и тут дохера чего в базе лежит джсоном. Например, если брать прикрепление файлов к посту. По методичке тебе нужна таблица files, где каждая строка хранит id поста. У нас же в таком случае просто в таблице posts будет поле files, а в нем json с массивом файлов. Это норм?
>>1143280 Тоесть они хранят в базе, формат передачи данных для JS? >У нас же в таком случае просто в таблице posts будет поле files, а в нем json с массивом файлов. Это даже не говнокод, это уже клиника.
>>1143295 Я знаю что такое JSON. Только фишка в том, что он предназначен для формирования из БД. ПРи хранении его в самой бд ты теряешь всю суть JSON, надо получить немного другие данные - хрен, надо изменить выборку - хрен, надо провести другой запрос отличный от задачи - хрен. Надо улучшить бд - хрен, надо решить новую задачу и добавить полей к базе - заново перелопачивать каждое поле.
>>1143296 А потом все стоят и кумекают почему это хайлоап забивает 99% процессора, когда там всего-то неиндексированные имена файлов. Поэтому. Я вот удивляюсь кто в команду берёт людей на архитектуру приложений без знаний даже начальных по БД. И причём смысл то непонятен. Ну вот убрал он ID, а взамен что получил? Ничего же. Где профит то?
>>1143247 >условий, операторы и прочее в твиг не завезли, да? все завезли
>видишь ли хтымыло вместе с пшп, или видишь свой ебучий твиг? если у тебя шаблоны в твиге, ты можешь отдать их на редактирование верстальщику, дизайнеру менеджеру или уборщику, не боясь что он 1. обосрется от сложности пхп (а для них он сложный), 2. положит тебе сайт, изменив твои любимые глобальные переменные, например.
и опять же я не предлагаю вводить новые ("новые" лол) технологии только ради того чтобы они были.
про гит же такого вопроса нет, если даже один человек работает над проектом. а тем более если их два. плюсов у гита миллиард, минусов нет. в гите видна история изменений построчно, можно откатиться до рабочего коммита, легко искать баги, делать форки фич, можно автоматизировать деплой и т.д. но я вижу у тебя какой-то особый взгляд на вещи, фундаментально-консервативный, достаточно странный для программиста, но ладно. видимо какие-то причины есть.
>Научите тут лучше людей классы писать одно другому не мешает. изучение технологий - это такая же часть обучения, как изучение ООП >работая над одним говносайтом тут сидят не только те, для которых работа программистом - это работа с говносайтами >в тред начинающих и не только начинающие
>>1143280 >Плохо ли хранить JSON в SQL и если да, почему? Если нет выборки по содержимому JSON, то хорошо, если есть такая выборка - то плохо. Потому что индексация.
>>1143439 А если нет выборки, зачем вобще JSON в БД хранить? Можно запилить папку где всё это складировать и получить эдакую документоориентированную СУБД простейшую.
>>1143280 это сложный вопрос. возможно в вашем случае это экономит ресурсы. если, например, вы точно знаете, что никогда не нужно будет переформатировать этот жсон, добавлять туда что-то и т.д. тут лучше спросить у начальника, наверняка он знает причины.
субд то какая?
>У нас же в таком случае просто в таблице posts будет поле files, а в нем json с массивом файлов. Это норм? возможно, это денормализация (второй вариант - просто всем похуй, что вряд ли в хайлоаде). ее применяют, если запрос в рамках соответствия 3нф выполняется слишком долго (большие объемы данных и/или много джоинов).
>>1143441 это тебя на такую мысль сподвиг анон любитель глобальных переменных?
зачем его хранить в бд - а зачем данные типа "текст" хранить в бд? странный вопрос. если они у тебя в базе, ты можешь: 1. подрубить к ним сфинкс в случае необходимости 2. перекатиться на другую субд 3. раскатать данные по разным шардам 4. обращаться к ним в рамках одного запроса к базе, без костылей. если ты используешь ОРМ, то вообще без вариантов 5. ограничивать права (это можно сделать и ограничением прав на папку, но там есть лазейки) 6. делать бэкапы теми же средствами, которыми ты бэкапишь бд
это первое что в голову пришло. а какие плюсы у твоего решения?
>>1143559 Ну опять же всё перечисленное можно сделать и без БД. >6. делать бэкапы теми же средствами, которыми ты бэкапишь бд Делать бэкапы вообще любыми средствами. Ну хз я вообще не вижу преимужеств хранений JSON в БД. Какое-то извращение по моему.
Блин, я вообще сложно себе представляю именно запрос по которому нужно получить JSON именно из БД. Я привык к логике когда запос обрабатывается в бэке и потом бэк формирует JSON. А тут походу они получают миллиард JSON, или мудрят очень навороченные запросы чтобы получить что-то определённое. Опять же всё это даёт довольно большую нагрузку на сервер, на СУБД, на саму обработку запроса. Но при этом на формирование JSON сервер не тратит ресурсов. Или они просто отдают с десяток мегабайт JSON клиенту, а тот сам всё обрабатывает на своей стороне. Вот хоть убей не вижу профитов такой схемы. А в >>1143559 ну хорошо, вот только опять же просто в полях хранить данные хранить проще же, и обслуживать проще, и редактировать. Я уже представляю как неверный запрос редактирования случайно редактирует пару сотен лишних ячеек. Короче какая-то странная архитектура если это не документо ориентированная БД.
Вообще, такое иногда бывает нужно. Например, в файлообменнике мы собираем информацию о файле, которая бывает разная в зависимости от типа файла (длительность видео, битрейт, кодек, параметры кодека и тд). Ее удобно хранить как JSON, альтернатива - использовать EAV. Поля под нее делать неудобно, так как свойств может быть много, они сами по себе могут содержать массивы и тд.
Я думаю, дело тут не в хайлоаде, а просто в лени. Из недостатков - поиск по имени файла сделать почти невозможно (в postgresql впрочем можно сделать индекс по отдельному полю JSON документа). Какие-то запросы (вроде найти посты с большим числом файлов) делать неудобно.
>>1143592 А как потом собирать эту информацию? Ну вот например мне нужны все файлы MKV весом больше 5 метров и меньше 250. Я вижу тут только запрос через LIKE. И тут же я понимаю что это ведь довольно сильно даст нагрузки по СУБД. Или вот. Надо все JPG разрешением больше 4к, пережать. Как в таком случае редактировать уже занесённые данные?
Вообще, в Postgres и в новой MySQL есть функции для разбора JSON, а postgres даже позволяет делать индексы по произвольным выражениям, в том числе по полю в JSON.
>>1143569 >Ну опять же всё перечисленное можно сделать и без БД только с костылями
>я вообще не вижу преимужеств хранений JSON в БД если ты имеешь в виду "в сравнении с хранением их в файлах", то я тебе назвал шесть. а если про саму идею хранения данных сразу в json, то я согласен.
>>1143581 >просто в полях хранить данные хранить проще же
я и не защищаю такую хуйню, просто пытаюсь восстановить логику событий
- отсутствие транзакций и блокировок, есть например риск что 2 процесса будут писать в один и тот же файл , или кто-то будет читать не до конца записанный файл - отсутствие внешних ключей и проверок целостности - база может быть на отдельном сервере, в случае с файлами тебе придется как-то это самому решать - в базе есть индексы для ускорения поиска - база позволяет получить какие-то данные через SQL. В случае с самодельной БД ты это не можешь сделать.
То есть я вообще плюсов не вижу. В чем они? Если тебе хочется хранить данные в файле, есть встраиваемая СУБД sqlite, которая именно это делает.
Пока просто ощущение, что анон думает, что написать свою БД будет быстрее, чем разобраться в уже написанной.
Самый простой вариант - сделать bash скрипт и в нем написать команду обновления файлов из удаленного репозитория. Заходишь по ssh на сервер и выполняешь этот скрипт.
>>1143609 > >Выше же было про деплой >>1143223 я читал, поэтому и стало интересно, что именно ты используешь. я конечно имею в виду уже существующие решения. искал, нашел вот что: https://deployer.org/docs/getting-started как раз вариант простого скрипта, о котором ты говоришь. он занимается вопросами типа установки пакетов композера, нпм и т.д., блокировки проекта на момент обновления, но не решает (насколько я понял) с АВТОМАТИЧЕСКИМ обновлением, т.е. ты запушил - он спуллил. https://www.phing.info/ тут честно говоря черт ногу сломит, но я так понимаю он умеет все
знаю еще есть варианты с teamcity и еще travis, но тимсити жрет ресурсы сервера, т.к. он там сидит в бэкграунде, а если ты снимаешь впс за 5 баксов, то это проблема, а травис платный для не опенсорс проектов.
>>Заходишь по ssh на сервер и выполняешь этот скрипт вот этот процесс и хотелось бы автоматизировать (не заходить и не запускать каждый раз)
Ты можешь сделать репозиторий на том же сервере и настроить хуки, чтобы при пуше в него запускался деплой. Также можно установить какой-нибудь Jenkins и попробовать там настроить запуск деплоя при коммите.
Не совсем понимаю как в задаче про калькулятор, сделать так, чтобы выполнилось действие, которое находиться в переменной $op. Только ли через if/else это можно сделать?
>>1143228 >Есть 3 паттерна наследования: Single Table Inheritance, Concrete Table Inheritance, Class table inheritance - погугли их для начала и потом задай вопрос, если непонятно. В общем почитал я про них, как я понял единого верного варианта нет. Я могу просто прикинуть что расширяющих файл сущностей у меня будет точно не много (изображение, аудио, видео), и использовать одну общую таблицу. Хотя более логичным мне кажется использовать паттерн одна сущность - одна таблица без явных связей с другими таблицами(Concrete Table Inheritance), ведь объект полностью имеет поля своего предка, и раз в бд нельзя провернуть наследование, то может оно и не нужно? Хотя говорю я это без опыта работы с любыми орм и паттернами бд, на практике хз как выйдет.
И у меня еще вопрос по поводу хранения файлов. Я правильно понимаю что в бд я записываю путь к файлу, который лежит на диске, а потом при отправке пишу нужные заголовки и вставляю туда же путь к файлуу слима вроде обёртка есть для переменной _FILES, но я в подробности не вникал, и он оп и отправился?
Сап. Друзья, вопрос... Есть верстка сайта школы стилистов. На одной из страниц выводятся все курсы с кнопкой "Узнать подробнее", при нажатии на которую, открывается страница с подробной информацией об этом курсе.
Нужно сделать такую админ панель, где будет страница с полями "Название курса", "Дата", "Изображение курса" и т.п. Человек заполняет все нужные поля и нажимает на кнопку добавить. И на страничке курсов появляется этот курс. Можно как-то по-другому это реализовать, но главное чтобы сократить работу с кодом к минимуму. Первый опыт с сайтом, не знаю куда двигаться.
Конечно, я могу наклепать таблицы, написать PHP код, сверстать быстренько админ панель. Но я боюсь это делать, потому что опыта то нет.. Будут проблемы с безопасностью, как-то криво будет работать..
Сейчас взялся за ModX, как я понимаю, с помощью него я смогу все это реализовать. Но возможно есть более лучшее решение этой ситуации для новичка?
Спасибо, очень жду ответа, потому что время поджимает...
>>1144089 лол, подставляешь в качестве ключа, название роута, а в качестве значения, либо функцию которая открывает тебе твой контроллер, либо другой массив с ключами других роутов.
Сап обучающий. Хочу сделать сайт среднего функционала в качестве хобби. Сайт этот никуда не пойдет, буду делать фор фан. Хочу использовать php движок, раньше были DLE и Joomla! в связи с этим интересуюсь появилось ли чегонибудь интересного в этой сфере, конкретно движки. Гуглить пробовал, но интересует Ваше мнение.
>>1144098 Это в каких-таких Мухосрансках нет симфони?
Симфони ща в любой дырке затычка: Ларавель - юзает библиотеки Симфони Друпал 8 - юзает компоненты Симфони
Тем более Симфони, это автоматически юзание композера.. Со знанием Композера заехать в тот же YII2 вообще на изи.
Даже в моей ебучей провинции 3-4 ваканчии в пару месяцев появляется. Какой нахой Битрикс. Битрикс программист вообще не программист а собиратель говна и палок, чтобы клеить костыли. Нм одна блять здравая контора не возьмет Битрикс как основу для проекта выше обычного. Интеграция с Адинэс из коробки (единственный плюс Битрикса) не является сколь либо сложно задачей для имея на руках библиотеку уровня Симфони/ЮаЙаЙ
В этом задании https://phpclub.tech/pr/chain/1108694/ Тут просто надо методы прописать и параметры объектов? Или надо еще указать как взаимодействуют объекты между собой? Надо ли подключить базу и как то настроить все?
>>1144126 Какая разница кто что юзает, причем тут композиры?
Вопрос в другом, каких контор больше, битрикс клепальщиков или симфони ковыряльщиков и куда вкатиться проще. На симфони почти в любой конторе нужны только синьеры, максимум на что согласятся, мидлы с 1-3 годами опыта. При этом еще покажи им исходники проектов и все такое.
В битрикс вкатываешься стажером и все. Хотя постепенно битрикс тоже переходит такую модель, как брать только опытных с 1-3 года опыта. Становится труднее вкатится, но все еще можно.
>Битрикс программист вообще не программист а собиратель говна и палок, чтобы клеить костыли. Зависит от тебя, если ты собираешь говно и палки, то это не проблема битрикса, там много чего приходится дописывать, никто же не заставляет говнокодить, но ты же не можешь не говнокодить без симфониларавель, да?
>Нм одна блять здравая контора не возьмет Битрикс как основу для проекта выше обычного. Кекаю с наркомана. Берут как миленькие. Тебя что в интернет не пускают?
Ты в какой провинции живешь? Квебек? В провинция ойти вообще нету. Одни 1с и битриксоиды. А если и появляется то надо чтоб в мухосрани ты откуда то получил опыт в 3 - 5 лет чтобы взяли.
>>1144144 >Какая разница кто что юзает, причем тут композиры? >Вопрос в другом, каких контор больше, битрикс клепальщиков или симфони ковыряльщиков и куда вкатиться проще. Вопрос в том что вкатиться ты вкатишься, а вот выкатиться из этого говна будет проблематично. Лучше сразу вкатываться где прямые руки писали, чем потом переучиваться в пряморукий кодинг.
>В битрикс вкатываешься стажером и все. Хотя постепенно битрикс тоже переходит такую модель, как брать только опытных с 1-3 года опыта. Становится труднее вкатится, но все еще можно. В крупных компаниях есть Trainee, есть фриланцы и т.д. было бы желание
>Зависит от тебя, если ты собираешь говно и палки, то это не проблема битрикса, там много чего приходится дописывать, никто же не заставляет говнокодить, но ты же не можешь не говнокодить без симфониларавель, да? Предпочитаю не забивать гвозди утюгом. А вы?
>Ты в какой провинции живешь? Квебек? В провинция ойти вообще нету. Одни 1с и битриксоиды. А если и появляется то надо чтоб в мухосрани ты откуда то получил опыт в 3 - 5 лет чтобы взяли.
Хохлостанская южная мухосрань. У нас тут около 15 компаний в городе. Есть такие же битрикс-клепальщики, есть малые стартапы за доширак и опыт, если филиалы крупных компаний типа ДатаАрта. Короче на любой вкус.
Плюс опять же никто не отменял удаленку.
На серьезных щщах реально втирать что Битрикс тру - ну это пиздец. Есть задачи, для которых он хорош (тот же 1С), и дядя доволен что сайт быстро заработал и за десять тыщь - но в целом это тупиковая ветка если есть желание уйти куда в хай лоад или биг дату со временем.
>>1144154 >Хохлостанская Ну я так и понял. Ты вообще не вкурсе, что тут происходит. О чем с тобой говорить.
>мухосрань >15 компаний Ну ну, мухосрань, конечно.
Трени и прочие стажировки в дсах, в ваших хохломухосранях оно понятно что всяким датаартам негде брать стажеров.
Удаленка и срилансы, как я уже выше писал нужен разговорный язык нормальный, помимо языка тебе нужно будет показать опыт и портфолио, чего ты в мухосрани не наработаешь.
>Предпочитаю не забивать гвозди утюгом. А вы? К чему это сказано? Тебе наверное непонятен смысл этой фразы. Битрикс очень даже по назначению применяют, как ты ниже сам заметил. А то что тебе придется писать, какой либо сервис для интеграции с каким либо апи или бизнес логику клиента, так оно тебе и на симфони придется писать.
>На серьезных щщах реально втирать что Битрикс тру - ну это пиздец. >Есть задачи, для которых он хорош (тот же 1С), и дядя доволен что сайт быстро заработал и за десять тыщь Ты либо трусы одень, либо крестик сними.
Смысл бесполезного хейта битрикса? Тебе говорят как есть, причем в другой стране, ты говоришь да как такто, у нас же все так. Никто не спорит, что есть у него свои недостатки. Но нету выбора, по описаным выше причинам.
>>1144090 работу на битриксе не найти. в макдаке дофига вакансий.
а если с английским плохо, нужно подучить. ты же пхп выучил как-то. я не представляю как вообще можно гуглить без знания английского.
когда я последний раз смотрел работу на хх, там было 300 вакансий со словом "симфони" и из них 50 по удаленке. это меньше, чем на битриксе, но и специалистов меньше.
>>1144144 >Зависит от тебя, если ты собираешь говно и палки, то это не проблема битрикса какой "зависит от тебя". битрикс это позволяет и поощрает. если ты работаешь на симфони, ты по крайней мере пишешь тесты, т.к. это практикуется в конторе. а на битриксе ты глушишь все нотисы и ворнинги, которые он генерит.
плюс ты наверное видел много битрикс-кода и знаешь, что там нормальная практика писать sql-запросы прямо в шаблоне (или как он у вас называется).
>В провинция ойти вообще нету. Одни 1с и битриксоиды. я в дс работаю на симфони (на удаленке), у нас удаленные же сотрудники из разных городов, в т.ч. из такой жопы, до которой лететь 6 часов.
>>1144163 >Но нету выбора, по описаным выше причинам. по причинам "незнания разговорного английского" лол?
я тебе очень рекомендую подучить язык и перекатиться в будущем. поверь, ты прям задышишь по-другому. работать на битриксе это как работать инженером в советском нии. ты себя ненавидишь, все друг друга ненавидят, бедность и депрессия.
>>1144154 >это тупиковая ветка если есть желание уйти куда в хай лоад или биг дату со временем я работал в конторе, которая начинала с битрикса и потом продукт стал хайлоадом. это боль, конечно.
>>1144163 >Смысл бесполезного хейта битрикса? смысл защищать битрикс? если перестанешь его защищать и станешь ненавидеть как все, то со временем перекатишься на нормальный фреймворк. необязательно симфони, хоть на yii. на yii дохера работы в провинциях же.
>>1144022 вообще, это достаточно объемная задача, если ты раньше такого не делал. человек, который этим уже занимался и владеет инструментами, сделает такую задачу за рабочий день спокойно. а если ты не делал, это может занять от дня до нескольких недель.
у тебя три варианта: 1. написать все с нуля на голом пхп. это не варик для продакшна, так делают только в учебных целях 2. взять фреймворк, тот же Симфони и там уже есть необходимые решения - doctrine, security, easyadminbundle. но нужна какая-то база, чтобы те же сущности ОРМ правильно выстроить. 3. взять CMS: drupal, wodrpress или любой другой. думаю, для тебя это самый быстрый путь, но там тоже придется покопаться.
>>1144074 Мне недавно прилетел заказ на 500 рублей (мой первый заказ лол), допилить форму продажи, допилить загрузку фоток, и сделать им превьюшки. В общем до этого ковырялся я в пхп пару месяцев и буквально на базовом уровне знал html и css, ну думаю ща тут все раскидаю на изи. Открываю я этот битрикс, нихуя не понимаю, какая-то статистика скорости сайта, предлагают прям там пройти какие-то тесты блять, десять тыщь папок, шаблоны страниц в одной папке, заголовки и футеры в другой, стили в третей, оче сложная навигация, потом оказалось что у чувака сайт сверстан на таблицах, я об этом только читал на самом деле, а сейчас сам столкнулся, ну я не растерялся и ебанул таблицу в таблицу(так нужно было). Потом я еще пол дня ебался с джаваскриптом, так как до этого его не трогал вообще, но в итоге всё сделал, все довольны, лол. Пхп так и не трогал. Короче ковыряться в этом говне не вызвало у меня никаких положительных эмоций. Буду дальше пинать фреймворки и созидать.
В случае Гостиницы - написать классы целиком. И можно кусочек кода, который их использует (создает гостиницу, заселяет туда несколько человек, выводит статистику).
В случае Агенства - достаточно просто написать названия классов, полей и методов в них. Весь код писать не надо, проверяются только навыки проектирования.
>>1144255 >Дело не в защите, плохому програмисту, всегда другие программисты мешают. Это актуально и для фреймворков. не понял твою мысль. если ты имеешь в виду, что человек, отказывающийся работать с говном типа битрикса и на фреймворках не сможет что-то сделать, то это не так. и на моем примере, и на примере коллег.
бытует мнение что мол программист должен к любым продуктам, с которыми работает, относиться одинаково и не иметь предпочтений типа это всего лишь инструменты. мол пишу на симфони, но предложат на битриксе поработать - соглашусь. для бизнеса это может и корректно, но для специалиста ошибочно. можно по рынку труда посмотреть, что специализация рулит.
это как таксист будет говорить "мне похуй на чем бомбить, на камри или на классике - это всего лишь инструменты".
>>1144271 >не понял твою мысль Имел ввиду, что хороший специалист, даже сбитриксом напишет нормальный код, не ухудшающий приложение в целом. Так и плохой спец взяв фреймворк, все равно будет лепить код как может, сделав практически непригодным для дальнейшей поддержки без глобального рефакторинга.
Про специализацию, это само собой. Я сейчас про вкатывальщиков и начинающих, у которых в мухосрани просто нет выбора. Да и в дсах, можно прождать вакансию для вкатывающегося от года и больше.
>>1144279 Дело не только в коде, битрикс может вести себя непредсказуемо и это бесит. Второе: из коробки в битриcке есть много всего, но используется из этого далеко не все. Вот нахуя мне столько полей в инфоблоке? Это как пример. Я не работал с современным фреймворком, но мне кажется, что используя фреймворк ты используешь только те компоненты, которые тебе действительно нужны.
>>1144286 Как может код вести себя непредсказуемо? Или в фреймворках, какой то пхп, что там все предсказуемо? В фреймворках тоже всего много, например различия ларавель или слим. Мне тоже много всего ларавельного не надо. Это не основание говорить, что это плохой фреймворк. Мне кажется ты можешь использовать те поля, которые действительно тебе нужны?
>>1144291 Помню, как не мог понять, почему 404 при переходе на страницу новости. Дело было в том, что нужно было в настройке компонента убрать галочку и поставить ее снова. Два клика мышью у одного и того же чекбокса. Ебля с кэшированием. Разворот локальной версии - access denied, ок, поменял в базе имя хоста на локальный.
>>1144279 с битриксом наверное можно написать хороший код, но это сложно по трем причинам: 1. битрикс не способствует быстрому профессиональному росту 2. битрикс поощрает плохие практики 3. (самое главное) в конторах, где используют битрикс, обычно на хороший код кладут хер. думаю, ты с этим сам согласишься
>Так и плохой спец взяв фреймворк, все равно будет лепить код как может конечно. но тут скорее важно не то, что он плохой специалист, а то что есть много программистов, которым вообще срать на качество кода. типа работает и ладно. а сама экосистема фреймворка и контор, которые его используют, обычно такого не терпит.
>у которых в мухосрани просто нет выбора вменяемые курсы, фриланс, релокацию ты за вариант не считаешь. тогда да
>Да и в дсах, можно прождать вакансию для вкатывающегося от года и больше ну нет конечно. в дс1 можно сегодня устроиться, а завтра выйти на 30к. я даже могу подсказать места, лол
>>1144286 >используя фреймворк ты используешь только те компоненты, которые тебе действительно нужны если он компонентный, то да
>>1144291 >Мне тоже много всего ларавельного не надо в симфони 4 ты ставишь symfony/skeleton и там по дефолту только самый минимум компонентов. нет ни профайлера, ни твига, ничего. все ставишь по желанию
>>1144310 Ну не понимание, как работает система, с которой ты работаешь, конечно же затрудняет работу. Да и отсутствие настроенного деплоя, так же мешает. Тут уж надо самом с этим что то делать. Битрикс хоть и предлагает свою систему развертывания, никто ей не пользуется, так как быстрее самому сделать.
>>1144324 >в симфони 4 А заказчик хочит ларавель, поэтому что эта модна. То есть теперь мне надо начать ненавидеть ларавель, чтобы перейти на "нормальный фреймворк"?
>>1144320 Все сказанное про битрикс верно, если ты попал в плохую контору, где нету хороших спецов. Актуально так же для любого другого фреймворка языка. Я как то давно легаси на кодигнайтере поддерживал. Контроллер или модель на 5-7к строк, вполне имело место быть. Отличие от битрикса было лишь в том, что битрикс со своими компонентами на 5к строк, а тут контроллеры на столько же.
Да обычно вебстудии с битриксом имеют тенденцию хороший код не писать. Но есть и конторы, которые поддерживают один два проекта на битриксе, вполне способны тебе дать основы, возможно хуже чем если бы ты начал в хорошей конторе с фреймворком, но в целом для начала вполне неплохо.
Я бы сказал, что не стоит выбирать галеры, отдавай предпочтения конторе, которая строит бизнес вокруг своего сайта, для нее критически важно иметь высокий уровень.
>вменяемые курсы Например? В мухосрани потом приди и скажи, что курсы прошел. Над тобой посмеются дружно всем офисом.
>фриланс С нуля во фриланс, это самоубийство, даже хуже чем в битрикс вкатываться. Если тебе повезло и ты опытный, можно на удаленку попробовать, но это не для всех.
>релокацию Кому вкатывальщик без опыта нужен? Да и с опытом, переехать в другой город, помогают не так уж и много компаний. Если ты средний спец, вряд ли стоит ожидать. Был бы опытным и топовым спецом, давно бы уже пробовал за границу уехать.
Есть тут люди которые работали с woocommerce через rest api? Могут ли клиенты у которых нет доступа в админку для генерации ключей (consumer_key, consumer_secret) логиниться/смотреть списки товаров/покупать? Ключи ведь привязаны к конкретным юзерам но в документации я не нашел ничего о том, как сгенерировать ключ юзера через API. Такое впечатление, что их API это чисто для юзеров с доступом в админку
>>1144340 >если ты попал в плохую контору, где нету хороших спецов битрикс - это низший сегмент рынка по баблу. поэтому в общем случае там экономят на качестве и хороших спецов меньше. если есть битрикс-конторы с хорошим кодом, то заебись. лично я не встречал (а я работал в двух, лол)
>отдавай предпочтения конторе, которая строит бизнес вокруг своего сайта это 100%
>Например? В мухосрани потом приди и скажи, что курсы прошел profit, например. при желании можно их и в торрентах найти. необязательно говорить про курсы, можно показать знания, свои проекты, коммиты в какие-то библиотеки.
>С нуля во фриланс, это самоубийство ну мб
>Кому вкатывальщик без опыта нужен? опять же после некоторых курсов могут предложить стажировку за три рубля, а после стажировки релокацию. ну то есть оффер, а ты сам эту релокацию проводишь.
Бля пачаны первый раз в вашем треде, сильно не бейте.
Короче надо поправить форму обратной связи на лендосе и захотелось это сделать на локальном серве. Какая сейчас прога есть для этого или онлайн песочница чтобы по быстрому скормить этому всем html-css-js-php файлы и оно фурычило? Может какой-то аналог codepen jsfidle?
Алсо на компе стоит Денвер но я его год где-то не трогал, лол. Может что-то попроще есть для такой просто задачи?
Можно на любой СУБД. Я бы советовал брать ту, с которой раньше не работал - чтобы расширить кругозор. Если ни с одной не работал, то можно взять postgres.
>>1144470 Человеку сделал "фронтендер" на WPBakery Page Builder сайт для крипто-валют без оптимизации, на половину кривой. а я его второй день правлю и ахуеваю.
В конце спрошу сколько он "фронтендеру" отдал чтобы еще раз ахуеть.
>>1143597 >А как потом собирать эту информацию? Если требуется только показывать её юзеру, то и не надо ничего собирать. А жсон в этом случае используется для удобства обработки жаваскриптом, например. Если когда-нибудь потребуется выборка, тогда и изменят схему БД и распихают жсон по табличкам, это не проблема.
>>1144575 Да то я случайно тыкнул. Я пытаюсь отправить пост запрос на эту же страницу. В хроме просто ничего не происходит, в фаерфоксе после отправки (значит, пост запрос все таки отправляет?) вот такая вот херня
- открываю такую-то страницу с таким-то URL - ввожу в форму то-то и то-то - жму такую-то кнопку - вижу ошибку 404 и такой-то URL
А ты можешь сравнить URL в адресной строке, когда ты просто открываешь форму в браузере и она видна, и URL при отправке формы?
Я помню, что несколько месяцев назад анон писал про такую же проблему. и мне кажется, что дело может быть в шторме. У тебя наверно установлен PHP, ты не мог бы попробовать запустить встроенный в него сервер и открыть в браузере страницу через него? Это описано тут и потребует немного возни с командной строкой: https://github.com/codedokode/pasta/blob/master/soft/web-server.md#Встроенный-в-php-сервер
Пока моя версия - у встроенного в Шторм веб-сервера какие-то проблемы с обработкой POST запросов.
Вопрос по папке var/cache в Symfony4. По правам к ней, точнее.
Я корректно понимаю принцип работы на проде? Мы запускаем cache:clear (создается папка prod от имени нашего пользователя, права 755) и далее не позволяем системе создавать свои скомпилированные файлы в эту папку (она этого все равно сделать не сможет, т.к. пользователь у нее www-data), а создаем их сами, прогревая кеш? Тогда они создаются от имени нашего пользователя и все заебись.
То есть вопрос в том, что правильно ли я понимаю, что без прогрева не надо вообще на проде ничего менять?
>>1144590 >Ну вот так и надо было писать: Сорри, туплю :-(
>ты можешь сравнить URL в адресной строке, когда ты просто открываешь форму в браузере и она видна, и URL при отправке формы? Пикрелейтед оно? >попробуй глянуть, что там? 2018-02-23 00:12:31,898 [30225280] INFO - ide.actions.ShowFilePathAction - Exit code 1
>Это описано тут и потребует немного возни с командной строкой Сейчас попробую
>If you decide to store log files on disk, you will need to make sure your logs directory (e.g. var/log/) is writable by your web server user and terminal user. One way this can be done is by using chmod -R 777 var/log/. Just be aware that your logs are readable by any user on your production system.
То есть один способ такой (топорный), а какие есть еще? Я пока придумал только дать на папку права допустим 770, в кач-ве владельца поставить нашего terminal user и включить пользователя www-data в группу terminal user. Или создать им какую-то общую группу и поставить ее в кач-ве группы для этой папки.
>>1144590 >ока моя версия - у встроенного в Шторм веб-сервера какие-то проблемы с обработкой POST запросов Да, ты прав. Вышел из шторма, запустил через хампп - и все заработало. Столько времени и нервов убил, печаль :-/
Не уверен. По задумке да, на проде кеш генерируется из cli при деплое. Но я гарантировать, что симфони не захочет что-то записать в кеш, не могу. Ну например, там есть кеш для результата разбора DQL запросов (в доктрине) - по умолчанию вроде используется apcu, но кто знает, какие у тебя могут быть настройки. И какие там еще могут быть кеши.
Так что могу лишь посоветовать проверить экспериментально и понаблюдать.
Если URL одинаковый (а это вроде так), то проблема в встроенном в шторм сервере, он не работает с POST запрросами. Нужно освоить встроенный в PHP сервер (проще всего), либо Апач, либо nginx + php-fpm.
Простой вариант - запускать веб-сервер от того же юзера, что и используется в cli. Но тут минус: что, если разработчиков больше одного? Да и не хочется серверу давать доступ к своим файлам.
Можно тогда попробовать взять всех разработчиков + создать пользователя-веб-сервера и объединить их в группу. Сделать ее основной для пользователя-веб-сервера (чтобы создаваемые им файлы получали ее). Сделать chown на эту группу для всех файлов. Дать полный доступ к файлам участникам группы.
Подвох: если у кого-то из разработчиков эта группа не основная, то у создаваемых им файлов будет другая группа и веб-сервер и другие разработчики не получат к ней доступ.
Другой подвох: если есть несколько сайтов, у каждого своя группа то в любом случае у разработчика какая-то группа будет не основной.
Подвох: по умолчанию umask = 022 и надо его поменять на 002 иначе создаваемые файлы и папки будут иметь права rx для группы, а не rwx.
В этом случае остается только использовать ACL вместо ограниченной системы unix прав из 3 циферок. Там можно будет всех поместить в группу и дать доступ пользователям этой группы, даже если она у них не основная. ACL вроде умеют наследоваться с папки на вложенные папки и файлы по умолчанию. Но это надо уточнить.
То есть, если подытожить:
- либо использовать всем одного пользователя - либо сделать группу - либо сделать группу и использовать ACL для гибкой настройки.
> Я пока придумал только дать на папку права допустим 770, в кач-ве владельца поставить нашего terminal user и включить пользователя www-data в группу terminal user.
Надо еще выставить корректный umask (почитай что это) иначе сервер будет создавать файлы и папки с правами rx без w для группы. То же касается и твоего пользователя.
Погугли по теме phpstorm builtin server POST - много информации про плохую поддержку встроенным в PhpStorm сервером метода POST. Скорее всего дело в этом.
Авторизация и регистрация редиректом по страницам еще допускается, или уже не модна и надо мучаться переделывая на ajax+ jquery(которые я не знаю по сути)? >>1144610 Дело было в шторме, через апач все корректно работает.
>>1144648 Предварительно всё это завернув в массив. Который завернул в JSON. И закешировал запрос. А потом сохранил его в БД. Не проиндексировав. Или вообще создал новую БД под каждый запрос. Каеф.
Уже скоро 100 тред. Я тут с 1 треда и до сих пор не смог сделать задачу про айфон в кредит. ОП мне стоит вообще продолжать пытаться в программирование?
>>1144730 Он может не подходить для некоторых сфер, но устарела в языке C++ только часть. >нам его в универе давали Вам его в универе давали в виде Си с классами версии 98 года.
>>1144730 >нам его в универе давали на 1 курсе 5 лет назад. Это показатель какой-то? Или что? Ну вон пиши на расте тогда. Ему около года всего. Правда область применения мизерная и вакансий 15 на весь мир.
>>1144759 Еще лучше если мы говорим о просто Си. Но 98 на мой взгляд - необходимое зло. Везде где юзаюся фичи 11 + стандартов разумнее использовать другой язык
С переносом данных из JSON в таблицы скорее всего будут сложности, так как никто к тому моменту не будет помнить схему JSON данных (какие в них есть поля и для чего) и придется все это мучительно выяснять анализом кода.
В каком смысле фундаментального? Если тебе интересны низкоуровневые детали, то надо почитать как устроен процессор и учить ассемблер (только не учи древний 16-битный досовский - учи хотя бы 32-, а лучше 64-битный). Скорее всего, на ассемблере тебе писать ничего не придется, но ты будешь понимать, как программа выполняется на процессоре.
А затем можно переходить к Си. А потом к более высокоуровневым языкам.
Но это не проще PHP. Это будет сложнее. И потребует время. И зарабатывать этим ты вряд ли сможешь.
PHP по моему один из самых простых языков в освоении. Ну еще Питон есть, он может чуть проще. Можешь его попробовать учить.
>>1145073 Разобрался вроде. Но может кто пояснить, что происходит если я ввожу не латиницу? Почему оно второй раз не просит ввода второй раз(возраст)? А после имени сразу вываливает последний echo с пустыми значениями в переменных $name и $age
Что происходит при вводе "нелатинницы" зависит от используемых ОС, настроек ОС и кодировки скрипта.
В линуксе и маке по умолчанию консоль передает программе и отображает на экране данные в кодировке utf-8. Если скрипт написан в utf-8, то он будет работать с любыми символами любых алфавитов. Если не в utf-8 - то надписи из скрипта будут выводиться криво. Подробнее
Если ты используешь винду, то придется страдать. Виндовая консоль в русской версии использует по умолчанию 8-битную кодировку cp1251, и значит ты должен либо писать скрипт в cp1251 (плохо, плюс не все функции ее будут поддерживать), либо кириллица не будет отображаться.
Винда + cygwin кстати иногда умеет отображать utf-8 в консоли.
Еще один вариант, если ты под виндой, то можно писать программу в utf-8, но конвертировать все вводимые и выводимые данные в/из cp1251.
Причем обрати внимание, что cp1251 используется в консоли только в русской версии винды. Если твою программу запустить на другой версии винды, то кирилица не будет отображаться.
А, я ошибся. В винде в консоли по умолчанию может еще быть cp866. Не знаю, от чего это зависит, есть консольная команда chcp для ее переключения. На utf-8 переключить нельзя.
Проверить кодировку можно, набрав например такую команду
php -r "echo chr(253); echo '\n';"
Она выводит символ с кодом 253. Затем взять в википедии таблицы кодировок cp866 и cp1251 и посмотреть в них символ с таким же кодом 253 и сделать вывод о кодировке.
Почему такой вот венегрет? Кирилцу даже не попытался впихнуть, но почему каждая переменная содержит перенос строки? Из-за того что я ентером при вводе еще и перенос строки складываю туда? Как просто вбивать туда по простому инфу?
Вспоминается в паскале было read(); readln();
которые позволяли считывать пользовательский ввод, есть в пхп что-то аналогичное?
>>1145082 Сygwin и использую. Кстати, попробовал запустить на убунте - действительно с русским проблем нет. Но вопрос не в этом, я понимаю что с utf8 могут быть проблемы, вопрос в том, почему введя первый раз имя на русском оно не просит у меня ввести возраст, а сразу выводит последний echo? Т.е. пропускает заполнение переменной $age
Заметил, что изредка на базе данных MyISAM не срабатывают транзакции ладом. Делаю запросы: BEGIN INSERT в 1 таблицу получаю ->insert_id INSERT в 2 таблицу SET last_base_id=$insert_id COMMIT
Где-то раз в 100 тысяч таких срабатываний скриптов получается такое (при одновременной запущенных нескольких скриптов): У меня в 1 и 2 таблице AUTO_INCREMENT стоит и должно записываться: 1 таблица: id=999 id=1000 2 таблица: id=999, last_base_id=999 id=1000, last_base_id=1000
Но вместо этого изредка получается во второй таблице: id=999, last_base_id=1000 id=1000, last_base_id=999
Без транзакции в ->insert_id вообще какие-то левые данные.
>>1145271 перевел таблицы на InnoDB и охуел с тормозов из-за транзакций. Использую транзакции чтоб вместо по-очередной вставки данных вставился сразу блок - какие-то ключи и картинка в другой таблице. Потом выбираю это все объединяя таблицы. Тормозить стали почему-то и другие скрипты, где транзакциями и не пахнет и должны выполняться моментально. В общем, надо как-то настраивать, но лень разбираться. Эх, не быть мне программистом. Просто вернусь на старый тип таблиц и не буду использовать ->insert_id.
>>1145379 Лол, спасибо за идею с третьей таблицей связывающей. Это придаст моему проекту более понятный вид. Можно хоть тормознутые транзакции откинуть Тоже жду ответов. Главное чтоб быстро выбирало крупные данные и без лишних полей.
Сейчас делаю задачку на файлообменник и думаю над валидатором для файлов. Нужно ли проверять размер приходящего файла/файлов и их количество? Это же все задается в php.ini. Что вообще можно проверить?
>>1145426 Что бы входящий файл не был troyan_ot_vasyana.php например, и что бы злоумышленник потом пройдя по ссылке tvoy.sait/upload/images/troyan_ot_vasyana.php не получил полный доступ к твоему сайту.
Есть ли какие то бест практис так сказать при написании sdk и библиотек для работы со сторонними API? Попробовал искать но Гугл выдает результаты по ключевым словам api/sdk игнорируя остальное. Писал уже больше 10 разных либ для работы с апи но хотел бы почитать еще на эту тему
Сап. Как курлом отправить картинку постом? С директивой @ не отправляется картинка. Изучаю тут, пытаюсь тред создать, в ответ всегда получаю необходимость прикрепить файл.
Часть функции из задачи на банк. Сия функция должна принимать на вход три числа и переводить их в текст, но почему она глючит с цифрами типа, начинающимися на 0, типа 056 или 038. Указывает неправильные числа, например, вместо "пятьдесят шесть" пишет "сорок шесть" Я по калькулятору проверял, всё должно быть верно. Решил, что проблема в отсутствии сотен, решил сделать так https://ideone.com/6U4CQx где если нет сотен, то он сразу брал номер, не отбрасывая первую цифру, но такой номер он не видит в массиве и выдавал ошибки.
Однако в конечном варианте задачи ещё не до конца готовымhttps://ideone.com/hDcpnO такой ошибки нет.
>>1143230 Почему при отсутствии сотен он начинает глючить >>1145606 ? Там же сотни будут равны нулю, а значит и любые действия нулю? Или там пустота, NULL?
>>1145428 Я тут погуглил, наверное самое эффективное решение это выдавать ссылки на файл в публичной папке, а в этой папке отключить обработку скриптов. Я изначально хотел сделать папку не публичной, на практике это будет не слишком хорошо работать даже с каким-то йоба заголовком x-sendfile или еще хуже считыванием прямо пхпхой в озу.
У меня есть один вопрос к анонам. Каким образом в реальном мире производятся фоновые задачи? По наводке из статьи опа прочитал про gearman, мало что понял, есть еще какой-то крон. Вот как например ютуб конвертирует видео? Я загружаю видео на сайт, где-то внутри логика запускает эту фоновую задачу конвертации(представим что это консольная команда ffmpeg), она каким-то образом еще отдает ответ логике о прогрессе. Может создается какая-то временная запись в бд о файле и статус типа обрабатывается, завершил обратку этц. В общем сложна.
И еще есть один подводный камень с джепегом и внедренным внутрь пхп. Если я буду в превьюхе указывать сорс на оригинальную картинку, то будет ли выполняться пхп код? Я тестил на рандомном файлообменнике, там везде, даже в микро превьюшках 15x15 сохраняется пхп код, то есть чуваки не чистят метаданные, и у них ничего не ломается. Ргост кстати отказывается грузить такую картинку вообще, лол.
>>1135053 (OP) Привет, анон. Где-нибудь написано за куки? Нужны ли они? Я думал в куки передаются данные откуда перешел человек и всё такое, а в мануалах везде передают одну и ту же хуйню в виде простой строки
>>1144806 >Машина Тьюринга - это модель для математических доказательств и в изучении программирования не поможет. Описание машины Тьюринга - это самый элементарный язык. Тебе не поможет, зато мне помог.
>>1145789 >Почему он так реагирует на цифры с нулём в начале? Это у меня проблемы или компилятор глючит? https://ideone.com/QljIj0 Я везде, где только можно добавил условие if != 0, поэтому он просто должен подобные пропускать.
>>1145790 Учите алгоритмы, господа, теорию программирования. Тогда язык станет просто инструментом, где важно просто знать синтаксис и какие-нибудь специфические особенности.
>>1145869 Не, это я знаю. Я имею ввиду можно ли примеры как например с помощью куки запоминаются пароли, действия на сайте, подгрузка видосов, картинок, сохранение действий. Как это всё делается
Мне нужно создавать объекты разных классов в рантайме, я такой думаю, ну есть же какие-то йоба паттерны, натыкаюсь на фактори паттерны, читаю, большого смысла в своем случае не вижу. В одном источнике аргументация простой фабрики - если поменять название класса, то не придеться менять название во всех местах программы, только в самой фабрике. Ну охуеть.
Короче подумал что мой вариант это простая фабрика, которой передается тип/название класса, и она с помощью кейсов создает и возвращает что нужно. Потом у какого-то индуса почитал что так делать нельзя и это нарушает какой-то там йоба принцип, можно только расширять сущности, изменять их не стоит. Мол в будущем я захочу новых типов, полезу дополнять кейс и ВСЁ СЛОМАЕТСЯ. Альтернативой он предложил ФакториМетод, где каждый кейс это отдельный класс. Но мою проблему это не решает, теперь мне придется пилить кейсы сразу в каком-то контроллере, и вызывать нужные классы. Или я тупой и ничего не понял, или это всё говно из жопы. жопа горит
>>1146079 Ваще эти паторны хуита какая то узкоспецилазированная, тебе нужно сделать йобу, а они тебя сука ограничивают, шо нихуя не получается. Походу вообще хуй надо на них забить.
Кто-нибудь в тредике решал недавно кошек-мышек? Мне эта задача уже года два не дается наверное. Периодически сажусь за её решение и постоянно стопарюсь на том, что не могу принять какое-то решение на каком-то этапе. Наприрмер о том, где нужно хранить координаты животного. Либо в мире, либо в самом животном например. Начинаю себе голову какой-то фигней забивать о том, что вот если бы у нас был очень большой мир с очень большим количеством объектов, то например будут такие проблемы:
Допустим животные хранят в себе своё положение в мире. Стало быть нельзя просто взять и спросить у мира кто рядом с нами? (а было бы удобно просто спросить кто стоит в радиусе 4х клеток от x,y через простой вложенный цикл например), и придется для этого все объекты опрашивать, на предмет их координат, что бы понять о том, где они и не находится ли кто-то из них рядом с нашей текущей мшкой/кошкой.
Кароче у меня прям бомбит от своей тупости и не понимания того что делать тут. Как просто и по полочкам съехать в это примитивное казалось бы ООП с самыми что ни на есть кошечками и собачками :(
Есть вот такой говнокод: https://pastebin.com/UwKriche Посоветуйте, как мне лучше его переписать, чтобы он выглядел более менее разборчивым? Может как-то разобрать всё в разные функции? Как это делать, и как понять, когда нужно переносить код в функцию, а когда оставить как есть? Особо сильно не вижу смысла создавать дохуя функций однострочников, так ведь только больше места уходит. Если не прав, переубедите меня. Где вообще читать об этом? Еще мне порой очень сильно не хватает фантазии на то, чтобы придумать название переменной. Это уже проблемы из-за того, что пишу говнокод?
Вообще, желал бы перейти на функциональный и процедурный код. Отговорите меня, или наоборот, убедите использовать всего сразу, но по чуть-чуть и только в подходящих местах. Где?
быдланы, подскажите, если переменная не передана в запросе, нужно ее по дефолту установить. В перле было что-то вроде $huita_name |=$default_value В общем мне нужно, что если $huit_name - определена, то нихуя не делать, а если не определена взять значение default_value. Спс, аноны.
>>1146177 >>1146178 >>1146179 Зочем ты ему помогаешь? Он просит помощи, но делает это без уважения, да и всрато составленный вопрос максимум. Куда у него что приходит, в функцию, в пост, в базу? Фу блядь
А вот это >>1146129 тоже написао без уважения и с врасто составленными вопросами? Я тут нюфаг, но если ответа не получу, то можете сразу так и сообщить, тратить время не особо хочется.
>>1135053 (OP) Посоветуйте, пожалуйста, хороший видеокурс для начинающего, который можно было бы стянуть с торрентов. На английском или русском - без разницы. В PHP я полный ноль, но имеются некоторые знания в сфере HTML/CSS/JS.
>>1146197 Я твоего вопроса тоже не понял. Что у тебя там не так то? Ожидал увидеть тупую стену текста, но увидел класс для незнакомого фреймворка. Или знакомого? бесконечные $this->ci как бе намекают на codeigniter, но в общем хз что у тебя за мешанина там.
Ты в коде как используешь его? $test= new ImageUpdate($ci); $test->command(); как-то так и на этом всё?
Ты можешь пояснить что в итоге твои 2 метода конкретно делают? И зачем ты хочешь их оптимизировать? Если это до тебя писали и просто работает - проще ведь не лезть.
Если дали таск оптимизировать чужой код, что бы учился и разбирался, то хз.
Можешь попробовать например разбить на 2 функции это дело.
Первая будет искать какой-то там твой $diff и складывать его в $this->diff в самом объекте.
А в другой метод запихнуть то, что у тебя внитри форича дергается. Что это этому методу передавать этот самый $diff уже, или даже лучше каждый отдельный элемент.
а комманд например переписать уже так: { $this->diff = $this->addImages(); foreach ($this->diff as $image) { $image->doSomethingWithImage(); } ... //аналогично для самбнейлов
}
Можешь еще сделать так, что бы у тебя не всё подряд printf'алось, а только ошибки. Поле под это дело добавить, которое будешь в конструктор передавать или прямо в коде править когда надо дампить или не дампить, или вообще что бы оно из конфига сайта на этапе конструктора класса подсасывалось
Могу полный бред писать, сам полунубас, не воспринимай меня как гуру но с аналогичным говнокодом на другом фреймворке работал, прост сижу маюсь не могу вот задачи начать решать оповские, где нужно разобраться в том, как с 0 нахуярить микрофреймворк и на нем писать студентов и прочее уже :(
>>1146207 Фреймворк использую Slim, точнее микрофреймворк. Конкретно этот код мой. $this->ci это Container Interface, который подхватывается при совпадении правила route и выполнении функции в Slim. В этой функции находятся много связанного с самим фреймворком.
>Если дали таск оптимизировать чужой код, что бы учился и разбирался, то хз. Нет, это я исключительно со своим вожусь, страдаю перфекционизмом. Всё никак не могу остановится на одном варианте, постоянно не устраивает.
>Ты можешь пояснить что в итоге твои 2 метода конкретно делают? Вообще, забыл, что всё это действительно выглядит очень странно, без объяснения. Этот класс у меня запускается из командной строки, сделано так чтобы вызывалось из крона. Рекурсивно ищет изображения в директорих, берёт местанахождение, sha512 файоа и заполняет эту информацию в базу данных, с помощью Doctrine, попутно генерирует для всех этих изображений превьюшки в заданных размерах через imagemagick.
Вот еще есть вот такой вариант https://pastebin.com/ceAYHjZ3 , но я не знаю, лучше ли он, чем то, что было до этого. Пытался в функциональное программирование. Как видно, выжимал из функций array_* максимум, что они могут. Почему мне кажется, что это крайне плохая затея, программировать так в классах, и тем более в PHP. От того и захотелось переписать всё это на процедурный код. Сейчас пытаюсь вернуться к здравому смыслу и обратился ИТТ.
Со Сваггера приходит число, которое я передаю либе. Либа просит чтобы число было только float. Делаю (float)$number и floatval($number), но при gettype($number) я получаю каким-то хуем double вместо float. Что за хуйня?
>>1146307 Вот чочешь ты например написать для PHP функцию для своего сайта. Например сгенерировать новую 3d модель голой бабы. А в PHP такой функции нет. Вот тут на помощь приходить CGI, пишешь на другом языке это вот всё и потом к PHP подключаешь это всё. Вот это называется CGI.
В unix/linux часто используется принцип разделения ответственности, когда каждая программа отвечает за свою часть работы. В соответствие с этим принципом, веб-сервер (nginx, apache итд) занимается только взаимодействием с клиентом по протоколу HTTP и отдачей статических файлов. Он не умеет при поступлении запроса загружать и выполнять программы на каких-то языках программирования. А это часто необходимо - когда мы хотим, чтобы страницы генерировались бы на "лету", динамически.
Для решения этой проблемы и придуман CGI - набор правил, позволяющих серверу вызывать внешнюю программу на любом языке программирования для обработки запроса. Например, любой веб-сервер, поддерживающий CGI, может таким образом запускать PHP-скрипт при поступлении запроса от пользователя.
Можно настроить веб-сервер так, чтобы он при определенных запросах запускал бы внешнюю программу, а то, что она выведет, отдавал бы назад клиенту в качестве ответа на запрос. CGI и есть набор правил, в которых определено, как веб-сервер передает программе информацию о запросе, и как программа может передавать данные веб-серверу. как они взаимодействуют.
CGI, если ты почитаешь, очень простой и не требует каких-то специальных библиотек. Можно использовать хоть скрипт на bash из 5 строчек, а также, разумеется, программу на любом другом языке программирования. Это его плюс. Ну например, можно сделать bash скрипт, выводящий количество свободного места на дисках, и настроить сервер так, чтобы при заходе на определенную страницу показывалась бы эта информация.
Вот пример такого скрипта (работает только под Мак и Линукс), допустим с именем /var/www/disks.sh:
#!/bin/bash echo "Content-Type: text\plain; charset=utf-8" echo df # выводит информацию о дисках
В линуксе bash-скрипты являются исполняемыми программами и их можно запускать напрямую.
Вот пример части конфига, который указывает Апачу (он поддерживает CGI) запускать этот скрипт при обращении по URL http://127.0.0.1/disks :
Как видим, добавив всего несколько строчек, мы можем смотреть результат выполнения команды df через браузер. Этот пример показывает, насколько прост CGI.
PHP поддерживает взаимодействие с сервером в соответствие с спецификацией CGI.
Минус в том, что запускать внешнюю программу на каждый запрос довольно неэффективно, так как основное время может уходить на запуск/завершение программы, а не на выполнение полезной работы. Потому для нагруженных серверов придуманы новые интефейсы вроде FastCGI где программа запускается один раз и может обработать много запросов от веб-сервера не завершаясь. PHP поддерживает FastCGI с помощью php-fpm.
Ну и другое, не такое удчаное решение - это mod_php, PHP может работать внутрни процесса apache, взаимодействуя с ним через внутренние API Апача.
Веб-сервер nginx не поддерживает CGI, а только FastCGI. Для запуска CGI программ из-под него нужно использовать вспомогательную программу вроде https://www.nginx.com/resources/wiki/start/topics/examples/fcgiwrap/ которая будет принимать FastCGI запросы и запускать внешние программы через CGI.
Что значит "получить инфу от CGI"? CGI это правила взаимодействия двух программ, от самого CGI получить ничего нельзя, можно только с использованием правил CGI вызвать другую программу и получить что-то от нее.
>>1146081 Великовозрастное быдло? Тоже поймал себя на мысле, что все современные новшества - это хуита без содержания. Сидишь, пытаешься понять, читаешь доку - где же потаенный смысл? В итоге оказывается, что ты ожидал от какойто хуйни больше, чем она есть на самом деле. Зато пафоса нагоняют яебу, термины придумывают и пр. Причем специально преподносят инфу об этом в таком сложном виде, чтобы создать иллюзию, что они знают что-то мега сложное
>>1146561 Перечитал >Можно настроить веб-сервер так, чтобы он при определенных запросах запускал бы внешнюю программу, а то, что она выведет, отдавал бы назад клиенту в качестве ответа на запрос
>>1146564 Роутер - запросы роутит Ты пишешь ему hui\pizda\igor а он тебе по заросу страницу скидывает А CGI тебе делеает внутренние расчёты на компе, внешней прогой. Тоесть тут тоже запрос идёт, но это не роут блядь запрос. Это запрос к программе, который тоже через роутер можно сделать. Как вообще эти вещи перепутать можно, я не понимаю?
>>1146583 Я не виноват, что тебя трисет, гуманитарий. Хочешь общаться и не рваться - научись излагать мысли исчерпывающе. http://www.php.su/learnphp/cgi/?interface >Подобным образом можно передавать и html-документы, в таком случае они могут формироваться программой динамически и передаваться браузерам пользователей в ответ на их запросы.
>>1146588 Нахуй ты вообще в треде вопросы задеёшь дебил? Если тебе 5 раз сказали нет, это не роутер, а у тебя всё равно один роутер блядь на уме. Ну и иди нахуй тошда со своим роутером, еблана кусок. Не еби людям мозг. Всё равно ты необучаемый и тупой как полено. Выучил одно слово и теперь считаешь что это всё роутер. Тебе написали что нет, всё равно пытаешься что-то там доказать, зачем только непонятно.
>>1146588 В треде все тебя одманывают анон. Это всё на самом деле роутер. И весь PHP - это роутер. И JS это роутер. Даже CSS это роутер. Ты раскусил заговор против тебя. Не оборачивайся.
>>1146611 Тише. Понимаю, хотел умное спиздануть и обосрался принародно, мой совет - не бегай роняя кал, тихонько ретируйся потом подучишь, может столкнешься на практике и второй раз может получиться не обосраться
Поцаны, поясните, почему на вике написано про cgi >CGI является одним из наиболее распространённых средств создания динамических сайтов. это же совсем разные вещи, верно?
>>1146622 Потому что ты изобретаешь колесо. Есть тысячи библиотек для работы с DOM'ом, используя которые шанс ошибиться намного меньше, чем при попытке написать регексп. >>1146629 Ну смотри. Веб-сервер возвращает статичный контент. Нужна динамика? Дергай скрипт. Как дёрнуть скрипт? Через cgi. Вот и всё. Хотя в той же джаве не или го нет такого разделения на веб-сервер/прикладной код, но мы же тут за пехапе общаемся.
Сорян за глупый вопрос Стоит ли для вкатывания в php начинать проходит курс от И.О.Борисова? Каков он как преподаватель или преподаёт ли он нужную информацию для изучения?
Ну что же такое-то, я вроде пытался все подробно расписать в посте >>1146482 но все равно есть непонимание. Вы точно читали урок про HTTP? Понимаете, как работает веб-сервер?
Повторю еще раз. Когда ты переходишь по какой-то ссылке или вводишь адрес в браузер, браузер как HTTP-клиент связывается в HTTP-сервером и отправляет ему HTTP-запрос. По умолчанию сервер просто в ответ на запрос отдает файл с диска. Это может быть HTML-страница, картинка или что-то еще. Но такой подход позволяет отдавать только статические, то есть неизменные страницы. А часто требуется генерировать страницы динамически с помощью программы на каком-то языке.
Сам веб-сервер не умеет выполнять программы, потому были придуманы интерфейсы/протоколы (правила взаимодействия) веб-сервера с внешними программами - CGI и позже FastCGI. В конфиге веб-сервера мы настраиваем, какую программу и в каком случае надо вызывать.
CGI очень простой и понятный, но медленный - на каждый запрос программа запускается заново. На реальных сайтах используют FastCGI - в этом случае мы запускаем отдельно веб-сервер, отдельно FastCGI процесс, и затем веб-сервер начинает передавать этому процессу запросы, которые тот обрабатывает по очереди, не перезапускаясь. В случае языка PHP, программа php-fpm принимает от веб-сервера FastCGI запросы на выполнение PHP скриптов, выполняет их и возвращает серверу результат выполнения скрипта. То есть веб-сервер "просит" php-fpm выполнить PHP-скрипт, тот выполняет его и передает веб-серверу результат выполнения (что вывел скрипт с помощью echo, какие заголовки выставил с помощью header).
Эти протоколы (как CGI, так и fastCGI) позволяют веб-серверу взаимодействовать с программами на любом языке программирования. Веб-сервер не привязан к какому-то одному языку. Веб-серверу не надо "знать", как выполнить ту или иную программу. Также, они добавляют надежности - если во внешней программе (в интерпретаторе PHP например) произойдет ошибка, и она аварийно завершится, процесс веб-сервера это не заденет и он продолжит работать.
Также, важно то, что CGI-программа не привязана к какому-то конкретному веб-серверу - его можно заменить на другой и все должно работать так же, как и раньше.
Насчет роутера - "роутером" обычно называют часть приложения, которая занимается разбором запроса. То есть это функция, которая получает на вход URL и на выходе дает например название контроллера, который надо выполнить. CGI это не функция, а протокол (набор правил) и уже поэтому нельзя говорить, что "CGI это роутер". Тем более, CGI не занимается вообще разбором URL. Это набор правил, который говорит о том, как веб-севрер передает внешней программе информацию о запросе (через переменные окружения и поток stdin) и как программа возвращает заголовки и тело HTTP-ответа. Почитайте спецификацию CGI, например https://tools.ietf.org/html/rfc3875 (увы, на русском адекватного перевода не нашел) и найдите там что-то похожее на роутер.
> CGI является одним из наиболее распространённых средств создания динамических сайтов.
Это не точно. Во-первых, CGI сам по себе не позволяет создавать никакие сайты, а лишь позволяет веб-серверу вызвать внешнюю программу в случае поступления HTTP-запроса. Потому называть его "средством создания сайтов" неправильно. Во-вторых, как я писал выше, он простой, но медленный и сейчас используют FastCGI.
> Хотя в той же джаве не или го нет такого разделения на веб-сервер/прикладной код
Они просто общаются с веб-сервером по HTTP вместо CGI/FastCGI. В сравнении с CGI это усложняет приложение (ты вряд ли напишешь полноценный HTTP сервер на bash, а с CGI можно работать хоть из bash скрипта), приводит к дублированию функционала (разбором HTTP мог бы заниматься только веб-сервер). Есть конечно и плюсы - они могут работать как-то ограниченно даже без веб-сервера.
В той статье (по ощущениям, она старая или это перевод очень старой статьи) в самом начале ведь написано:
> Термин CGI ... обозначает набор соглашений...
Тут же черным по синему написано: CGI - это набор соглашений. А роутер это часть программы, функция или класс.
>>Подобным образом можно передавать и html-документы, А роутер-то тут при чем? Роутер не занимается передачей HTML-документов, а лишь разбором URL.
По статье - неточность:
> Фактически, до недавнего времени все Web-программирование представляло собой программирование CGI-приложений "до недавнего времени" - где-то до 2000 года, так как спецификация FastCGI появилась в 1996.
> хттп адрес вызывает программу, Не так. Веб-сервер при поступлении HTTP-запроса страницы с определенным URL может вызвать внешнюю программу с использованием соглашения CGI, если в его настройках так указано.
"хттп адрес" (URL видимо) это просто строка, и она ничего не может вызвать.
Вы просто не так понимаете. Вы прочли "фабрика может использоваться для создания объектов" и думаете, что "в 2018" все объекты принято создавать через фабрики. Нет, где это написано? Не надо использовать паттерны просто, чтобы они были.
Паттерны (могу ошибаться) начал собирать Фаулер. Он работал с самым разным кодом, и выделил какие-то типичные решения, которые часто встречались. Дал им названия, определения, описал их в книге. Иногда одну задачу можно было решить несколькими способами (например, наследование таблиц). Если у вас нет книги, то краткое описание паттернов есть на его сайте: https://martinfowler.com/eaaCatalog/ Там, кстати, нет Фабрики или Синглтона (которые вы изучаете, так как они вам кажутся самыми простыми). Зато есть Контроллер Страницы (тот самый, из MVC), паттерны наследования таблиц, паттерны взаимодействия с БД. Почитайте, полистайте. У меня как-то язык не повернется сказать, что описанное там "нигде не нужно" - я это видел много раз, а если вы будете разбирать Симфони, там половина этих паттернов встретится.
В PHP double и float это синонимы. В других языках, вроде Си, это 2 разных способа хранения чисел с плавающей точкой (в Си double занимает 8 байт, а float 4 байта, но первый хранит больше знаков после запятой и представляет более широкий диапазон значений).
> class ImageUpdate Название класса - это существительное, хотя бы ImageUpdater, "обновлятель картинок" (есть впрочем мнение, что вредно называть классы с суффиксом -er).
> class ImageUpdate extends Container Здесь ошибка, непонимание наследования. Вот я даже в своем учебнике пытался описать ( http://phpbooktest.ga/l1/pasta.html )
> Наследование позволяет создать новый класс не с нуля, а расширив уже существующий. > Нельзя наследовать что угодно от чего угодно. Наследование должно применяться только для однотипных сущностей. Например, класс Банк можно унаследовать от класса Организация (так как банк - это вид организации), а вот унаследовать класс Работник от Организации нельзя. Также, нельзя унаследовать Организацию от Банка, так как Организация - это более широкое понятие.
"А наследуется от B" - это значит "А является B". Это значит, объект класса B можно использовать в коде вместо A (принцип замещения Лисков).
Обновлятель Картинок не является улучшенной версией DI Контейнера. Никто в здравом уме не будет передавать его туда, где нужен Контейнер. Он выполняет совсем другие задачи. Наследование тут неприменимо.
Также, ты нарушил принцип единственности ответственности (каждый класс выполняет свою задачу) - у тебя класс ImageUpdate занимается и сбором картинок, и выполняет роль DI контейнера.
Кстати, это типичная ошибка, я такое во многих CMS видел, люди просто не понимают ООП.
Хотя, я могу ошибиться, так как из куска кода неясно, что такое Container. Тем более что некий ci у тебя еще и передается в конструктор.
Дальше, в конструктор ты передаешь DI Container - но DI делается не так. Прочитай мой урок про DI, лень тут пересказывать все: https://github.com/codedokode/pasta/blob/master/arch/di.md . В конструктор передаются сами зависимости, а не контейнер.
> $images = $this->repo->findAll(); Это будет хорошо работать только до нескольких тысяч записей, а потом скрипт начнет есть много памяти и медленно работать.
> $files = Files::find($this->imageRoot, $this->ignore, $this->imageExts); Название класса Files неудачное. Что, его объект представляет набор файлов? Нет, это просто Utility class со статическими методами и логично было назвать его FileUtil или FileHelper.
Список расширений наверно незачем делать задаваемым извне параметром - у тебя ведь код поддерживает только определнные расширения и логично их тут же жестко и прописать. В какой ситуации тебе понадобится менять этот параметр?
> foreach ($images as $image) array_push($list, $image->getImage()); Надо писать в 3 строки со скобками. Глянь PSR-1 и PSR-2, они есть и в переводе. Или пропусти код через phpformatter.com.
> $image->getImage() Метод называется getImage но возвращает, судя по всему, не картинку, а путь к ней. Ну так и сделай соответствующее название.
> if ($dup = $this->repo->findOneBy(['sha512' => $sha512Hash])) { Если ты загрузил все файлы в память выгоднее сделать "индекс" в виде массива и искать по ключу в нем - это в разы быстрее, чем слать запрос в БД.
> $this->ci->em->persist($image); > $this->ci->em->flush(); Вообще, не выгодно делать flush после каждого файла, выгоднее собрать побольше сущностей и разом их записать в БД.
> $this->ci->em->clear(); А это вообще не логично. Ты понимаешь, что делает эта команда?
> exec(sprintf("convert -thumbnail Это довольно невыгодно, запускать внешнюю программу на каждую картинку. Выгоднее использовать расширение imagick или gd.
Также, ты плохо сделал запуск внешней программы. Она может вывести что-то, вернуть ненулевой код возврата, даже зависнуть - у тебя это никак не проверяется. А это значит, что ты не обнаружишь ошибку сразу, а потом обнаружишь битую или отсутствующую превьюшку и потратишь кучу времени на выяснение, откуда она взялась.
> ob_flush(); Зачем они там в каждой строке?
> foreach (["medium" => "1000x1000", "small" => "250x250"] > as $name => $size) Слишком длинный и нечитаемый заголовок цикла. не надо так.
> $key = array_search($thumb, $files); Невыгодно искать по значению, быстро делается поиск по ключу.
По коду, код плохо оформлен, не по PSR, оставлены какие-то закомментированные куски, тяжело читать. Также, функции написаны одниой длинной стеной кода, надо выносить отдельные действия. Например, в методе addImages (который правильнее назвать findNewImages или findUnregisteredImages), можно вынести отдельно метод createImageEntity.
В методе createThumbs генерацию одной превьюшки надо вынести отдельно.
Также, ты делаешь обработку в неправильном порядке. Надо сначала генерировать превьюшки, а потом вставлять информацию в БД. Иначе, возможна ситуация, когда картинка есть в БД, но на диске нет соответствующих файлов.
> есть вот такой вариант https://pastebin.com/ceAYHjZ3 Куча методов с плохо составленными названиями, без тайп-хинтов. Если ты хочешь попробовать функциональное программирование, изучай Хаскелл, так как это конечно не оно.
> isset($args[0]) && $args[0] === "thumbs" ? > $this->thumbs() : $this->thumbs($this->images()); Не надо так делать. Тут нужен if, а ты зачем-то его обфусцируешь, от этого никакой пользы и труднее читать код.
> Вообще, желал бы перейти на функциональный Тогда изучи сначала функциональное программирование на примере Хаскелл. На PHP корявость синтаксиса только отпугнет тебя.
> Как это делать, и как понять, когда нужно переносить код в функцию, а когда оставить как есть Когда полeчается тяжело читаемая стена кода, когда в ней явно можно выделить отдельные действия.
> так ведь только больше места уходит Цель - читаемость, простота поддержки, а не экономия строчек.
> очень сильно не хватает фантазии на то, чтобы придумать название переменной Надо учиться объяснять, зачем нужна эта переменаая и что она хранит.
> Мне эта задача уже года два не дается наверное Это нездоровый перфекционизм. Ты сделай хоть что-то работающее и вбрось в тред, а там тебе укажут что исправить. Иногда лучше просто что-то сделать, чем долго думать.
> Наприрмер о том, где нужно хранить координаты животного. Либо в мире, либо в самом животном например. Надо взвесить плюсы и минусы.
> Допустим животные хранят в себе своё положение в мире. Стало быть нельзя просто взять и спросить у мира кто рядом с нами? Ну допустим, координаты хранятся в "мире" в виде массива Coordnate[] (объект Coordinate содержит поля x и y). В чем отличие? В одном случае - массив животных, в другом - массив координат.
Я скажу, в чем. Отличие в том, что когда координаты в мире, их нельзя изменить без его ведома. Если у тебя есть, например, индекс для быстрого поиска на карте, то его надо обновлять при изменении координат. Когда они в мире - это просто. А когда в животных - то мир должен как-то узнавать об их изменении:
- животные должны либо явно уведомлять мир об их изменении - либо он должен держать копию их координат и после хода сравнением обнаруживать изменения
Если у тебя нет индекса, то разницы, как мы видим, нет, и миру не надо знать, что координаты изменились.
Чтобы быстро спросить "кто рядом" при большом числе объектов, разумеется, массив не годится - там время поиска O(N). Для этого используют индексы - структуры для оптимизации поиска. Есть много разных видов индексов с плюсами и минусами:
Например, kD- и BSP-деревья позволяют быстро искать точки в определенном радиусе, но к недостатку можно отнести то, что при перемещении любой точки надо их перестраивать - а у тебя перемещения происходят постоянно. Они лучше годятся для неподвижных объектов (поиск точек на карте, например). R-tree ( https://en.wikipedia.org/wiki/R-tree ) врде лучше заточены под изменение, но очень сложные.
Есть еще другие подходы. Например, разделение пространства на "сектора", причем id сектора вычисляется из координат. Затем мы делаем индекс (просто массив), который хранит для каждого сектора все объекты в нем. Когда нам надо искать ближайшие точки к данной, мы берем ее сектор и, если надо, соседние, берем объекты из них и уже их отсеиваем по расстоянию. При перемещении объекта в другой сектор индекс надо обновить, при перемещении внутри сектора - не надо.
Многие из алгоритмов рассчитаны на поиск в произвольном радиусе, но если у тебя радиус фиксированный, то их можно сильно упростить.
В этой задаче мышек и кошек не так много, и можно не заморачиваться. Но, если хочется разобраться в теме, я конечно, готов помочь. Индекс стоит сделать в виде отдельного объекта, конечно же. Его надо обновлять при каждом перемещении любого объекта. Но сначала можн осделать просто без индекса.
> Как просто и по полочкам съехать в это примитивное казалось бы ООП с самыми что ни на есть кошечками и собачками :( Напиши список классов, полей и методов (без кода) и обсудим.
А давай сформулируем задачу и ты сам предложишь ее решения, а там обсудим.
Ну например: надо сделать авторизацию на сайте, и такие функции:
- регистрация: функция получает на вход логин, пароль и "запоминает" их где-то - проверка данных: функция получает на вход логин, пароль, и проверяет, правльные ли они - вход на сайт: функция получает на вход логин, пароль, если они верные, то выставляет некую куку - проверка залогиненности: функция проверяет по кукам, залогинен ли текущий пользователь, если да, то возвращает его логин, если нет - null - выход: вызов функции "разлогинивает" пользователя, удаляя авторизационную куку
Попробуй описать алгоритм этих функций словами или кодом.
> действия на сайте Создается таблица в БД. При каждом действии пользователя в нее добавляется запись. Можно писать действия в лог-файл. Можно использовать Google Analytics, где это уже сделано.
> подгрузка видосов, Тут куки не причем. Сформулируй конкретную задачу.
> сохранение действий. Это по моему то же, что и выше. Делается табличка или файл.
Код надо выравнивать. У тебя он прижат влево (ты прямо в ideone пишешь? Установи notepad++, sublime text, netbeans, eclipse pdt, phpstorm или другой редактор кода) и потому читать очень тяжело. Или пропусти код через phpformatter.com.
> $amount7 = 02020200; Это число в 8-чной системе счисления:
> наверное самое эффективное решение это выдавать ссылки на файл в публичной папке, а в этой папке отключить обработку скриптов.
Тут есть подвох, что файлы могут быть с самыми разными именами: file.php, .htaccess, файл из иероглифов. И это требует тщательной настройки сервера - стоит сделать ошибку и он начнет радостно выполнять php-файлы. Плюс, может ты захочешь считать статистику скачиваний, ограничивать доступ.
На практике, файлообменники все же обычно используют что-то вроде x-sendfile. То есть запуск скрипта, а потом выдача заголовка для сервера на скачивание файла. При этом файл можно хранить под безопасным именем.
> Каким образом в реальном мире производятся фоновые задачи? Через очередь задач. В приложении делаешь класс с методами добавить задачу/проверить статус задачи/снять задачу. Обычно там просто делается таблица - очередь задач (могут быть другие варианты - например, очередь в RabbitMQ) - и есть один или несколько скриптов-рабочих, которые следят за ней и при появлении новой задачи берут ее, выполняют, и записывают результат. Могут по ходу дела обновлять прогресс. Опять же, они могут как-то посылать уведомление о завершении.
Использовать БД не принципиально - можно например постить задачи, сообщения о прогрессе, ошибке/успехе в очередь сообщений вроде RabbitMQ. Как удобнее. Можно использовать и то, и другое.
Рабочие могут запускаться через крон, может быть отдельный какой-то супервизор, который за ними следит, может быть какой-то процесс с несколькими потоками-рабочими внутри.
На клиенте - можно использовать поллинг (периодиечски отправлять аякс-запросы на проверку статуса либо просто перезагружать страницу ожидания), либо настроить передачу уведомления с сервера на клиент о прогрессе и завершении задачи (надо изучить вебсокеты и протокол WAMP).
Если ты ищешь готовую функцию, то такой нет. Если ты думаешь, что PHP ограничен выполнением скриптов при вводе URL в адресную строку, то ты ошибаешсья - программу PHP можно запустить отдельно от веб-сервера, вручную или прописав ее в автоматический запуск при включении сервера под наблюдением супервизора.
> По наводке из статьи опа прочитал про gearman, мало что понял, Задавай вопросы
> есть еще какой-то крон Ну так изучи его.
> Вот как например ютуб конвертирует видео? Так, как я описал, только у них скорее всего система распределенная, и конвертацией занимается не просто несколько процессов-рабочих, а множество таких процессов на множестве серверов.
> Если я буду в превьюхе указывать сорс на оригинальную картинку, то будет ли выполняться пхп код Нет, с чего бы? Только неэффективно ради превьюшки качать огромную картинку. Но конечно, это зависит от настройки сервера - если ты скажешь ему, что картинки надо выполнять как php-скрипты, то все возможно.
Можно смотреть на библиотеки крупных компаний: Гугл/Яндекс. А так, я не смогу сформулировать требования, думаю, тут те же подходы, что и при написании внутреннего кода, только побольше комментариев и документации. Чтобы код был простой и логичный, без побочных эффектов и "магии".
species можно сделать ENUM или внешним ключом (ссылкой) на таблицу видов животных, если их ограниченное количество.
> список владельцев с полями, по id животного > список животных с полями, по id владельца > информацию по владельцу(ам), по некоторой известной инфе о животном (клеймо, микрочип)
Запросом SELECT с JOIN. Ты изучал джойны? Если нет, то изучи.
> тормознутые транзакции откинуть Это бессмысленное утверждение. Что значит "тормознутые транзакции"? В случае InnoDB любое изменение данных это транзакция.
> Главное чтоб быстро выбирало крупные данные и без лишних полей. Транзакции тут точно не при чем - они относятся к изменению данных.
>тормозов из-за транзакций. Почему ты решил, что дело в них? Может, у тебя индексы не сделаны? диск медленный? памяти мало выделено? еще что-то не так?
Тебе надо научиться настраивать MySQL, а также профилировать запросы. например, освоить команду EXPLAIN, ну и посмотреть в htop, iotop на процесс MySQL - сколько он ест памяти, CPU, диска.
Внешние ключи и транзакции экономят твое время на исправление багов в данных в БД.
Попробуй сдампить echo bin2hex($s), где $s - строка с кириллицей, полученная через fgets() и напиши что получится - может, это даст ответ. Может, там какие-то коды есть, которые интерпретируются как перевод строки.
>>1146702 >Напиши список классов, полей и методов (без кода) и обсудим.
Окей, тогда отталкиваясь от совета: >Это нездоровый перфекционизм. Ты сделай хоть что-то работающее и вбрось в тред, а там тебе укажут что исправить. Иногда лучше просто что-то сделать, чем долго думать. Сделаю максимально просто для начала.
Например не буду заморачиваться с тем как это там дожно быть по хорошему в вакууме.
1. Ну для начала нужен класс Animal, у него будут поля $x и $y - это банально место положение на нашей карте. Далее например будет абстрактный метод lookAround() - который будет переопределен для мышки и кошки отдельно, пока сложно понять что он должен возвращать, допустим пусть возвращает все доступные животному клетки(координаты) со значением привлекательности каждой из этих клеток.
Опять же вот думаю об этом, и если у нас например объекты хранят в себе координаты, то для кошечки, когда она смотрит вокруг, а она будет смотреть на всё поле, для КАЖДОЙ долбанной клеточки на поле будет вызываться перебор ВСЕХ объектов в мире, что бы высчитать для этой клеточки привлекательность, ведь надо что бы рядом с клеточкой было как можно больше мышек и как можно меньше других кошек скажем. Будет адуха адская в плане неоптимальности решения, ну да и черт с ним.
Допустим посмотрели вокруг, и нужно сделать ход, для этого другой метод, которому уже передаем массив клеток с их привлекательностью, и кошечка уже принимает решение куда сходить. Либо кошечка ходит просто на САМУЮ привлекательную клетку из доступных, либо например сделать так, что бы она ходила на самую привлекательную клетку, из тех, которые лежат на кротчайших путях к САМОЙ привлекательной клетке на поле. Условно говоря пикрил (пока рисовал, думал что кошечка ходит на 1 клетку за ход, а там вроде бы на 2 по условию задачи, так что не суть, просто как пример)
Для мышки аналогично сделать, опять же перебирать все все объекты на поле, что бы вычислить привлекательность для каждой из тех клеток которые она видит, благо видит она всего +-4 в каждую сторону, так что итераций будет в сотни раз меньше в случае средненького поля. Ну и методы подсчета привлекательности переделать, подальше от кошек, стен и скопления других мышей ей прописать например. Ну или наоборот что бы жалась к другим мышкам, глядишь в толпе выжить проще и съедят не тебя (бедная глупая мышка, только проще для кошки будет с каждым ходом становиться, когда они в кучке)
2. Ну и наверное класс поля, который будет просто нужен для хранения в себе всех животных, через него наверное будем обращаться ко всем объектам, блин если честно пока вот это писал - уже голова закипать начала, как будто не простейшую задачу пишешь, а целую игру программируешь сложнейшую со своим ИИ и поиском путей, блин.
Ну и метод для отрисовки поля, думаю простейшее - сначала залить поле нулями, а дальше перебирая все объекты заменять нули на иконку мышики или кошки. Выглядит логично.
Ну и какой-нибудь класс по типу gameLoop, для того что бы в него всё свалить, запускать на каждой итерации которой все живые животные по очереди будут ходить, а потом будет отрисовываться карта. И так столько сколько задано.
В общем, идеи верные, можно начинать писать код. Я вижу, что ты сильно заморачиваешься с алгоритмом хода, почемы бы вместо него пока не поставить заглушку - просто делать рандомный ход или даже стоять на месте - сделать все остальное, а потом перейти к тестированию разных вариантов алгоритма?
> Далее например будет абстрактный метод lookAround() - который будет переопределен для мышки и кошки отдельно, пока сложно понять что он должен возвращать, допустим пусть возвращает все доступные животному клетки(координаты) со значением привлекательности каждой из этих клеток.
Тут можно еще чуть упростить задачу, если свести все к функции оценки (сделать ее абстрактной). Мы даем животному координаты и оно оценивает привлекательность этого хода. Так мы можем вынести перебор ходов, выбор лучшего наружу - но правда тогда все животные должны будут использовать этот алгоритм.
Другой вариант - сделать абстрактный метод makeMove(), который ничего не возвращает и сам выбирает и делает ход. В этом случае животное может использовать вообще любой алгоритм.
> Опять же вот думаю об этом, и если у нас например объекты хранят в себе координаты, то для кошечки, когда она смотрит вокруг, а она будет смотреть на всё поле, для КАЖДОЙ долбанной клеточки на поле будет вызываться перебор ВСЕХ объектов в мире, что бы высчитать для этой клеточки привлекательность, ведь надо что бы рядом с клеточкой было как можно больше мышек и как можно меньше других кошек скажем
Ну у нас там пара десятков объектов всего. Ты бы вместо того, чтобы переживать, сделал бы тест и померял, сколько это времени занимает.
И еще мысль. Ты вот сейчас мыслишь по-программистски - надо любой ценой оптимизировать потребление CPU. Но в реальной работе программиста бывают и другие варианты:
- надо оптимизировать время разработки. Лучше плохой, но работающий алгоритм сегодня, чем идеальный через месяц - надо оптимизировать затраты. Дешевле может быть переехать на сервер помощнее, чем 2 недели оптимизировать код
Мы конечно тебе за обучение не платим и потому расходы твоего времени нас не очень беспокоят, но может быть, они беспокоят тебя.
Ну и если уж ты задался целью любой ценой оптимизировать потребление CPU - надо брать другой язык программирования. Так что давай без фанатизма, но и конечно без откровенно плохого решения - искать компромисс.
В твоем случае, я уже писал выше, можно 1) использовать индексы для поиска ближайщих соседей, причем, что важно, можно сначала писать без индексов и только потом их добавить 2) можно что-то кешировать, например, если несколько кошек делают одни и те же вычисления, можно закеширвать их результаты.
Также, можно упростить алгоритм. Ну например, вместо обзора всех клеток в поле зрения - просто перебирать только те клетки, на которые мы можем сходить, вычислять очки по какой-то простой системе для них и не просчитывать на несколько ходов вперед. Вполне возможно, что тестирование покажет, что этот алгоритм прекрасно справляется с задачей. А если будут какие-то мелкие косяки - закрыть их добавлением дополнительных факторов при оценке хода.
У нас все таки задача больше на ООП, чем на игровые стратегии.
>>1146724 Я как раз и пытаюсь выйти на новый уровень, потому что я уже поработал 2 года говношлепом на фреймворке, когда тупо херачишь говнокод быстрее быстрее, лишь бы работало по уже отработанной схеме, просто потому что надо. Ладно, не буду об этом.
Не могу в общем при написании отделаться от ступора, например когда тебе в мир нужно передать объект животное когда ты его вроде бы там логично спавнишь, и при этом же в животное передовать мир, когда ты смотришь вокруг, получается такая вот какая-то взаимозависимость, к чему я ВООБЩЕ НЕ привык на своих нубоработах. >Я вижу, что ты сильно заморачиваешься с алгоритмом хода, почемы бы вместо него пока не поставить заглушку - просто делать рандомный ход или даже стоять на месте - сделать все остальное, а потом перейти к тестированию разных вариантов алгоритма? Спасибо, камень с души прям, так и сделаю сейчас.
>1) использовать индексы для поиска ближайщих соседей, причем, что важно, можно сначала писать без индексов и только потом их добавить Не понял что тут имеется в виду? Хранить отдельно координаты? скажем еще и что бы мир знал что у него в какой клетке и через него спрашивать а кто тут у нас в округе сидит, вместо того что бы опрашивать все объекты в мире? Я над этим уже много думал. Наверное дублирование всё же нужно в хорошей системе. Просто потому что ну как с базами, если всё пытаться к третьей форме приводить, то ты очумеешь делать простейшие запросы собирая страничку юзера, так и тут, одуреешь перебирать все объекты мира, в надежде узнать есть ли кто рядом в соседней клетке, КОГДА МОЖНО ПРОСТО ПРОДУБЛИРОВАТЬ ИНФОРМАЦИЮ 1 РАЗ, и иметь возможность спросить у overseer-объекта кто у нас там рядом в соседней клетке. Ты об этом?
>>1146705 Архивировать на клиенте файлы недопустимых расширений, отправлять на сервер файл вида file.php.tar.gz и хранить на сервере в виде архива, будет плохой идеей? Я тоже решаю эту задачу, только у меня там еще потуга сделать более или менее полноценный фронт-енд.
>>1146698 >Они просто общаются с веб-сервером по HTTP вместо CGI/FastCGI. И да, и нет. Контейнер сервлетов - такой же полноценный веб сервер. Да и несервлетные приложения тоже. >В сравнении с CGI это усложняет приложение (ты вряд ли напишешь полноценный HTTP сервер на bash, а с CGI можно работать хоть из bash скрипта), приводит к дублированию функционала (разбором HTTP мог бы заниматься только веб-сервер). Ты же не пишешь свой сервер. Ты точно так же берёшь томкат/аппликейшн сервер/библиотеку и пользуешься. И опять: веб сервер - это не только апач или нджинкс. >Есть конечно и плюсы - они могут работать как-то ограниченно даже без веб-сервера. Они работают полноценно. И на этом основаны всякие ништяки микросервисов вроде service discovery и client side load balancing.
>>1146700 Паттерны (могу ошибаться) начал собирать Фаулер. Фабрику, синглтон и всякие прокси описаны задолго до него бандой четырех. Фаулер именно по ентерпрайзным паттернам угарел.
>>1146757 Ладно, поясню тебе на пальцах. Там php 5.5 - что самое главное. Там уже есть ооп и прочее. Те изменения, что завезли пхп 7, тебе всё равно в первый год не понадобятся, я базарю.
Во вторых подобный курс - это всё равно лишь основы языка и не более. Тебя научат как сделать простенький сайт на коленке с несложной версткой и основами владения mysql опять же.
Что в подобном курсе от 2014, что от 2018, тебе будут объяснять по сути одно и тоже, тупо в мелочах отличия, которые ты забудишь через пару дней - базарю. А еще если ты не будешь сидеть и ждать пока тебе подкинут идеальный гайд как стать синьёром-php за 5 дней без регистрации и смс, а прямо сразу посомтришь хотя бы первый день, то ты уже бы сделал для своего потенциального будущего куда больше, чем возможно за всю предыдущую жизнь в школе (и универе).
>>1147201 Дополню тебя, что в PHP7 (который вышел аж в 2015-м году) есть spaceship оператор и cтену if'ов в колбеке можно заменить одной строкой: return $a <=> $b; >1146129 >Еще мне порой очень сильно не хватает фантазии на то, чтобы придумать название переменной.
Не можешь дать нормальное имя переменной - не до конца понимаешь, что в ней находится. Плохое именование от непонимания.
>>1147307 там 2 строчки кода в каждом решении, он не может быть неправильным. >Почему во втором решении код выглядит как не читабельная каша? Потому что ты не привык просто пока к каким-то операторам или синтаксису и тебе нужно больше практиковаться.
Не парься над такими легкими задачами, то что ты решил её двумя способами - это уже хорошо само по себе, а пытаться вычислить идеальное решение - это глупо, решай так, как тебе больше нравится, думай об этом как о СВОЁМ СОБСТВЕННОМ стиле программирования.
ебучая система образования сука с её заучиванием идеальных путей и алгоритмов, когда тебя именно кормят идеальными путями решения всяких уравнений и прочего говна, а потом ты по жизни везде пытаешься под это подстроиться :( Вместо того что бы просто решать проблемы, ты ищешь идеальный, "правльный" путь её решения. Тьфу пиздос кароче горит аж, потому что у меня тупо саем по жизни
Ребят, есть скрипт, парсящий xml-документ. Скажите, в какую сторону гуглить, если я хочу, чтобы xml-документ для парсинга и вывода результатов на страницу выбирался с помощью диалогового окошка?
Интересует мнение пехепешников. Сам я пхп макакер, с сайтами приходится работать редко, в основном пишу разные парсеры, ботов, спамеры и пр хуйню-малафью. Ничего другого кроме пхп не знаю когдато знал жс и немного кресты но нихуя не помню. Часто ловлю себя на мысле "ах вот если бы то или се", "вот еслибы запустить куски моего кода асинхронно и кококо". Подумываю взяться учить ноду, стоит ли этим заниматься в 2к18? Спешить никуда не планирую, буду в свободное время посматривать уроки, но может стоит обратить внимание на чтото более актуальное?
>>1147710 А в чём фишка нодовской асинхронности? Может кто-нибудь расскажет? Ну тоесть я так понял это когда ты отправляешь несколько запросов, и они отрабатываются отдельным потоком каждый? Но ведь по факту там просто формирование очереди запросов и вся асинхронность получается чисто на бумаге. Или я не прав?
Я тут посмотрел вакансии на hh, примерно 30% компаний указывают что нужна техническая вышка. У меня вопрос к устроившимся анонам, в остальных компаниях без вышки в большинстве случаев покажут на дверь?
>>1148355 то есть чуваков с опытом/портфолио берут и без вышки? вот допустим я с головой ухожу в backend может ли сказаться нехватка знаний по высшей математике/азов программирования что изучают в профильных вузах?
>>1148380 А что мешает п_одучить математику или "азы хирургии"? Открываешь учебник по биологии за 11 класс и читаешь. Вот примерно также ты сейчас сказал. На деле тебе нужны будут тонны практики. Так что советую её получить.
>>1148376 В сурьезные конторы, да и в некоторых случаях заграницу без вышки не выйдет. Никто не запрещает попробовать, откажут ну и хуй с ними. Во всех остальных случаях не так жеско. Где то якобы требуют, а на деле похуй, где то напрямую говорят нам насрать. На срилансе вообще никого не ебет, что ты там закончил, главное пили таски и не лажай сильно.
Ты упускаешь самое главное для ойти это английский язык. Знаешь хорошо, считай будешь устроен. Знаешь средне придется тяжело. Нихуя не знаешь, только доку иногда покурить можешь, нихуя не найдешь.
А если английский знаешь, то пилишь портфолио или нарабатываешь опыт на галерах, и все получится. Книжки можешь почитать, но это для общего развития. Ты больше узнаешь из практики, чем из книг.
>>1148405 При чём тут биология за 11 класс? Чел спрашивал про азы программирования, а их, т.е. алгоритмы, структуры данных и прочее, как раз в этих книгах и можно найти (плюс еще пара книг по архитектуре, сетям, операционным системам и пр). А дальше да, уже дело за практикой.
В медицине то же самое, ты можешь преспокойно учиться по книгам самостоятельно, но для того, чтобы стать хирургом, безусловно нужна практика.
>>1148429 Так я и не хотел опровергнуть, я хотел дать другую перспективу точки зрения. Ну и я сам прочитал овер 9000 книг, но на работу меня не брали пока не появилось более менее вменяемое портфолио и кое какой рассказ об участи в проектах. Никого не смутило что проэкты я сам для себя придумал и написал.
>>1148431 Потому что работодателю по большей части пофиг на твои знания, будь ты хоть ученым в области информатики. Он заинтересован только в том, сможешь ли ты выполнить свою работу или нет, сможет ли он на тебе заработать или нет.
Пишу свой первый бложик и реквеструю у анона не много мудрости. В БД лежат категории и статьи, хочу выводить каскадом по 1 блоку с n-количеством статей своей категории, следующий блок новой категории уже идет справа, как на пикрелейтед.
Я, в принципе, знаю как это сделать, но без каскада, а просто циклом перебрать статьи по категориям из бд.
Можно запрашивать из бд четные категории влево, а нечетные вправо, но тогда как быть с блоками ?
Братцы, поясните, как лучше всего хранить прикрепленные файлы к постам на мелкопараше. Сделаю табличку аттачей, но какая структура папок будет наиболее верной. Папочка для каждого треда или как?
Реквестирую гайд по пхп для не новичка в программировании. Чтобы не поясняли 5 лет что такое переменная, а сразу к сути. Желательно видосик, хотя врядли такое существуют.
>>1148376 1. Программирование наверное единственная профессия, где на образование смотря в последнюю очередь т.к. тут реально нужно уметь делать и это важно в первую очередь. 2. Образование может быть плюсом если ты нубяра полнейший. Друг учился, его взяли работать т.к. понимали, что он учится соответственно его нубство - явление временное и он развивается почучуть, а не забил хуй.
Кукареки про математику придумали долбоебы, которые никогда не работали, нахуй тебе ее знать, сука, объясни? Сам хоть понимаешь? Если конечно под знанием математики подразумевают умение сложить 2+2, то это везде надо уметь и только школьный довнич может назвать это "знанием математики", а не признаком недауна.
Необходимо понять, что человек не может знать все и ты не можешь заранее подготовиться, выучить все, что потребуется, прийти на работу и не столкнуться с трудностями. Везде свой стек, который ты просто не можешь знать заранее. Всегда будет ощущение, что ты нихуя не знаешь, всегда будут появляться ошибки, которые ты не сразу поймешь как исправить - ВСЕГДА. Однако, знать основы нужно конечно и уметь гуглить.
И самое главное - опыт, чем быстрее начнешь работать - тем лучше. Опытного человека всегда видно и всем похуй есть у него образование или нет, чем больше опыта тем более похуй тебе будет на образование и тем менее будет стоять вопрос "если уволят куда я пойду"
Как сделать чтобы данные из post формы не сохранялись? Сделал говноскрипт - шортлинкер aka goo.gl, создает файлы с рандомным именем с редиректом внутри, ввожу в него ссылку, он создает, все заебись, а потом обновляю страницу, и он с той же ссылкой (которая уже не введена) создает еще один.
>>1148812 >Куки же можно угнать у пользователя Тоже хотелось бы узнать подробнее об этом вопросе
Куки можно угнать: 1. С помощью xss
Чтобы избежать этого нужно выводить все вводимые данные пользователем с помощью функции htmlspecialchars(...) И, дополнительно, поставить кукисам параметр httpOnly
Так же, хотелось бы узнать, есть ли такой способ кражи, при переходе на посторонний сайт.
Почему бытует мнение, что переход по незнакомым ссылкам чревато? Посторонние сайты же не имеют доступа к кукам вне своего домена. И единственное чем может быть это полезно, это сбором информации о клиенте и его ip-адресе, а так же рамещением фейковой формы, для залогинивания, что, на мой взгляд, совершенно бесполезно.
>>1148838 https://ideone.com/VM1bq4 Алсо, почему он из массива только цифры берет, и вообще берет не 5? Алсо, насколько я понял, isset это не совсем то, что мне нужно для обработки нажатия. Что мне нужно?
>>1148585 братюнь, ты вот рекомендуешь котерова качать, мне интересно, а ты сам где работаешь? у тебя тимлид проводит код ревью? заставляет тесты писать?
>>1148916 >Алсо, почему он из массива только цифры берет, и вообще берет не 5? Не знаю, но с версией PHP7.2.2 берётся именно 5 https://3v4l.org/J9BpQ#output
А почему ты сохраняешь не в базу данных, а в файлы? И тем более в php скрипты? Лучше было бы в .json - как раз конструкция ключ -> значение К тому же, у тебя должен быть отдельный php скрипт, который берёт параметр $_GET с ключом к твоей ссылки, и делает редирект - никаких $_SERVER['SERVER_NAME'] делать не нужно (http://htmlbook.ru/samhtml/ssylki/absolyutnye-i-otnositelnye-ssylki):
/redirect.php?key=foo42
<?php if (isset($_GET['key'])) { $key = $_GET['key'];
if (форма отправлена) { // валидируем ссылку // создаем массив [$key => $url] // преобразуем его в json // сохраняем json // перенаправляем на страницу с результатом и выводим ссылку на redirect.php?key=$key }
Так же не забывай, что если ты позволяешь пользоваться твоей программой посторонним, то тебе следует валидировать ссылки и экранировать их вывод
>>1149023 Красиво конечно сделано. Приятно просматривать файлы, все понятно сразу что где куда. 2 года ты это постоянно делал или прерывался? Считаешь проект законченным?
>>1149017 Нихуя себе ты накатал. > Не знаю, но с версией PHP7.2.2 берётся именно 5 У меня вообще была версия 5 почему-то в вампе, лол. Переключил на 7.1.9, все также. > Должно быть, это как-то связано с этим https://secure.php.net/manual/ru/migration72.incompatible.php#migration72.incompatible.rand-mt_rand-output Нихуя не понял, как это может быть связано с работой функции, которая рандомит элементы из массива. > Тебе нужно $_SERVER['REQUEST_METHOD'] == 'POST' Блядь, охуеть, а именно конкретного онклика нет? Язык-костыль. > А почему ты сохраняешь не в базу данных, а в файлы? И тем более в php скрипты? Лучше было бы в .json - как раз конструкция ключ -> значение Потому что я вчера впервые в жизни взялся за пхп. И бомбанул от костыльности. За сим, нихуя из ниже слудующего не понял.
>>1148973 > После того, как сделал свою ссылку, делай рефреш страницы и всё. Так а зачем, если в рефреше и проблема? Если не рефрешить, кстати, а убрать слеш в конце ссылки и перейти, то все норм и ничего не создается. > P.S. Для шортлинкера лучше не использовать рандомные комбинации, а последовательно увеличивать последовательность символов. В смысле увеличивать последовательность символов? Чтобы после сотого раза у меня моя короткая ссылка была длиннее чем какой-нить запрос в гугл на русике? Алсо, наоборот же. Потому что тогда юзеру можно будет смотреть че там другие юзеры делают.
>>1149061 Ты пиздец тупой, еще и быдлан, тебе уважаемый человек в треде отвечал вежливо, а ты хуйню несешь.
>В смысле увеличивать последовательность символов? Если ты рандомишь, то есть шанс что ты зарандомишь под новый запрос такой же урл, который ты уже отдавал когда-то.
Поэтому если у тебя ссылки например были бы из цифр, то нельзя просто руярить случайное число /34533, /43234 /21387 ... /34533 - так по мере накопления у тебя будут тупо старые заменяться новыми и ты че совсем еблан рили?
/00001, /00002/, /00003, ... /99999 - все урлы равномерно заполнят все возможные комбинации чисел без пробелов и перезатираний.
Кто-нибудь поясните вкратце или дайте ссылку как на джеквери склепать комменты, как на дваче, конкретно ту часть, где тыкаешь мышкой в ид коммента на который отвечал и появляется окошко с этим комментом, и там можно ещё тыкнуть и появиться ещё окошко лесенкой... Короче, интересует именно как выстроить эту лесенку, как на дваче и чтобы она убиралась как на дваче, пре отводе мышки на коммент более высокого уровня либо вовсе с коммента. (Систему ссылок и получения данных комента по этой ссылке я уже сделал). Заранее спасибо.
>>1149135 > Ты пиздец тупой, еще и быдлан, тебе уважаемый человек в треде отвечал вежливо, а ты хуйню несешь. Лол, блядь. Быдлан я, охуеть. В треде про быдлоязык. > Если ты рандомишь, то есть шанс что ты зарандомишь под новый запрос такой же урл, который ты уже отдавал когда-то. Я написал про это под спойлером, васька сможет смотреть другие ссылки уменьшая число, а это как-то не комильфо. Я думаю 5-разрядного даже 16-ричного числа хватит чтобы нивелировать шанс перезаписи с лихвой, а ведь туда можно еще буков добавить. Да и вообще, можно просто сделать проверку на существование файла. А как пофиксить кривой рандом так никто и не сказал.
>>1149202 > А как пофиксить кривой рандом так никто и не сказал Все, я уже сам нагуглил, охуеть. Оказывается array_rand возвращает ключи, а не значения.
>>1149061 >В смысле увеличивать последовательность символов Возможно не совсем правильно выразился. Смотри. Первая ссылка будет такой: shrt.er/0, вторая shrt.er/1, потом цифры закончатся и ты переходишь на буквы: shrt.er/A shrt.er/B ... shrt.er/z
Потом добавляешь второй символ и всё заново:
shrt.er/00 shrt.er/01 ... shrt.er/zz
Ну и так далее. Я сам делал шортенер с телеграм ботом даже, со статистикой переходов по странам, времени и прочему, но это очень тупой проект, ибо сервисов дохуя и новый никому не встрался.
У пыхи есть будущее в ближайшие 2.5 года? Вопрос актуальный, т.к. учусь в Беларуси и попадаю на распределение, поменять место работы или стек не получится.
>>1149202 >В треде про быдлоязык. >Я думаю 5-разрядного даже 16-ричного числа хватит чтобы нивелировать шанс перезаписи с лихвой Поссал на лицо смачно.
Правильно я понимаю, что в современных реалиях лучше не брать yii как то, на чем можно написать хелоу-ворд для гитхаба, что бы было проще найти работу?
Так как в треде почему-то много вопросов про работу и мало про программирование, то я принес вам статью про то, как работает система повышения в Гугле, как там становятся миддлами и сеньорами:
>>1149481 значит что нельзя иметь доступ к базе под этим пользователем. Там же разгараничения могут быть что под каждую базу свой юзер выделен. Что бы если спиздят пароли от одного лендоса, то другие не положили заодно например.
> public function addNewRoom($number) { Здесь в номерах не указываются их параметры (цена, вместимость).
> public function settleGuest($room_id, $guest_id) { > $rooms[$room_id]->setGuest($guest); Зачем тут id? Где их брать? У нас же есть объекты. id нужны только для баз данных, тут можно обойтись без них.
Также, заселение придется сделать чуть сложнее. Нам ведь надо вести историю: кто, когда, где останавливался.
А так, начал в правильном направлении. Спрашивай, если что непонятно.
>>1148916 >почему он из массива только цифры берет, и вообще берет не 5? А ты из массива и не берёшь ничего, только рандомируешь его ключи, а не элементы массива. > берет не 5? Так счёт идет от нуля. 0, 1, 2, 3, 4, 5. То-есть 6 элементов. > isset это не совсем то, что мне нужно для обработки нажатия. Что мне нужно? Почему нет то?
>>1148917 Смирись, лучше Котерова никто книгу не написал. Остальные книги настолько плохи что даже для обучения не подходят. К тому-же спорить о стиле кода в 2018, когда всё форматируется под любой стандарт нажатием сочетания клавиш?
Нужно заходить в БД с логином и паролем. Если пользователей нет - с логином админа, но на продакшене желательно для каждого сайта создать своего пользователя с доступом только к одной базе данных.
Используй события вроде hover/mouseenter. На каждую ссылку ставить обработчик замучаешься, потому можно поставить один глобальный на документ с фильтром по классу/тегу ($.on). В случае наведения мыши показываем прелоадер, запускаем загрузку данных. Когда загрузятся - создаем абс. поз. относительно родителя див с нужным нам смещением и в него вставляем HTML код поста.
При уведении мыши все происходит в обратном порядке, див скрывается, загрузку можно отменять, если она началась.
> конкретного онклика нет? onclick - это атрибут элемента DOM. На сервере никакого DOM нет, никаких нажатий нет, на сервер просто приходит HTTP-запрос и никакого "онклика" быть в принципе не может.
После успешной обработки POST запроса и создания новой ссылки надо делать редирект, чтобы страница загрузилась методом GET. Это называется POST-Redirect-GET: https://ru.wikipedia.org/wiki/Post/Redirect/Get
Не надо создавать кучу PHP файлов. Ты скорее всего думаешь, что веб-сервер всегда ищет тот файл, который указан в URL. Но это можно настроить как угодно, например, чтобы всегда бы вызывался один и тот же скрипт index.php и уже в нем разбирался URL. Как именно это делать - зависит от используемого веб-сервера, в каждом по-разному. В апаче через htaccess и mod_rewrite, в встроенном в PHP веб-сервере через скрипт роутинга, в nginx через конфиг.
Обычно используют базу данных. Если неохота задействовать отдельную СУБД, можно использовать Sqlite, которая хранит таблицы в файлах.
При вставке в БД можно проверить, не занят ли нужный идентификатор, а также можно автоматически генерировать порядковые номера.
Если ты хочешь лучше научиться делать такие вещи, я советую посмотреть первый пост треда и задачу про студентов - в ней много комментариев и она учит как раз, как писать приложения с формами и таблицами.
А что значит "выбирался"? Просто select со списком документов не подойдет? Или тебе надо поле для загрузки файла? Изучи, какие поля есть в HTML формах.
Наверно имеет смысл для каждого треда делать свою папку - проще будет например удалять или архивировать или еще что-нибудь делать. Если несколько разделов, то можно еще для каждого раздела свою папку тоже.
Просто так куки угнать нельзя. Куки отдаются только тому сайту (домену), который их выставил. Но дальше начинаются интересные варианты.
Ну например, атака на DNS: злодей взламывает твой роутер (а китайские роутеры очень дырявы) и перехватывает DNS запросы, чтобы сайту example.com соответствовал бы их сервер и твой браузер бы отправлял куки туда. Защита: использование HTTPS, установка флага secure у кук, чтобы их не отдавало по HTTP.
Или социнженерия: отправляем письмо с просьбой посмотреть документ info.doc.____________.exe.
> Так же, хотелось бы узнать, есть ли такой способ кражи, при переходе на посторонний сайт. Нет при условии отсутствия уязвимостей в браузере и ОС.
> переход по незнакомым ссылкам чревато? Потому, что браузеры и ОС не идеальные и в них могут быть уязвимости, которые позволяют запустить вредоносный код на машине или обойти ограничения. Но если ты обновляешь браузер и ОС, не используешь флеш, Adobe Reader и ява-плагин и используешь браузер с печочницой (вроде Chrome), то вероятность этого не велика. Так как уязвимости такого уровня стоят десятки тыс. долл. и вряд ли кто-то ради протроянивания твоего пк будет столько тратить. Если ты конечно не связан с военными тайнами какими-нибудь.
Регулярно проводится конкурс pwn2own на взлом браузеров (запуск вредоносного кода при посещении сайта). Ты можешь по призовым выплатам оценить, насколько сложен взлом: https://habrahabr.ru/company/kingservers/blog/324480/
Часто ломают не сами браузеры, а плагины, в которых защита слабее: флеш много раз ломали, adobe reader, ява-плагин. Потому Гугл пытается поскорее вытеснить флеш и использует свой просмотрщик для PDF. Ломают через офисные приложения (Word, Excel). Так как их разработчики не выстраивают такую надежную защиту, как Гугл, а иногда делают откровенное решето (макросы в офисных приложениях). Также, были случаи, когда ломали браузер за счет уязвимости в виндовой библиотеке, отвечающей за вывод шрифтов - Хром по моему позже от нее отказался.
> Браузер Safari поддался участникам соревнования четыре раза, Firefox — один раз, Google Chrome взломать пытались, но не хватило времени. А раньше по моему взламывали.
> а так же рамещением фейковой формы, для залогинивания, что, на мой взгляд, совершенно бесполезно.
Вообще-то через фейковые формы входа в Гугл-аккаунт была взломана какая-то американская партия и они очень обиделись. Фишинг работает, и еще как. Потому что пароли довольно неудобная и ненадежная система, в адресную строку никто не смотрит, плюс браузеры пишут там "Надежный" при наличии HTTPS, вводя пользователя в заблуждение. Я сторонник аппаратных ключей, которые можно носить с собой. Хотя, конечно, их можно отобрать силой.
> Функции не обязаны быть определены до их использования, исключая тот случай, когда функции определяются условно, как это показано в двух последующих примерах.
Это такой подход, когда мы просим ОС начать выполнять операцию и не ждем, пока она завершится, а делаем в этом время другие вещи.
Желательно понимать что такое процессы, ядро ОС и тд. То есть изучить основы линукса и может быть сетевого программирования (Сокеты Беркли, TCP, UDP) не помешало бы, иначе можно так и не понять многое.
> https://ideone.com/sgoWlo Как-то многовато кода для такой задачи. Тяжело разбираться. Ответ верный, но решение можно сильно упростить.
Ну например, так:
- вычисляем баланс с добавлением процентов и коммиссии - определяем, сколько мы платим в этом месяце (используя min()/max()) и кладем в переменную - платим - если дошли до нуля - кредит выплачен
> https://ideone.com/c6Lwqo Вроде как работает, но есть одна проблема. Символы, которые ты используешь, я не очень хорошо знаю (да и ты наверно тоже) и есть вероятность, что где-то там ты мог использовать один и тот же символ для нескольких букв. Легко ведь не заметить. Можешь ли ты программно проверить - все ли символы уникальные или среди них есть 2 одинаковых?
Вообще, во втором решении можно было сделать цикл из 2 шагов, а после него - отдельно сделать вывод третьей строки. В цикл надо помещать только действия, которые повторяются, а последняя строка не повторяется.
Сложно выглядит код наверно из-за длинных выражений вроде $line[$i] = $word1[array_rand($word1) ]....
> Почитал про джойны, примеры работают, а как их к этой базе применить не доходит. Если тебе нужно объединить в одну строчку данные из 2 таблиц или искать что-то в 2 таблицах сразу - используешь джойн. Джойн по умолчанию создает декартово произведение строчек (очень много строк), потому обычно сразу же в нем пишут условие отбора строчек.
Почти все задачи на SQL решаются именно через джойн + иногда группировка.
> Еще внешние ключи ну никак не могу понять, Если в таблице стоит ссылка на ячейку другой таблицы, то это внешний ключ. Вот и все. Где и как ставится внешний ключ, зависит от типа связи. Их там всего несколько - 1:1, 1:M и M:N. И еще вариации, например, бывает связь 1:M, а бывает [0, 1]:M. То есть левая сущность может быть обязательной, а может и нет.
Ты определяешь тип связи между сущностями, и исходя из этого, создаешь внешние ключи.
По схеме БД: процедуры (в receptions) придется в будущем всего выносить в отдельную таблицу. У них могут быть свои какие-то атрибуты, цены и тд.
Также, у тебя есть избыточные связи. Например, в receptions приписан owner. Если pay_ticket привязан к reception, то owner в нем не лишний ли? Да и если еще подумать, может быть счет логично выписывать на животное, а не на конкретного владельца? Их ведь там несколько.
То же самое касается поля employee. Хотя конечно бухгалтерия дело сложное, и может там счет выписывает другой сотрудник?
Насчет связи между receptions и pets - а не может хозяин придти без животного? На консультацию например? Это учтено?
Насчет связи между receptions и pay_tickets - мне кажется, должно быть связь 1 receptions - (0..N) pay_tickets. То есть по итогам приема может быть выписано сколько угодно счетов (инвойсов?).
Связь между prescriptions и pay_tickets - я не уверен, что она нужна. Разве выдача рецепта как-то связана с оплатой? Вполне возможно, что врач решил выписать рецепт бесплатно.
Насчет правой части - где учет медикаментов - я не очень понял, что там к чему. Почему и как запись в журнале расхода медикаментов связана с записью в журнале прихода.
> Еще внешние ключи ну никак не могу понять, я вот их наставил тут, но походу немного далеко уехал с ними. Ты определеяешь связи между сущностями, и исходя из них ставишь внешние ключи. То есть сначала определи, что с чем связано и как.
> Почитал про джойны, примеры работают, а как их к этой базе применить не доходит. Ну простой пример: вывести дату приема и имя животного на приеме:
SELECT r.date, p.name FROM receptions r JOIN pets p ON p.id = r.pet;
У меня есть подозрение, что во-первых, не везде это работает, во-вторых, затраты времени на запаковку могут быть больше чем затраты на передачу данных. Плюс, это потом распаковывать надо. Плюс, многие типы файлов - картинки, аудио, видео - не пакуются дальше, они и так сжатые.
У той же mega.nz "толстый" фронтенд и она субъективно очень тормозная и сильно грузит процессор.
>>1149526 это может и так, но ты ответь на вопрос, ты в конторе работаешь? пишешь поддерживаемый код? есть код-ревью? у вас такой код, который пишет котеров, пропустили бы?
речь не про psr. просто в любой нормальной фирме за такой код тебя сразу отправят в бухгалтерию забирать документы.
>>1149588 >в любой нормальной фирме за такой код тебя сразу отправят в бухгалтерию забирать документы. За какой такой то? Почему Котерова не попросили забрать документы тогда? Он книги пишет, но видимо анону с двачей виднее каким должен быть код конечно же. К тому-же он обьясняет и учит как применять то или иное, а не говорит мол пиши как я и только как я. У меня например не возникло сложностей интерпретировать его код. Почему у тебя такие сложности должны возникнуть?
>>1149511 >Зачем тут id? Я вот тут запнулся, мне надо придумать какой нибудь хэш для комнаты(он же идентификатор), но по идее идентификатор комнаты ее номер. А вот по поводу гостя, какой идентификатор добавить? Если сделать идентификатором пользователя имя и фамилию и использовать как ключ для доступа поля в массиве?
Историю клиента я планирую хранить отдельно для номера, отдельно для клиента. Хотя может это не имеет смысла, потому что история заселения это сущность отеля, и хранить надо в отеле? Например создать класс HotelLog, который будет содержать в себе информацию о дате заселения, номере и посетителе. А в классе отель создать приватный параметр массив содержащий в себе эти логи. Какой из этих вариантов лучше выбрать?
Еще мне очень интересно как на это все добавить тестов или вообще в идеале делать по тдд, если это конечно возможно?
>>1149588 >тебя сразу отправят в бухгалтерию забирать документы. Брр, от тебя повеяло совком каким то, ты на заводе каком то работаешь наверно или тебе лет 50, угадал?
>>1149589 >но видимо анону с двачей виднее каким должен быть код конечно же видимо да, лол. любой анон, имеющий опыт написания промышленного поддерживаемого кода, будет более компетентным, чем котеров с его миллионом книг по пхп4.
ты так говоришь, как будто для тебя является новостью, что часто люди, не добившиеся успехов в программировании, начинают стричь бабло с новичков, называя это обучением. котеров выезжает исключительно на том, что он начинал первым.
опять же, я на самом деле не против таких советов. чем больше людей будут учиться по котерову, тем проще будет вменяемым программистам устроиться на нормальную работу.
>>1149602 нет, контора в дс, удаленка, просто официальное трудоустройство. ты когда начнешь работать, узнаешь, как происходит процесс трудоустройства и тогда все встанет на свои места.
>>1149611 Короче ответов от тебя нет вообще никаких. Конкретики нет, одна обобщённая критика, причём ещё и PHP4, хотя у Котерова по 7 версии книга есть таки. >любой анон, имеющий опыт написания промышленного поддерживаемого кода, будет более компетентным, чем котеров с его миллионом книг по пхп4. Окей спорить не буду. Назови Другую книгу по PHP7?
>>1149616 >Конкретики нет я в прошлых тредах (98 или 97) подробно разбирал какой-то кусок его кода примеров к какой-то книге как раз по пхп7. немного лень искать, можешь это сделать сам по слову "котеров" в архиваче
>причём ещё и PHP4, хотя у Котерова по 7 версии книга есть таки это ирония была. у него книги по пхп7, а код как на пхп4 (опять же, я приводил примеры с каким-то минимальным разбором почему так неправильно и как надо)
>Назови Другую книгу по PHP7 книг "с нуля" нет. к сожалению, из-за исторических особенностей развития пхп, на нем основная масса книг учат писать html и sql-запросы в одном файле, что раньше считалось нормальным (и за что пхп справделиво считали языком веб-макак). язык и сообщество развились, но книги почему-то не подвезли.
>>1149552 > post-redirect-get Спасибо, но я уже пофиксил это с помощью ajax'a. Теперь-то и выглядит это все не так костыльно, ты лично посылаешь запрос скрипту на серв, и лично получаешь и обрабатываешь от него ответ.
>>1149525 Счет идет от нуля, а параметр отвечает за количество. Впрочем, неважно, когда я переделал код под возвращаемый массив с индексами, все заработало как надо. > почему нет В гугле написано, насколько я помню, что это проверяет, объявлена ли переменная. Не, ну оно и подходит, в принципе.
>>1149523 Быдлоязык - потому что в него вкатывается всякое быдло ради 300кк/нсек(особенно в треде на мейлаче), а еще потому, что у меня бомбануло, он слишком не похож на другие нормальные языки, где берешь, и без задней мысли делаешь, а здесь какой-то пердолинг. И еще все эти долларчики, блядь, аж трясет от них. Были бы халявные хосты с питоном или нодой, я бы туда убежал за милую душу.
>>1149647 >потому что в него вкатывается всякое быдло ради 300кк/нсек исторически так сложилось, что да. например, ты
>он слишком не похож на другие нормальные языки конкретнее, пожалуйста. можно недостатки языка по пунктам? про долларчики это не аргумент, а вкусовщина.
>Были бы халявные хосты с питоном или нодой шта? 5 долларов в месяц за свой впс с нужным окружением для программиста на нормальных языках слишком серьезная сумма?
>>1149647 Похоже, что это почётное звание перешло к js. В моём окружении таким языком вообще Java является. Но стартанул я не очень, потом перескочил на что было. К языку нет претензий - седьмой пых очень приятный. белорус-на-распреде
Ну впрочем старожилов веба этим не удивишь, "фронтенд специалисты" постоянно радуют нас своими нездоровыми придумками.
Критикуя - предлагай, скажет читатель. Предлагаю: не можете сделать хорошо, делайте просто черный текст на белом фоне. Вы удивитесь, насколько это прекрасный дизайн.
>>1149825 >error_reporting Вот эта претензия меня всегда смущала, потому-что в других языках если я получаю ошибку, - по факту я либо кладу весь сайт! Либо весь сервис! ДЛЯ ВСЕХ ЮЗЕРОВ! (Привет ASP). Для тех кто в танке. Представьте что у одного юзера вкмылору произошла ошибка получения доступа к бд например. И из-за этого ВК лёг у всех. Удобно да? Поэтому говорить о том что это минус ну ооооочень странно. Да и настраивать error_reporting учат раньше чем Hello world писать.
>>1149865 >Сам он настолько экзотичный, что я скорее отнес бы php к эзотерическим языкам программирования и поставил где-нибудь рядом с HOtMEfSPRIbNG. Дальше можно не читать. Как вообще можно воспринимать человека всерьёз, если он по факту не знаком с целым семейством языков? Я вообще в шоке. Синтаксис похож вообще на всё что я знаю, разьве что кроме JS. И говорить что PHP экзотический? Либо толстота, либо крайне скудный опыт в ЯП.
>>1149839 Руби помер 10 месяцев как. Да и вообще язык одного фрэймворка (Rails). Который за всю историю своего развития получил тонны похвал, тонны хвалебных статей, тонны упоминаний в IT сообществе и вообще язык хайп и чуть ли не идеальный язык программирования, но при этом худо бедно можно наскрести 2-3 приложения которые на нём действительно написаны. Сорян за оффтоп. ПРосто я реально не понимаю зачем нужен руби.
>>1149905 Летом проходили сборы всяких хакатонов, и прочих набегов где обсуждаются языки программирования и прочее. Выяснилось что на мероприятия с руби в залах собирается по 5-10 человек, редко 40. Когда на аналогичные мероприятия собираются 1000-1200. Ну как-бы "At this moment Jonny knew - he fucked up."
В PHP много плохого, это да. Синтаксис страшный, да. Работа с ошибками сломана безнадежно. Но есть и хорошее: тайп-хинты (ну-ка, покажите мне тайп-хинты в Руби, Питоне или JS), классы как в Яве (покажите мне классы в JS). Есть HHVM. В отличие от JS есть поддержка тредов.
Вообще, у разных языков свои сильные и слабые стороны. Мне нравится в плане возможностей Java и C#, они с типизацией, с классами и компилируются (хорошая производительность). Но в плане установки и использования они не такие простые как PHP, и Симфони там нету.
Плюсами PHP считается наличие большого числа разных CMS например. Тот же Вордпресс. Покажите мне вордпресс на JS.
Также, PHP очень просто в использовании. Пишешь файл 1.php, запускаешь встроенный веб-сервер - страница готова. Попробуйте сделать то же в Руби, Питоне, JS без поиска нужных библиотек.
> 1. Настройка и установка php - это весьма своеобразная история.
Набрать команду apt-get install php - это своеобразная история? Давайте посмотрим на Питон, где инструкция по установке почти любого приложения начинается с установки одного пакетного менеджера через другой. И с освоения virtualenv.
> То, где может искаться php.ini - это целый здоровый список в документации с целой кучей вариантов в зависимости от ОС и сервера.
Можно набрать php -i и посмотреть.
> Сюда же идёт тот факт, что php всегда намертво связано с веб-сервером и не может толком использоваться вне его
Может, хотя не очень понятно, зачем.
> что интерпретатор в общем случае живет в рамках одного http запроса.
И это очень полезная фича. Вообще, PHP можно запускать так, чтобы он обрабатывал много запросов не перезапускаясь (как Руби, Питон итд), и экономить на инициализации приложения, но тут есть свои подвохи. Ну например, я читал, что у людей в Руби утекала память и они не нашли ничего лучше как по крону прибивать и перезапускать приложение.
> Зачем-то в динамический язык скопировали ООП из джавы. > Зачем, почему, непонятно
Потому, что в Яве прекрасный ООП, в отличие от других языков.
> Долгое время, конечно же, не было пакетного менеджера PEAR был.
> Безопасность среднего поделия на php ниже плинтуса, Виноват ли в этом язык?
Ну и автор не назвал, какой язык он считает хорошим. Не беда; какой бы он не назвал, у меня есть, что ответить: https://habrahabr.ru/post/315152/
>>1149921 > Если произошла ошибка - надо прекращать обработку запроса и отдавать 5xx. В том то и дело что ту не можешь узнать произошла ошибка или нет. Даже блоки try catch иногда не отрабатывают ошибку. >Также, весь сайт не упадет, а ошибку получит только тот, у кого она произошла. У тебя явно мало опыта в таких проектах на других языках. Пример ASP показывает что падает у всех, хотя ASP и старенький по современным меркам, но тем не мение он как раз из вот этой концепции. >Скрытие ошибок ни к чему хорошему не приведет, их просто будет труднее заметить. Что значит труднее заметить? На продакшне ты вообще не должен их замечать. И вообще вываливать тонны ошибок на юзера - как по мне КРАЙНЕ странная практика. На тестовом сервере ты можешь выставить ошибки и отловить всё что тебе угодно. Опять же на ASP выводятся тонны ошибок если где-то в SQL запросе что-то пошло не так или вообще по любой другой причине, в результате я как програмист разработчик который может это исправить может и радубсь, но 5000 юзеров сайта недоумевают зачем им вообще знать что там какой-то SQL запрос неправильный? Сделать то они ничего с этим не могут.
>>1149925 >они не нашли ничего лучше как по крону прибивать и перезапускать приложение. Забавно что у Node.js точно также обстоят дела. Хотя это было в прошлом году, может сейчас есть что-то новое.
>>1149925 >И это очень полезная фича. Языки с корректно сделанной сборкой мусора и рантаймом (JVM и CLR) умеют жить очень в рамках одного процесса. Возможно, автор, как раз на них и ориентировался.
>Яве прекрасный ООП, Но только он завязан на статическую типизацию, которой в ПХП толком не было.
>>1149926 Опять-таки у приложений на той же JVM или CLR с обработкой ошибок всё хорошо и там как раз в веб приложениях обычно падает только обработчик конкретного запроса.
Вообще, по идее утечки памяти можно находить. Для языка Си, например, есть Valgrind, думаю, что и для JS мог бы быть инструмент, но его никто не написал. Для PHP, кстати, тоже.
Вот кстати, отладка - отдельная вещь. Насколько я знаю, для PHP есть отладчики, увы, только в виде тяжелых IDE вроде PHPStorm или Netbeans, а для Node.JS или Go - вообще нету. То же касается профайлинга, у нас хотя бы xdebug есть.
В PHP есть сборка мусора (хотя ее нет для нативных расширений). Утечки памяти в долгоживущих приложениях происходят не из-за этого.
Условно говоря, если у тебя где-то в коде есть глобальная переменная-массив и ты в нее добавляешь элементы и никогда не удаляешь, то будет утечка памяти. И найти это без специальных инструментов (отслеживающих аллокации/деаллокации памяти) сложно. А их для многих языков нет. А вот кстати для взрослых энтерпрайзных языков вроде Ява инструментов написано много, хотя и не все бесплатные.
> Но только он завязан на статическую типизацию, которой в ПХП толком не было.
Ты все понял неправильно. Правильная система обработки ошибок - это исключения. Не должно быть такого, что произошла ошибка и программа продолжается. На пользователя их никто не вываливает, он получает 503 страницу и ошибка фиксируется в лог.
> В том то и дело что ту не можешь узнать произошла ошибка или нет. Даже блоки try catch иногда не отрабатывают ошибку.
Я как раз могу. Все фиксируется и логгируется. Даже падения процесса PHP можно фиксировать и логгировать, если запускать под супервизором например (ну и php-fpm их тоже по моему отслеживает).
> Пример ASP показывает что падает у всех, хотя ASP и старенький по современным меркам, но тем не мение он как раз из вот этой концепции.
Может быть у вас что-то было неправильно настроено.
> но 5000 юзеров сайта недоумевают зачем им вообще знать что там какой-то SQL запрос неправильный? Сделать то они ничего с этим не могут. Именно потому им надо показывать не текст ошибки, а страницу 503. "тонны ошибок" там быть не может, так как обработка запроса прекращается на первой же ошибке и следовательно больше одной ошибки за раз быть вообще не может.
>>1149941 >Я как раз могу. Все фиксируется и логгируется. Даже падения процесса PHP можно фиксировать и логгировать, если запускать под супервизором например (ну и php-fpm их тоже по моему отслеживает). Ну так-то да, вот только error_reporting довольно далеко от этого. То-есть претензия была к нему, и к тому что отслеживать ошибки трудно. А в итоге то всё-равно лезь в логи и смотри. Тогда причём тут error_reporting? Непонятно. >Может быть у вас что-то было неправильно настроено. Это весьма спорно. Поскольку настраивали всё аж спецы из Американского офиса Майкрософта. Ну и я сам имел около 5 проектов на ASP. И был весьма удивлён таким вот поведением.
Логи это лишь первичные данные. Ты с ними можешь потом делать что угодно, в том числе например пересылать данные из них в какую-то систему мониторинга.
> Тогда причём тут error_reporting? При том, что это опция, позволяющая игнорировать отдельные виды ошибок и она вредная.
Что же тут может быть непонятного? Если у тебя произошла любая ошибка или предупреждение, ты останавливаешь скрипт, выдаешь пишешь ошибку в лог и выдаешь пользователю страницу 503.
И очень плохо, что в PHP так не сделано по умолчанию.
Не знаю где написать, напишу здесь. Скиньте пожалуйста пример готового сайта, с фронт-эндом, бэк-эндом и всем вот этим. Интересует конкретно структура файлов и папок в нем.
>>1150169 Эм... как бы тебе сказать. Я не понимаю зачем тебе структура файлов и папок на сайте, потому-что банально она может быть любой. Ну тоесть вообще любой. От банального все файлы в одной папке в корне, до каждый файл в своей подпапке. А некоторые JS вообще умудряются разнести функционал по 3-50 доменам! Так что структура папок и файлов тебе вообще не скажут ничего.
>>1150203 > Так что структура папок и файлов тебе вообще не скажут ничего Так мне и не нужно, чтобы они мне что-то говорили. Просто я поехавший перфекционист, и все должно быть максимально упорядочено. Сейчас вот пилю некое подобие сайта, накатал 1 индекс страницу, другие уже так как обмазался пыхой планирую загружать в нее из БД, так вот есть этот индекс, рядом с ним лежит папка res, и в ней все сразу: и жс, и сасс/сиэсэс, шрифты, картинки, либы, теперь там еще и пыха, которая вообще не из этой тарелки. Типа, я бы мог конечно навасянить себе свою личную структуру, но зачем придумывать велосипед.
Подскажите немного с теорией. Повторяющийся парсинг популярного ресурса, с мультикурлом, группиповкой данных и извлечением контента проблем нет, интересуют именно способы обхода блокировок. Насколько я понимаю спуфать IP на уровне языка я не могу, максимум только поменять прокси/юзерагента на лету с помощью angry/rolling curl. Я вот думал может написать сервис-парсер, может даже на nodejs, который будет заниматься непосредственно пирсингом и наполнением промежуточной бд и отправкой данных в главное хранилище получая обратно следующий список страниц. Можно будет поднять любое количество нод, так как главный сервер будет решать какая нода что будет парсить. Интересно следующее, представляют ли облачные сервисы апи для поднятия/отключения ноды или каким образом это можно авторизировать? Буду благодарен за любую идею или информацию
>что значит this.request в данном контексте? создается переменная request в которую записывается что? >https://github.com/dorsha/login-modal-react-redux/blob/master/src/util/api.js#L21 Функция checkStatus вызывается с привязанным контекстом с помощью checkStatus.bind(...), новой созданной переменной request устанавливается значение одноименной переменной из контекста.
>что тут происходит? >https://github.com/dorsha/login-modal-react-redux/blob/master/src/util/api.js#L23 Очередь с рекурсивными промисами с кэррингом и привязкой контекста. Что может быть проще? Новый request получает ссылку на вызов функций resolve и reject в созданном Promise, чтобы в дальнейшем можно было их вызвать в другом месте (в очереди будет запущен request, который является ф-ей postPut/get с привязаным контекстом). Сам промис возвращается как результат выполнения checkStatus, в то место где был вызван, и после запуска resolve или reject (в очереди) промис получит соответствующий статус и результат запроса (postPut/get) отправится в обработчик.
>>1150518 > модалка для логина на реакте > Очередь с рекурсивными промисами с кэррингом и привязкой контекста. Вспомнился пик. Мне кажется, что раз задача такая простая, а код настолько сложный, то ему не место в продакшене. В проект будут приходить новые люди, им тоже нужно будет ломать голову над таким кодом?
>>1150563 Для меня весь js такой, слишком запутанный. В защиту конкретно этого примера скажу, что модалка появляется автоматически, как только сервер ответил кодом 401 на любой запрос, и этот запрос будет отправлен повторно после того, как юзер залогинится. Я смотрел другие варианты реализации очереди с реквестами, они не намного проще. Хотя наверное, можно избавиться от рекурсии, кэрринга и привязки контекста. Но кода будет больше.
>>1150518 То чувство, когда ванила JS написанная на коленке с тем-же фугкционалом - получается примерно в 1000 раз проще и понятней чем вот это вот всё. Зато реакт, модно стильно молождёжно.
В задаче про файлообменник можно проигрывание видео/аудио сделать через html5 теги без всяких video.js или других расширений? И какие у этого будут минусы?
Подскажите, пожалуйста, где можно почитать про реализацию mvc подхода на php в простых примерах. Единственное, что из похожего нашел - https://habrahabr.ru/post/150267/, но тут комменты какие-то противоречивые. Весь тостер уже перерыл, везде в духе пикрлейтеда. Читаю сейчас Зандстру, попутно пилю проектик, но в итоге один хуй получается какая-то мешанина из классов и процедурного кода.
>>1149825 >22. Долгое время, конечно же, не было пакетного менеджера, но в итоге добро всё же победило. Я вот понимаю что пакетный менеджер - это круто в какой-нибудь JS, где разрабы сами себе кучу говна наложили, и теперь чтобы например автообновление в браузере врубить - надо ставить npm, потом node, потом gulp, И ТОЛЬКО ПОТОМ расширение для gulp. Когда я ставил расширение для PHP, всё что я сделал - копирнул файлы и в php.ini прописал параметры. Стоит ли ради этого делать пакетный менеджер - хз. Вообще кто из вас думает что для PHP он впринципе нужен то?
притом в реальных проектах я часто вижу чтонибудь типа SmsProvider, который по сути занимается тем, что по АПИ стучится к оператору, дает ему команду отправить смс и получает ответ, который потом например логирует.
где тут абстрактная фабрика? и вообще подобных провайдеров я кучу видел, они все больше похожи на Service.
>>1151079 >Когда я ставил расширение для PHP, всё что я сделал - копирнул файлы и в php.ini прописал параметры ты говоришь о менеджере экстеншнов видимо (pecl)? не каждый экстеншн ты можешь просто копирнуть и вставить в ини файл, некоторые надо собирать и компилировать (пример - xdebug). pecl делает это все за тебя и очень экономит время
Давай подумаем. Ты когда-нибудь на сайтах жал лайк, оставлял комментарий через виджет ВК, регистрировался или входил на сайт через аккаунт ВК? Я имею в виду, не на известных сайтах вроде Хабра, а на малоизвестных?
А так, ты мог бы сам попробовать изучить, как оно работает. Открой отладчик (Ctrl + shift + I) в браузере на вкладке Network и перезагрузи сайт. Там ты увидишь запросы к серверу vboro.de и соответственно можешь попробовать изучить эти скрипты. И может даже увидишь, как определеяются твои данные.
Я не пользуюсь ВК потому мне понять трудно, как оно работает.
Твой аккаунт они могли узнать разными способами:
- ты мог на каком-то сайте использовать любой виджет ВК (лайки, комментарии, вход через ВК) и они слили твои данные отслеживающему сервису - они могли использовать кликджекинг: это когда под курсор тебе подводится прозрачный виджет ВК (например, кнопка лайка или вступления в группу) и ты на него нажимаешь - может быть, ты использовал какое-то приложение в ВК или игру и она слила твои данные сторонним сайтам
Отчаиваться не стоит. Скорее всего эти данные можно удалить, полностью очистив куки и прочую информацию в браузере (Ctrl + Shift + Del). Если это не поможет, значит, они привязали твои данные к IP адресу и user-agent. IP адреса обычно со временем меняются, если у тебюя динамический IP, а user-agent меняется при смене или обновлении браузера.
Также, есть еще вариант, что они не знают твое имя, а просто показывают тебе обрезанный кусок какого-то виджета ВК в ифрейме, где оно выводится, но это менее вероятно.
>>1151091 Провайдером обычно просто называют класс, который что-то предоставляет. Лучше называть классы исходя из их ответственности. В противном случае получится пикрил. Есть ещё полезная статья: https://habrahabr.ru/post/153225/ В Yii2 например есть DataProviderInterface, который предоставляет единый интерфейс для всяких виджетов: http://www.yiiframework.com/doc-2.0/yii-data-dataproviderinterface.html А его уже имлементят ElasticSearch provider, Sphinx Provider, Array Provider, ОткудаУгодноProvider
> SmsProvider, который по сути занимается тем, что по АПИ стучится к оператору, дает ему команду отправить смс и получает ответ, который потом например логирует.
Ну и такой класс правильнее назвать SmsTransport (по аналогии с email транспортами в swiftmailer) или может быть даже SmsSender. Такое название лучше описывает назначение класса.
>>1151079 Composer - лучшее, что произошло с PHP за последнее время, есть уйма статьей в сети объясняющих почему. Советую освоить, без него будет сложно обновлять зависимости, будут конфликты между разными зависимостями и уйма других проблем. Без Composer путь в серьёзную разработку закрыт.
>>1151090 PHP - отличный выбор, я использовал фреймворк BotMan, который позиционирует себя как кросс-платформенный: https://botman.io/
>>1151106 >Также, есть еще вариант, что они не знают твое имя, а просто показывают тебе обрезанный кусок какого-то виджета ВК в ифрейме, где оно выводится, но это менее вероятно. Это какраз-таки единственный возможный вариант
Потому что эти сайты могут сливать твои данные на сторону. Ну и еще возможен кликджекинг, я точно знаю что некоторые компании использовали его чтобы потом связываться с покупателями, которые пришли на сайт, но по каким-то причинам не произвели покупку.
Можно кстати для соцсетей завести отдельный браузер.
У меня запущен на локалхосте сервер, слушающий порт 8080 по https
Из php c помощью curl я к нему обращаюсь. CURLOPT_SSL_VERIFYPEER установлено в false.
Если я вызываю php-шный скрипт, в котором curl-запрос через браузер, apache, то все работает. А если пытаюсь вызвать этот скрипт через консоль - "php path/to/script.php", то curl мне выдает ошибку "Unknown SSL protocol error in connection to path.to.server:port".
Причем если я из консоли самим curl-ом пытаюсь подключиться, то все тоже работает "curl -k path.to.server:port"
Подскажите, пожалуйста, хоть в каком направлении искать решение этой проблемы, уже все перепробовал, ничего не работает.
>Ну и такой класс правильнее назвать SmsTransport мне тоже такое название кажется более логичным, но менять пока нельзя, я над этим проектом работаю 3 дня.
>>1151090 У тебя какая идея для бота? Я вот написал простейшего, наполовину спиздив код с hello-bot'a. Типа пишешь ему сообщение, а он тебе рандом пик с гелбуры в ответочку. Хотел бы игрового бота запилить, что-то типа угадайки. Но я неебу как его отлаживать можно через эти веб-хуки. А на локал-хосте не смог поднять.
Поцаны, устроился в прошлом году в конторку в своем миллионнике. Недавно дали ковырять вордпресс и вот чот непонимаю я этот вордпрес, уже месяц ковыряю кое как исправляю мелкие косяки по верстке или там по коду. Но досихпор нихуя понимания нету. Все хаотично всезде все по разному лежит, куча функций, который хуй пойми как связаны между собой. Хз для моего милионника плотят неплохо, но яж нихуя не научусь ничему верно? За месяц заебало прямо тошнит, все эти хуки хуюки, собственнописные плагины обоссаные из кучи рандомных функций, рандомно все как то, может вообще бросить нахуй кодинг, раз единственно чо нашел в мухосрани это вротпрес.
>>1151350 Я другой анон и мне кажется удобнее подключать через исходники. Все эти менеджеры усложняют простые вещи. Если бы ты вынужнен был каждый день по 10 проектов разворачивать, менеджер проектов пригодился, когда у тебя новый проект раз в полгода, оно только мешает.
>>1151353 Ну там apt-get и подобные помогают. Если чего то нету, собирать из исходников боль и страдание. Вот где уж реально нужны менеджеры пакетов, там где просто нужно побыстрому закинуть бинарники и настроить окружения.
Поясните пожалуйста за многостраничные сайты с не изменяющимися хэдерами@навбарами. То есть вообще все сайты. Как они вообще делаются? Очевидный вариант - это копипаст кода с одной страницы на другую и замена динамической части. Но это явно не тот вариант, который используется на нормальных сайтах. Знаю только, что вот это вот все через пхп реализуется.
>>1151616 Обычно используют layout'ы (я хз как на русском правильно звучит), обычно это header + footer и динамический body, либо контент внутри body. То-есть при формировании любой страницы генерируется контент который вставляется в layout. Пример layout в yii2: https://github.com/yiisoft/yii2-app-basic/blob/master/views/layouts/main.php
А не может быть такого, что ты просто в композере не разобрался (тем более что там дока на английском)?
Вот мне просто интересно, что может быть проще, чем дописать одну строку (!) в composer.json, или набрать команду composer require? То есть по твоему проще - это идти искать библиотеку, скачивать архив, распаковывать, читать, что ей нужно, идти скачивать зависимости, распаковывать, копировать, потом настраивать автозагрузку (библиотека сама себя не загрузит)? Что-то мне так не кажется.
Также, в случае с менеджером пакетов обновление происходит проще. Также, это позволяет не хранить в репозитории сторонний код (и защищает от любителей его править).
Да и возьми тот же Андроид. Никто там вручную файлы не скачивает, ставятся приложения через репозиторий и менеджер пакетов (Google Play).
На локалхосте можно вроде использовать бота, если использовать не хуки (когда сервер к тебе коннектится), а самому раз в N секунд коннектиться к серверу и забирать новые сообщения.
> Если я вызываю php-шный скрипт, в котором curl-запрос через браузер, apache, то все работает. > А если пытаюсь вызвать этот скрипт через консоль - > "php path/to/script.php", то curl мне выдает ошибку > "Unknown SSL protocol error in connection to path.to.server:port".
У тебя может использоваться разная конфигурация при работе с веб-сервером и в командной строке. С помощью команды phpinfo() (или php -i в ком. строке) проверь, какой файл конфига используется. Какие расширения установлены, включено ли расширение openssl.
Сравни параметры расширения curl в обоих случаях в phpinfo().
Также, может быть там различаются переменные окружения, влияющие на OpenSSL (это будет видно в phpinfo).
Запускать бота надо скорее всего в командной строке, а не через Апач. Нужно чтобы хостинг поддерживал ssh-доступ и возможность прописать произвольные команды в автозапуск, а значит, тебе нужен не хостинг, а VPS.
Пакетные менеджеры это как раз правильно. Почему я должен руками скачивать и копировать какие-то библиотеки, искать их зависимости, ставить их? Пусть это все ставится одной командой.
Как удобно все сделано в Дебиане, где программы ставятся через apt-get или через их стор. Не то что винда, где надо что-то качать, потом отключать галочки для установки троянов от яндекса и мейл ру. В дебиане к пользователю относятся как к человеку, а не к продукту.
> надо ставить npm, потом node, потом gulp, Вообще-то npm идет в комплекте с нодой. Надо ставить ноду, и если все настроено правильно и есть файл package.json, то gulp с расширениями ставится одной командой npm install. Куда проще?
> Когда я ставил расширение для PHP, всё что я сделал - копирнул файлы и в php.ini прописал параметры Не все расширения есть в виде dll, а под линукс все ставится либо через пакетный менеджер ОС, либо через pecl.
> Стоит ли ради этого делать пакетный менеджер Конечно, стоит. Не руками же расширения компилировать.
video.js это просто обертка, которая вставляет в страницу либо тег video, либо флеш-плеер в зависимости от формата файла и версии браузера. Так что разницы нет.
Если ты используешь теги audio/video напрямую, то высока вероятность, что многие форматы не будут воспроизводиться, так как браузеры поддерживают ограниченное число форматов. Форматов мало, потому большинство файлов воспроизводиться не будут. В комментариях к задаче это ведь описано и даны ссылки на MDN, где перечислены форматы: https://gist.github.com/codedokode/9424217#Информация-о-файле
Можно сделать по-простому, но если тебе захочется, чтобы любые форматы вопроизводились, то придется заморачиваться с перекодированием в поддерживаемые форматы. Это довольно сложно.
Вообще, у меня тоже вопросы к коду появляются, например:
> function checkStatus(response) { > var quiet = this.quiet; checkStatus это же не метод объекта, что тут значит this? Оказывается, если поискать, то ниже можно увидеть:
Это конечно запутывание кода. Что мешает опции явно передать в аргументы либо сделать настоящий объект RequestOptions? Где это видано, чтобы аргументы функции передавались через привязку объекта к this?
Далее, из промиса извлекаются коллбеки resolve/reject и записываются куда-то в объект request (который, если присмотреться, является функцией: postPut.bind(...)). Это конечно тоже запутывает код, так как очень трудно понять, куда они потом передаются, что с ними делается. Что мешает их обычным способом, например, через аргументы, передавать?
Не, по моему с точки зрения читабельности это плохой код. В нем сложно разобраться и легко допустить ошибку. Я сильно сомневаюсь в адекватности того, кто его писал.
> export function setStore(s) { Вот это тоже какая-то извращенная идея, они модуль используют как объект. Если вам нужен объект, почему не сделать класс?
Хуже того, это все неочевидно и никак не документировано. Мы должны как-то догадаться, что сначала надо вызывать setStore(), а только потом можно вызывать другие функции из модуля.
Такое ощущение, что для автора JS - первый язык и он просто не знает, как те или иные вещи принято делать и изобретает какие-то свои странные подходы.
Также, я не уверен, что вообще имеет смысл делать показ окон через react. А тем более, сохранение отложенных запросов в store. Очень странный выбор, по моему человеку просто принципиально все делать на реакте, даже если это усложняет код.
Тут сразу видны проблемы. Например, в свойствах Room:
> private $arrivalDate; > private $countOfGuests; Никак не учтено, что вообще-то одну комнату можно забронировать несколько раз - на разные даты. Бронь - это тоже объект вообще-то.
> private $guests = array("firstName" => array(), "lastName" => array()); Ты тут пытаешься вместо того, чтобы использовать объект Гость, имитировать его с помощью массива.
> private $isFree = TRUE; Это свойство довольно неудачное, так как занятость номера зависит от даты - в одни дни он свободен, в другие занят.
> public function changeIsFtee():void Это неудачная функция, так как ее результат зависит от предыдущего значения занятости. Лучше явно передавать значение true/false в аргументы. Тогда будет очевидно, какое значение записывается в поле при вызове.
В общем, логичнее сделать так: сделать объект Бронь и добавлять Бронь к Номеру. А у тебя вместо этого какие-то разбросанные по отдельным полям не связанные друг с другом данные. Это все усложняет, плюс появляется шанс, что ты где-то изменишь одно поле и забудешь про другое.
> class Hotel > public function addGuest(string $firstName, string $lastName): void Непонятно, куда эта функция добавляет Гостя и зачем. Она ведь ничего не возвращает. Да и что это за список гостей? Это все, кто останавливались в Гостнице? Кто бронировал? Кто собирался бронировать, но передумал?
> public function getRoom(int $numberOfRoom): Room Это неудачная функция, так как непонятно, где брать $numberOfRoom.
> public function getGuest(string $firstName, string $lastName): Guest Это неудачная функция. Зачем нужно искать объект по его свойствам, если объект сам по себе уникален и обладает идентичностью? Зачем сначала вызывать addGuest, а потом искать его по имени/фамилии, если можно сразу возвращать объект Guest из функции addGuest? Или вообще создать через new?
> private $receipts = array("date" => array(), "money" => array()); Опять, имитация объекта с помощью массива.
> class Guest > public function addVisitedRoom(int $numberOfRoom): void Зачем добавлять сюда порядковый номер комера? Он ведь в теории еще и поменяться может при удалении номера например. Если и добавлять, то сам объект Room, а не его номер.
> class Registration Многие методы отсюда можно было бы перенести в Гостиницу
> if($hotel->getReceipts()["date"][$i] == end($hotel->getReceipts()["date"])){ Это какой-то адски переусложненный код на массивах, даже трудно понять, как он работает.
> $room = $hotel->getRoom($room); Так делать нельзя. Не надо в одной переменной хранить разные типы данных (число и объект), это запутывает код.
То есть тут неудачно спроектированы классы и их методы (что можно с ними делать). Вот взять то же заселение:
> $hotel->getRoom($numberOfRoom)->setDate($hotel, $arrivalDate, $dateOfDeparture); > $hotel->getRoom($numberOfRoom)->addGuestToRoom($firstName, $lastName); > $hotel->getRoom($numberOfRoom)->changeIsFtee(); Почему заселение делается за 3 вызова? Что, можно вызвать только setDate() и не вызывать остальные методы? Ты тут нарушаешь принцип инкапсуляции. Ты должен просто вызвать метод класса Room "пометить номер забронированным таким-то гостем", а дальше внутри класса Room уже код будет заполнять нужные поля. При твоем подходе очень легко ошибиться, например, забыть вызвать один из методов.
Если бы у тебя был класс, представляющий Бронь, то хватило бы просто вызова
номер->добавитьБронь(бронь);
Сортировку номеров лучше делать с помощью usort, а не городить там сложные циклы.
>>1151712 >Раз тебя банят, значит, не хотят, чтобы ты с них парсил данные. Займись чем-нибудь более полезным. Да, вот только это и есть более полезное так как мне за это платят деньги.
>>1151711 > > Что тут сложного? Выносишь шапку и подвал в отдельные шаблоны и вызываешь их в начале и конце страницы. И так все делают, лол?
Вообще, единственное, что пришло мне в голову, это наоборот загружать на одну html страницу динамическую часть из БД с помощью аджакса, вроде и выглядит красиво, но потом я понял, что тогда при обновлении страницы оно будет все сбрасывать до начального состояния, и вообще что большинство сайтов таки крутят колесо когда на другую страницу переходишь.
>>1151712 >Как удобно все сделано в Дебиане, где программы ставятся через apt-get или через их стор. Не то что винда представляю, как ты обрадуешься, когда узнаешь, например, о yum.
Проще всего сдеалть денормализацию и добавить поле "число статей" к таблице тегов. Так как SQL-запрос с группировкой потребует обхода всех статей (их могут быть сотни и тысячи) и будет не эффективен. Либо кешировать его результаты, если не нужна оперативность.
По твоему коду - не проще ли писать DQL, чем городить кучу скобок и стрелочек?
Не нужно использовать addslashes. Плейсхолдеры использовать нужно. Строки сами по себе никакого вреда не несут, уязвимость появляется при неправильной подстановке данных от пользователя в какую-то строку, например, SQL-запрос или HTML-код страницы.
Ты все переусложнил. После того, как ты нашел все буквы первой регуляркой, ты можешь просто обойти массив этих найденных букв в цикле и посчитать их число, используя массив такого вида для хранения результата:
'a' => 0, 'б' => 0, ...
На каждом шаге цикла ты берешь 1 букву и увеличиваешь соответсвующее значение в массиве.
Есть еще функция array_count_values, но тут она не очень подойдет.
Ты можешь прочесть комментарии и посмотреть, какие из них можно применить к твоему коду.
Ну например, не надо смешивать в кучу php-логику и вывод HTML-кода, не надо подставлять переменные прямо в SQL запросы (у тебя там SQL инъекция), не надо писать сплошную стену кода на 200 строк, а надо разбивать код на функции.
Код надо правильно отформатировать на phpformatter.com
Надо давать нормальные имена переменным. Что такое mea или st? Кто это будет расшифровывать?
mysql-функции давно устарели.
Плюс, у тебя есть просто синтаксические ошибки, например в $_GET[from] надо from брать в кавычки. Ты пробовал включить вывод предупреждений и посмотреть, что выведется?
Пока код очень некачественный. Ты по какому-то очень устаревшему учебнику учился.
По поводу if, можно поставить echo во все ветки и увидеть, что выполняется.
На дампе справа я вижу, что в массиве один и тот же объект - это видно по номеру после слова DateTime - он одинаковый. То есть ты добавил в массив кучу ссылок на один и тот же объект, и так как объект один, то тебе кажется что у тебя много объектов которые синхронно модифицируются. но объект там один. Короче говоря
$a = new \DateTime; $b = $a;
Тут всего один объект и 2 переменные, которые на него указывают. И если ты делаешь $a->modify() то в $b значение тоже обновится так как она указывает на тот же самый объект.
Основы ООП, в общем.
Также, строчка date->format() у тебя ничего не делает.
- прибавляем проценты и комиссию к остатку долга (!не вычитаем ничего пока!) - если остаток маленький, выплачиваем сколько осталось и уходим - иначе платим 5000
«Платим» здесь значит уменьшаем долг и увеличиваем общую сумму выплаченного.
> Почему количество коффе,которое задается в условии для каждой профессии не является свойством? (так написано в подсказках) Я думаю, там была идея про то, что надо различать базовое количество кофе (свойство работника) и итоговое потребление с учетом ранга (вычисляется из базового). И для итогового не делать свойство, а сделать метод и вычислять на ходу.
> . Зачем нужно свойство "профессия" (так написано в подсказках)? Чтобы знать, какой профессии работник? Там есть 2 подхода, можно сделать для каждой профессии свой класс, а можно сделать единый класс, но тогда нужно свойство, показывающее, к какой профессии относится работник.
По опыту предыдущих решений, там придется хранить метаданные (битрейт, разрешение, кодек) либо в JSON-поле, либо делать EAV (Entity Attribute Value). Так как они разные для разных форматов файлов.
> Хотя более логичным мне кажется использовать паттерн одна сущность - одна таблица без явных связей с другими таблицами(Concrete Table Inheritance), ведь объект полностью имеет поля своего предка, и раз в бд нельзя провернуть наследование, то может оно и не нужно?
Это неудобно по таким причинам:
- не будет генерироваться возрастающий id для файлов - неудобно ставить внешний ключ. Ну например, с комментария на файл.
> Я правильно понимаю что в бд я записываю путь к файлу, который лежит на диске, а потом при отправке пишу нужные заголовки и вставляю туда же путь к файлу
Нет конечно. Если ты вставишь в ответ путь к файлу, то только путь и отправится, а не файл. Ты конечно можешь давать пользователю прямую ссылку на файл, но там есть свои подвохи.
В комментариях к задаче предложены варианты отдачи файла.
> вроде обёртка есть для переменной _FILES
$_FILES - это файлы, отправленные из браузера на сервер.
Я не очень понял, в чем вопрос? Это где-то описано и ты хочешь ссылку или ты сам придумал? Если сам, то наверно тебе придется и алгоритм работы роутера придумать.
> мне надо придумать какой нибудь хэш для комнаты(он же идентификатор), но по идее идентификатор комнаты ее номер. Не надо - объект сам по себе идентификатор. Но как ты заметил, есть номер.
> А вот по поводу гостя, какой идентификатор добавить? То же самое.
> Если сделать идентификатором пользователя имя и фамилию и использовать как ключ для доступа поля в массиве? Плохая идея. Они не уникальны.
> Еще мне очень интересно как на это все добавить тестов или вообще в идеале делать по тдд, если это конечно возможно?
ТДД значит, что ты сначала определяешь требования к классам в виде тестов, а только потом пишешь код.
Что касается тестирования, то тут как раз все хорош тестируется. Определяешь требования к классам и их сочетаниям и на каждое требование пишешь тест, проверяющий его выполнение.
Например, возьмем такое требование к функции проверки занятости номера:
- функция проверки занятости номера должна возвращать, что номер занят, если он забронирован на эту дату
И пишем тест:
- создать Номер - добавить в него бронь с 3 по 5 января - проверить, что функция свободенЛи() для 4 января вернет false
То есть попробуй рассмотреть все классы, методы и сформулировать требования к ним.
>>1151828 >Не надо - объект сам по себе идентификатор. А как проверять, что у меня нужный мне объект? С идентификатором комнаты понятно, сравнить у моего объекта и какого либо другого номера, но если нету такого идентификатора, нужно получается, что то типо uuid поля создавать?
>>1151828 >Определяешь требования к классам и их сочетаниям То есть в твоем примере теста, проверка свободен ли номер 4 января, это и есть требование?
Если я не прав можно попросить пример требований?
А что проверяется в сочетаниях классов? Все тоже самое только в комбинациях классов? Например класс А может использовать классы Б и В, я проверяю тестами сначала для классов А+Б, потом для классов А+В?
Может есть какой совет или рекомендация, как увидеть все требования, ничего не забыть или не напридумывать других требований?
Такая ситуация: создал удаленный репозиторий. Закоммитил, но не заметил, что добавил один файл, который не нужен. Сделал уже три коммита, и только сейчас обнаружил, что он на гитхабе. Как его убрать из всех коммитов?
>>1151714 >Как я понимаю, react отвечает ведь за view, отображение данных, не очень понятно, какое отношение он имеет к HTTP-запросам? На случай, если это был не риторический вопрос, у автора разделен код компонента модального окна (view, components/Modal/LoginModal.js ) от кода, который отвечает за создание и отправку реквеста (util/api.js). Но есть зависимость "export function setStore(s)", причем она используется только для запуска метода store.dispatch(loginRequired(request)), можно передать только сам метод dispatch() а не store целиком.
>>1151714 >> export function setStore(s) { >Вот это тоже какая-то извращенная идея, они модуль используют как объект. Если вам нужен объект, почему не сделать класс? За то небольшое время, пока я ковыряю исходники и примеры различных библиотек около рект/редакс модулей, я ни разу не видел, чтобы кто-то использовал классы, только файлы с набором функций. Я не защищаю такой подход, просто делюсь наблюдением.
>>1151714 >Также, я не уверен, что вообще имеет смысл делать показ окон через react. А тем более, сохранение отложенных запросов в store. Очень странный выбор, по моему человеку просто принципиально все делать на реакте, даже если это усложняет код. Но если все приложение использует react+redux, то немного странно делать модальное окно не на основе компонента react? Или как быть с запросами, ведь интерфейс должен инициировать запросы к api и каким-то образом реагировать в случае, если сервер вернул ошибку 401? Допустим я сделаю класс класс Api, который знает о том где находится сервер и как отправлять запросы, создам класс Request, который будет хранить заголовки и данные. Но где создавать и хранить Request? Сделать еще один класс посредник, который будет подписан на события изменения store, забирать нужные данные, формировать, отправлять и хранить запросы?
Представь, что ты поручаешь кому-то написать функцию. Ты должен сформулировать требования к этой функции, чтобы человек знал, что от него нужно. Что она должна делать? Как должна себя вести в той или иной ситуации?
Когда он напишет эту функцию, ты берешь по очереди каждое требование и проверяешь, что оно выполняется. Вот это и должны делать тесты - проверять, что код соответствует поставленным при его написании требованиям.
Соответственно, когда ты потом будешь использовать эту функцию в коде, ты можешь ожидать, что она соответствует этим требованиям, но ты не должен ожидать от нее что-то сверх этого.
Обычно сначала пишется функция, а потом тесты к ней. В случае использования TDD, мы сначала пишем тесты, а только потом код функции. TDD позволяет, например, одному человеку написать требования в виде тестов и передать их разработчику для написания кода.
Ну например, возьмем метод добавления брони $room->reserve() на определенные даты на номер в классе Room. Что он должен делать?
- он должен выдать ошибку, если выбранные даты уже заняты - иначе, он должен добавить бронь (то есть где-то сохранить информацию, что номер забронирован на такие-то даты такими-то гостями, и это потом можно проверить) - (тут еще могут быть дополнительные требования по проверке данных, которые я для простоты не пишу)
Имея требования, мы можем написать тесты, проверяющие их выполнение. Тут нам придется проявить смекалку и придумать, как именно их проверять. Например, для проверки второго требования можно написать такой тест (я использую синтаксис phpunit):
public function testReservedRoomIsMarkedAsOccupied() { $room = new Room(..); $guest = new Guest(...);
$room->reserve($guest, new DateTime('2020-01-03'), new DateTime('2020-01-05'));
// Проверяет, что функция вернет true $this->assertTrue($room->isOccupied(new DateTime('2020-01-04')));
// При желании еще можно написать так, хотя некоторые скажут, // что это нужно писать в отдельном тесте $this->assertFalse($room->isOccupied(new DateTime('2020-01-06'))); }
В случае TDD, можно использовать даже специальный язык для формулирования требований, например, Gherkin. На нем требования пишутся с использованием конструкций Given (дано) - When (если) - Then (то). Например, аналитик может записать одно из требований так (я пишу текст на русском для удобства чтения):
Feature: бронирование номера Scenario: Забронированный номер помечается как занятый
Given Есть свободный Номер 100 And Есть Гость Иван Иванов And Иван Иванов бронирует номер 100 с 3.01.2020 по 5.01.2020 When мы проверяем, занят ли номер 4.01.2020 Then номер помечен как занятый
> То есть в твоем примере теста, проверка свободен ли номер 4 января, это и есть требование? Нет. Требование - функция должна позволить забронировать незанятый номер и запомнить это.
> А что проверяется в сочетаниях классов? Некоторые классы можно тестировать отдельно, но некоторые классы не могут работать сами по себе и им нужны еще какие-то другие классы. Тогда мы их тестируем вместе.
> Например класс А может использовать классы Б и В, я проверяю тестами сначала для классов А+Б, потом для классов А+В? Такое редко бывает, обычно бывает, что классу А нужны Б и В. Тогда в тесте для класса А мы создаем объекты Б и В и передаем их в А.
> как увидеть все требования, ничего не забыть или не напридумывать других требований? Нужно взять каждый класс, каждый публичный метод и подумать, что мы от него хотим. Что он должен уметь делать и как себя вести в той или иной ситуации.
> А как проверять, что у меня нужный мне объект? Объекты можно сравнить с помощью ===: if ($a === $b) выполнится только если $a и $b ссылаются на один и тот же объект.
$a = new Guest('Иван Иванов'); $b = $a; // В $a и $b один и тот же объект, $a === $b
$c = new Guest('Иван Иванов'); $d = new Guest('Иван Иванов'); // в $c и $d разные объекты, $a !== $b
Потому я и пишу, что каждый объект обладает идентичностью и отличается от всех других объектов (даже если у них одинаковые значения всех свойств). Не нужно добавлять искуственные идентификаторы только для того, чтобы сравнивать объекты.
> public function __construct($rank, $rate, $isBoss, $profession) Если ты используешь PHP7 (я надеюсь, что да), то нужно расставить тайп хинты для аргументов, а также для возвращаемых значений функций, мануал http://php.net/manual/ru/functions.arguments.php
Для $isBoss лучше использовать значения true/false вместо 1/0.
> public function GetSalary() > > switch ($this->rank) { Здесь для надежности надо добавить пункт default с выбросом исключения, если ранг не равен 1, 2 или 3.
> get_class($this)::COFFE*2 Это неправильно. Во-первых, ты бы мог просто написать static::COFFEE. Во-вторых, ты не должен в базовом классе обращаться к константам, которые добавят только в наследнике.
И тут есть еще одна проблема. А где вообще гарантия, что тот, кто пишет наследника, сделает эти константы? Это ведь никак не описано и никак не проверяется.
И еще одна проблема. А что, если кто-то создаст объект класса Employee? Он ведь не помечен как абстрактный, значит создавать его не запрещено. А констант в нем нет.
В ООП (да и не только в ООП) ты должен стараться так писать код, чтобы нельзя было его неправильно использовать. Если класс Employee используется только как основа для наследования, то надо пометить его абстрактным, чтобы никто даже не пытался создать объект такого класса.
Если ты хочешь, чтобы в каждом классе профессии была определена базовая зарплата, это тоже надо зафиксировать в коде, чтобы нельзя было ее не определить при объявлении класса профессии.
В идеале, ты бы мог еще проверять данные, чтобы например при создании работника нельзя было передать неправильный ранг.
Это все делает код более надежным и позволяет обнаружить ошибки как можно раньше.
Вместо констант тут нужно сделать так:
- пометить базовый класс как абстрактный - определить в нем абстрактные методы вроде getBaseSalary(), которые должны будут реализовать наследники. Так мы укажем, какие методы обязан реализовать наследник, и PHP не позволит это не сделать. Про абстрактные методы мельком написано в уроке по ООП (где-то рядом с задачей Вектор).
Если ты используешь для каждой профессии свой класс, то свойство profession избыточно.
> abstract class AbstractDepartment > public $rank; Это неправильно. Разве у Департамента есть свойство Ранг? Оно есть только у Работников.
> class BuyDepartment extends AbstractDepartment Если департаменты отличаются только названием, то нет смысла для них делать отдельные классы. Они нужны, когда объекты одного типа различаются поведением (то есть в них есть одни и те же методы, но они разные).
Я бы советовал у Департамента сделать свойство списокРаботников и методы для приема на работу/увольнения работника.
Также, советовал бы сделать класс, представляющий всю Компанию.
И еще кое-что. Ты используешь тут публичные свойства - а значит, любой может записать в них любые значения. Разве это хорошо? Давай сделаем свойства закрытыми от доступа снаружи и сделаем методы для их изменения. Так мы во-первых, можем решить, какие свойства можно менять, а какие нет, во-вторых, мы можем гарантировать, что в них не запишут неправильное значение. Это назвыается инкапсуляция.
Минус этого подхода в том, что кода будет больше чем с публичными свойствами, но тут задача простая, так что я не вижу проблемы.
Про инкапсуляцию:
----------
Инкапсуляция. У этого слова есть разные определения, в том числе такие что ничего не понять, потому объясню простыми словами.
Суть инкапсуляции в том, что класс скрывает (инкапслирует) в себе логику работы с данными и сами данные (помечает их private/protected), а наружу выставляет только методы. Пользователю этих методов не важно, как класс устроен внутри, как он хранит данные, ему достаточно вызвать нужный метод, чтобы получить результат.
Это упрощает понимание кода: тебе не надо читать и разбирать код класса, достаточно прочитать название метода (и может быть комментарий к нему). Также, это упрощает изменение кода: если какое-то свойство имеет уровень private, то доступ к нему возможен только из того же класса и тебе не надо бегать по всему коду и смотреть что там с этим свойством делается, тебе достаточно просмотреть один файл с этим классом.
При инкапсуляции автор класса строго ограничивает, что можно делать с объектом.
Как плюс, мы можем поставить какие-то проверки в методах, и запретить установку неправильных значений свойств. Таким образом, снаружи записать неправильное значение в объект будет нельзя и автор класса может гарантировать его корректную работу в любой ситуации.
Инкапсуляция это хорошо. Так как весь код, который занимается одной задачей, оказывается заключен внутри одного класса. Противоположный случай это когда код (или знание о его внутреннем устройстве) вылезает из класса и размазывается по всей программе.
Если проводить аналогии, то можно представить кофе-машину. Ты нажимаешь кнопку (=вызываешь публичный метод) и получаешь кофе (=результат вызова этого метода), при этом ты не видишь что происходит внутри нее и тебе не надо в этом разбираться.
Некоторые используют наследование шаблонов, если оно есть в шаблонизаторе - с ним конечно удобнее.
> Вообще, единственное, что пришло мне в голову, это наоборот загружать на одну html страницу динамическую часть из БД с помощью аджакса, вроде и выглядит красиво, Переусложнение.
> function spellSmallNumber($num, $female) { > $result = array();
Должно быть
function spellSmallNumber($num, $female) { --->$result = array();
Без отступов тяжело читать код.
Если ты пишешь прямо в ideone, то поставь себе какой-нибудь редактор кода или IDE - такие большие куски кода неудобно писать без них.
Искать форматтеры можно по "php beautify", хотя часть из них кривые. Вот этот работает, если повозиться с настройками: http://phpbeautifier.com/beautify.php
> $hundOne = $lastTwo % 10; Название неудачное, лучше просто lastDigit или units.
> $units = floor($lastTwo / 10) * 10; Десятки - это tens
> if ($female == 1 or $female == 2) { Тут по задумке передается не последняя цифра (она уже есть в числе), а 1 если используется женский род (для тысяч) или 0 для мужского. Неазвисимо от того, какое число.
Так, алгоритм примерно правильный, но код читать невозможно. Надо отформатировать правильно. Во втором посте треда вроде написано, как форматировать код.
Насчет хранения истории - сложный вопрос. Давай рассмотрим варианты:
1) хранить историю бронирований только в Room
Плюс: данные не дублируются, значит не может быть противоречий Плюс: работает инкапсуляция, Room знает, когда она занята или свободна Минус: если мы хотим получить историю по клиенту, мы должны обойти все комнаты. Также, а что делать при удалении комнаты? Куда денется история? Минус: чтобы получить данные по отелю за сутки, надо обойти все комнаты. Минус: гость не знает, где он был и когда
"обойти все комнаты" - само по себе не такая уж проблема. Проблема, что делать, когда мы захотим удалить комнату? Наверно, придется делать soft-delete - то есть помечать комнату закрытой, но не удалять ее.
2) дублировать историю в Room и Guest
Плюс: теперь у Гостя появилась "память".
Примерно тот же набор минусов, только теперь данные дублируются и мы должны следить, чтобы всегда добавление/отмена бронирования происходило в 2 местах. А если в процессе этого вылетит исключение? То есть мы создаем новую проблему - отслеживание согласованности данных - которой не было бы, если бы данные не дублировались.
Также, хранение истории в 2 местах не повлечет ли дублирование кода?
3) хранить историю в Hotel (или в HistoryLog, который хранится внутри Hotel)
Плюс: данные не дублируются Плюс: удобно строить отчеты
Теперь у нас Room и Guest становятся классами почти без логики, а вся логика перемещается в Hotel. Немного меньше разделения обязанностей.
4) сделать класс HistoryLog, держать на него ссылку в Hotel и передавать (инжектировать) во все Room и Guest при создании
Плюс: централизованное хранение истории, при этом Room/Guest могут сами с ней работать Минус: новые объекты Room/Guest теперь можно создавать только через Hotel, нельзя создать через new Минус: а что, если Гость хочет остановиться в нескольких Гостиницах?
То есть попробуй выписывать разные варианты и искать их плюсы/минусы.
Не лучше ли тут реализовать это не через store? То есть у нас есть условно говоря, клиент API. Мы в нем можем предусмотреть состояние залогиненности/незалогиненности. И пусть он об этом сообщает, что нужен логин:
// делаем запрос через API var promise = client.getSomeData();
То есть вынести это в отдельную сущность, не использовать для очереди запросов store. Зачем все в store тащить-то? Получится же God Object.
Кстати, сам ApiClient тоже можно разделить на 2 класса - класс, который умеет делать запросы и класс, который умеет повторять их при различных ошибках.
> Но есть зависимость "export function setStore(s)", причем она используется только для запуска метода store.dispatch(loginRequired(request)), можно передать только сам метод dispatch() а не store целиком.
Сделана она неудачно, так как можно вызвать другие методы модуля, не задав store. Более того, тут еще и жестко задана невозможность использовать более одного store. Они модули используют как синглтон.
А в случае с классами мы могли бы сделать класс и передавать store в конструктор. Еще можно не делать класс, а просто добавить store в аргументы функции, которым он нужен.
> Но если все приложение использует react+redux, то немного странно делать модальное окно не на основе компонента react? Не знаю, а почему нет? В моем понимании:
store - это что-то вроде модели, хранящей состояние. Это не совсем модель из MVC с данными приложения, так как она хранит еще и состояние интерфейса (то, что иногда называют ViewModel).
окно - это view, отображающее данные из модели. Никто не запрещает сделать каждое окно отдельным view, и создавать/удалять их не через react. Я, кстати, даже не вижу проблем с тем, чтобы делать для некоторых окон свой store - а почему нет? Разделение ответственности.
А так, подход react/redux - получается, мы делаем одно мегавью, в котором внутри есть все попапы. И при любом изменении модели мы перерендерим все это мегавью и все попапы в нем.
У меня просто ощущение, что реакт задумывался, условно, для каких-то интерактивных мест на странице, например, сложных форм, каких-то редакторов. А не для того, чтобы целиком все на нем делать.
Поставил убунту на виртуалку. Подскажите с чего начать, что бы уметь на ней: 1. поднять сервер. 2. поднять доман на локалхосте. 3. всё это запустить и протестить. 4. Подключиться к гитхабу - залить туда репозиторий.
>>1152037 >>1152037 >1. поднять сервер. >2. поднять доман на локалхосте. >3. всё это запустить и протестить. почитать интернеты, например https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-16-04 >4. Подключиться к гитхабу - залить туда репозиторий. создать репозиторий на гитхабе, скопировать код "git add remote ..." из его интерфейса, потом на локальном хосте написать git init, git add ., git push origin master
Сап тред. Я слепил велосипед и он ужасен. Вторая задача по массивам. Я накидал говнокода и оно работает, но получился действительно говнокод. Вот: https://ideone.com/r5b38C Дайте подсказку как это сделать правильно, а то я сидел, думал, но высрал только это.
>>1152195 Используй циклы вместо 9 условий. Тебе нужно всего лишь рост каждого одноклассника сравнить с ростом Антона. Твоя реализация такая, чисто человеческая. Представь, что у тебя не было бы заданного массива, а файл с произвольными данными об одноклассниках какого-то анона. Тут уже этот велосипед не сработает.
>>1152028 >Не лучше ли тут реализовать это не через store? То есть у нас есть условно говоря, клиент API. Мы в нем можем предусмотреть состояние залогиненности/незалогиненности. И пусть он об этом сообщает, что нужен логин: > >var client = new ApiClient; >
Тогда нужно будет соединить его с основным приложением (я предполагаю случай, когда реакт+редакс app - основное приложение, компонент базовый элемент интерфейса наследующий React класс Component): 1. Можно импортировать его как модуль в каждом компоненте, где необходимо что-то отправлять или получать от api, при этом данные полученные от ApiClient отправляются компонентом в store с помощью dispatch(somAction(data)); Компонент знает о ApiClient и его методах. 2. Сделать middleware класс, который слушает основной поток событий от компонентов, и реагирует на определенные события, запуская ApiClient.someFuction(); Middleware класс знает о ApiClient и о App (store.dispatch() и определенных Action). 3. Можно сделать компонент ApiClient, который имеет локальный state, в котором хранит свои специфические данные, например очередь запросов, и подписан на определенные изменения store, которые являются условием инициации отправки запросов, также умеет в dispatch() как и обычные компоненты. Именно так реализована библиотека Redux-Json-Api, которая позволяет отправлять и получать запросы в формате jsonapi, выковыривать из них данные и нормализовав сохранять в store https://github.com/redux-json-api/redux-json-api
Т.е. возможность иметь отдельный ApiClient, который не знает о store это вариант 1 и 2. Я пока не могу в полной мере оценить плюсы и минусы каждого подхода хотя и пробовал оба варианта.
>>1152028 >Более того, тут еще и жестко задана невозможность использовать более одного store. Они модули используют как синглтон. Тут такая религия, store един. с оф сайта редакс: Redux can be described in three fundamental principles: 1.Single source of truth The state of your whole application is stored in an object tree within a single store.
Некоторые последователи предлагают таки хранить часть данных в локальном state компонента, например информация о поле формы, валидна инфа в поле или нет.
>>1152028 >> Но если все приложение использует react+redux, то немного странно делать модальное окно не на основе компонента react? >Не знаю, а почему нет? С помощью react мы можем сделать модальное окно, используя кнопки и поля ввода, для которых мы уже создали компоненты. Если даже это и не удобно, то во всяком случае соблюдается единый стиль описания html элементов.
>В моем понимании: >store - это что-то вроде модели, хранящей состояние. Это не совсем модель из MVC с данными приложения, так как она хранит еще и состояние интерфейса (то, что иногда называют ViewModel). > >окно - это view, отображающее данные из модели. Никто не запрещает сделать каждое окно отдельным view, и создавать/удалять их не через react. Я, кстати, даже не вижу проблем с тем, чтобы делать для некоторых окон свой store - а почему нет? Разделение ответственности.
Вообще у компонентов есть способ хранить состояние - local state. Мы можем там хранить данные относящиеся к UI.
React предлагает компоненты, классы которые позволяют делать не связанные между собой элементы интерфейса, которые могут хранить свое состояние и отрисовывать html элементы описанные с помощью JSX. Иметь свои обработчики событий в качестве методов. Бонусом, компоненты умеют в композицию, т.е. компонент форма может быть собрана из компонента поле-ввода и компонента кнопки. В дочерние элементы данные передаются по цепочке через props, который передается в конструктор компонентов.
Rudux нужен для того, чтобы создать единое хранилище состояния всего приложения. Store - это хранилище. Изменение в нем происходит единственным способом: с помощью reducer, это функции, которые принимают в качестве аргументов объекты action и предыдущую версию store. Action это объекты контейнеры, имеющие определенные типы и содержащие данные. Все участники вечеринки могут получить доступ к функции store.dispatch(someAction), после запуска которого someAction попадет в цепочку редьюсеров для обработки. А компоненты могут "подписаться" на изменение определенных данных в store и получать их каждый раз, когда они изменятся. Т.е. данные поступают в store только с помощью store.dispatch(someAction), а из store в компоненты через props, каждый раз, когда изменяется store.
>А так, подход react/redux - получается, мы делаем одно мегавью, в котором внутри есть все попапы. И при любом изменении модели мы перерендерим все это мегавью и все попапы в нем. DOM не обязательно перерисовывается при изменении store, т.к. данные могут не затрагивать сам интерфейс, а только их внутреннее хранилище local state или же просто не один из компонентов не подписан на изменение этих данных.
А то открываешь, видишь кучу файлов и даже непонятно, что это. Непонятно, как установить и что надо делать. Пришлось гуглить, разбираться в документации Laravel итд. Очень неудобно.
Если ты не используешь тесты, то файлы от них не нужно добавлять.
Также, у тебя там прописана сборка JS-файлов, подключение Vue. Но он нигде не используется. Зачем тогда это добавлять? Из-за этого труднее найти, где именно твой код, а где стандартные заготовки.
Дальше, мне не нравится, что в composer.json прописан "name": "laravel/laravel". Как будто бы это не твое приложение, а официальный репозиторий фреймворка Laravel. По моему, это вводит в заблуждение. Поле name предназначено в первую очередь для добавляемых в репозиторий packagist библиотек, а в твоем случае оно вообще не нужно.
У тебя (вроде бы) сделано так, что таблица студентов недоступна без авторизации, но вообще в задаче она должна выводиться для любых пользователей.
Получение данных по идее должно быть в модели, а не в контроллере. Ты тут пишешь типичный "толстый контроллер".
Ты используешь в форме регистрации PUT, но ведь браузеры не поддерживают этот метод и там будет использована POST-форма с скрытым полем, а на стороне Ларавел будет сымитировано поступление PUT-запроса. Не переусложнение ли?
По условиям задачи требовалось разрешить пробелы, дефисы и апострофы в именах.
> 'birth_year' => ['required', 'string', 'regex:@^199[0-9]|200[0-5]$@iu'], Люди старше 28 лет - не допускаются?
Далее, я попробовал запустить у себя проект с помощью встроенного в PHP веб-сервера - он показывает страницу "Whoops, looks like something went wrong" (2 раза), но подробности ошибки нигде не выводятся - ни на странице, ни в консоли (выяснилось, что надо создать .env, но я не понимаю, почему по умолчанию подробности ошибки не пишутся в консоль - как это отлаживать?).
В форме регистрации подписи к полям в нечеловекочитаемом виде вроде "second_name". Также, сообщения об ошибках почему-то на английском. Плохо смешивать разные языки в интерфейсе. В меню также надписи на английском. А где-то в форме подсказки на русском.
Также, в задаче была предложена безпарольная регистрация - ты не хочешь сделать такую же? Наверяка в Ларавель это можно настроить.
При сортировке никак не выделена колонка и направление сортировки. Нужно выводить стрелочку или треугольничек или еще как-то показать режим сортировки.
Если при поиске ничего не найдено, то надо бы выводить соответствующую надпись, а не шапку от пустой таблицы.
> protected function validator(array $data) Имена функций обычно начинаются с глагола, сделайЧтоТо()
> `birth_year` int(11) NOT NULL В таблице можно было бы использовать тип YEAR.
Так, конечно, при использовании Ларавел тут получается очень мало твоего кода (так-то это хорошо, но у нас ведь задача научиться). На мощном фреймворке лучше было бы делать задачу вроде TestHub, где все сложнее. Ну или попробовать сделать безпарольную авторизацию, как описано в задаче.
- основы командной строки, можно начать отсюда https://github.com/codedokode/pasta/blob/master/soft/cli.md - основы линукса (почитать любой учебник для начинающих, про файловую систему, про права, про пользователей, про основные команды вроде ls или rm) - используемый в твоем дистрибутиве пакетный менеджер (apt-get)
Тебе надо настроить виртуалку так, чтобы к программам в ней можно было подсоединяться с основной системы. Для этого придется добавить второй сетевой интерфейс. Тут это описано: https://gist.github.com/codedokode/420c8c12a1edae25f0ec (то, что про Дебиан - можешь не читать, хотя Убунта и сделана на его основе).
Чтобы "поднять домен на локалхосте", тебе достаточно в файл hosts на основной системе приписать любое доменное имя и IP-адрес виртуалки.
- настроить второй интерфейс на виртуалке - прописать домнен в hosts - установить, настроить и запустить в виртуалке веб-сервер (Apache, nginx или встроенный в PHP)
После этого из браузера можно будет зайти на сайт.
Чтобы залить существующий репозиторий на гитхаб, надо сделать слудующие шаги:
- создать на гитхабе пустой репозиторий без всего - локально добавить новый remote (git remote add origin ..), указав URL, который тебе выдаст гитхаб на первом шаге - сделать git push origin HEAD
Да, твое решение неудачное, так как надо на каждого ученика писать блок в if. Нужно использовать цикл по массиву таким образом:
- завести переменную и сохранить в нее 0 - взять по очереди каждого ученика, поместить его имя в $name, а рост в $height (это делает команда foreach) - если рост текущего ученика больше роста школьника, то увеличить переменную на 1 - когда цикл закончится, в переменной будет ответ
Вообще, мне не очень нравится идея использовать реакт для основы приложения. Как я понимаю, там придется хранить все данные приложения в сторе в виде одного гигантского объекта, при любом изменении создавать копию этого объекта (так как иммутабельность), перерендеривать все вью и это будет наверно не очень быстро работать. Хотя, тут надо тестировать. Сделал бы кто-нибудь задачу про SPA на реакте...
По мне, так он бы больше подошел именно как вью, управляющий каким-то одним экраном или попапом. При смене экранов можно уничтожать старое реакт-приложение и создавать новое. Ну это просто идея, не проверенная на практике. Не знаю, как она согласуется с redux.
> Можно импортировать его как модуль в каждом компоненте, где необходимо что-то отправлять или получать от api, при этом данные полученные от ApiClient отправляются компонентом в store с помощью dispatch(somAction(data)); А с какой стати компоненты должны работать с АПИ? Компоненты же просто отображают переданные им сверху (взятые из стора и пропущенные через редюсер) данные?
> Можно сделать компонент ApiClient, который имеет локальный state, Зачем работу с АПИ делать компонентом Реакта? Реакт это просто View, библиотека для отображения данных.
> Тут такая религия, store един. Ну если мы решим, что у нас за каждый экран отвечает свой стор (и свое реакт-приложение), то уже получается не един.
> С помощью react мы можем сделать модальное окно, используя кнопки и поля ввода, для которых мы уже создали компоненты. Если даже это и не удобно, то во всяком случае соблюдается единый стиль описания html элементов.
Так в моем вариант тоже, просто попап будет отдельным независимым реакт-приложением со своим стором.
> DOM не обязательно перерисовывается при изменении store, Я не про DOM. А про компоненты реакта, которые имеют метод render() и генерируют объекты виртуального DOM. Представь что у тебя чат, слева список из 100 контактов (каждый как компонент), справа - 100 сообщений. Плюс еще скрытые компоненты разных попапов. То есть куча компонентов реакта. При выполнении любого действия со стором все это дерево компонентов обходится, вызывается метод render, генерируется огромный виртуальный DOM, сравнивается с предыдущей версией? Или нет?
Сделал бы кто-нибудь что-нибудь сложное на реакте с кучей форм и таблиц, можно было бы потестить.
> Even though React only updates the changed DOM nodes, re-rendering still takes some time. In many cases it’s not a problem, but if the slowdown is noticeable, you can speed all of this up by overriding the lifecycle function shouldComponentUpdate,...
> In most cases, instead of writing shouldComponentUpdate() by hand, you can inherit from React.PureComponent. It is equivalent to implementing shouldComponentUpdate() with a shallow comparison of current and previous props and state.
Пачаны, такая ошибка, делаю регистрацию на сайте, но почему то проверка if (!$result) не срабоатывает, все время получается: MessageSend (1, 'Пользователь с таким E-mail адресом уже существует!');
$result = $pdo->query("SELECT mail FROM users WHERE mail='$mail'"); if (!$result){ $reg = $pdo->query("INSERT INTO users VALUES('$name','$mail','$password','0')"); }else { MessageSend (1, 'Пользователь с таким E-mail адресом уже существует!'); }
Пожалуйста, пишите один большой пост вместо нескольких маленьких и не флудите не по теме.
Это тред для начинающих. Не написал за свою жизнь ни одной программы и имеешь тройку по математике? Ты наш человек.
Предыдущий тред был тут: . Остальные треды есть в архиве: https://phpclub.tech/ или ищутся в гугле по словам "клуб изучающих php" и в архиваче.
Мейлач лежит? Есть запасной тред на доброчане: /s/res/23225.xhtml#i46467
Что самое главное для программиста? Умение аккуратно оформлять код (как, написано во втором посте).
Правила: ведем себя воспитанно, помогаем новичкам, читаем учебники, решаем задачки, постим ссылки на решения, ОП их проверяет и дает советы и замечания. ОП заходит редко, где-то раз в 2-3 дня, у него мало времени, не жди его, решай задачки дальше. ОП отвечает на все вопросы по его задачкам и учебнику, а вот насчет каких-то других вещей - только если останется время. Но в треде немало анонимных экспертов разного уровня, так что вряд ли вопрос останется без ответа.
С чего начать
У нас есть свои уроки по основам PHP, они собраны и выложены по адресу http://codedokode.github.io/phpbook (вас отредиректит на другой домен, не читайте, не сохраняйте, не запоминайте его, он временный). Это учебник для изучающих с нуля, то есть если ты вообще ничего не знаешь, то можно начать с него. Он простой и понятный. Там есть задачи, их нужно решать (чтобы стать программистом, надо писать код — иначе никак). Пости ссылки на решения в тред, мы их проверим, напишем замечания и дадим советы по улучшению. С другой стороны, если этот учебник тебе не нравится, можно читать любой другой. Или официальный мануал. Или все сразу.
Устанавливать пока что ничего не требуется, разве что редактор кода вроде Sublime Text 3, Notepad++, Visual Studio Code, Netbeans PHP или PhpStorm (с ним будет удобнее).
Если не знаешь как решать, запости код, напиши в каком месте остановился и попроси подсказку.
Ты прошел весь учебник? Молодец, но это были лишь основы языка PHP, этого недостаточно. Вот что в идеале надо изучить еще: ООП, как работает веб-сервер, HTML/CSS, SQL, PDO, работа с таблицами в БД, работа с формами, MVC, git, composer, JS, фреймворки, автоматизированное тестирование.
Надо переходить к более серьезным задачкам, которые научат тебя всему этому.
- для начала прочти урок https://github.com/codedokode/pasta/blob/master/soft/web-server.md
- установи Апач + PHP (советы выше и ниже) и читай туториал http://php.net/manual/ru/tutorial.php
- Учи HTML/CSS и SQL, PDO, хотя бы основы
- Далее простая, но полезная задача сделать список студентов, в ней много полезных советов: https://github.com/codedokode/pasta/blob/master/student-list.md
- Более сложная задача сделать файлообменник на микрофреймворке Slim: https://gist.github.com/codedokode/9424217
- Еще более сложная и долгая задача на Yii/Symfony: https://gist.github.com/codedokode/8733007
- После нее можно изучать автоматизированное тестирование https://gist.github.com/codedokode/a455bde7d0748c0a351a
- Если ты все решил, переходи к Symfony 3/Doctrine 2
- Почитать про паттерны http://designpatternsphp.readthedocs.org/ru/latest/README.html (если ты не изучил ни одного фреймворка, то это будет рановато), тут с примерами кода http://designpatternsphp.readthedocs.org/ru/latest/README.html . Имей в виду что без примеров использования их учить бесполезно - не поймешь, хочешь увидеть примеры использования паттернов - ковыряй исходники Симфони, например Symfony Forms. Не заучивай паттерны - смотри код и думай, зачем тут они использованы.
Чтобы делать эти задания, тебе надо установить Апач + PHP (можно заодно сразу и MySQL) на компьютер. Вот полезные инструкции:
https://github.com/codedokode/pasta/blob/master/soft/php-install.md
https://github.com/codedokode/pasta/blob/master/soft/apache-install.md
Может тебе понадобится пользоваться командной строкой, вот гайд https://github.com/codedokode/pasta/blob/master/soft/cli.md
Решения задач лучше показать мне, особенно на ООП,так как сам ты вряд ли увидишь все ошибки. Пости свой код на гитхаб и вкидывай ссылку в тред по мере решения. Я прокомментирую и укажу на ошибки.
Параллельно стоит подучивать английский, на первых порах можно без него, но по мере развития придется все чаще сталкиваться с англоязычными статьями, так что лучше не откладывать. Читать можно news.ycombinator.com - это что-то вроде их хабра. Также можно начинать смотреть фильмы и видео на английском.
Также, у нас есть задачи которые позволят тебе изучить или подтянуть до нормального уровня знания JS/HTML/CSS/SQL. Решай их параллельно с задачами выше.
- HTML/CSS: https://github.com/codedokode/pasta/blob/master/html/html.md
- JS: https://gist.github.com/codedokode/ce30e7a036f18f416ae0
- SPA (сложно): https://github.com/codedokode/pasta/blob/master/js/spa.md
- Проверялка решений на JS: http://dkab.github.io/jasmine-tests/
- MySQL: https://github.com/codedokode/pasta/blob/master/db/databases.md
Что почитать
- Мануал по PHP — http://www.php.net/manual/ru/langref.php
- Сайт phptherightway (перевод на русский: http://getjump.me/ru-php-the-right-way/ )
- По PHP: Профессиональное программирование на PHP Джордж Шлосснейгл
- По PHP: Мэтт Зандстра — PHP: Объекты, шаблоны, методики программирования
- JS: learn.javascript.ru
- Про Git: https://git-scm.com/book/ru/v1
- Новости IT на англ. https://news.ycombinator.com/
Оформляй код аккуратно!!! — например пропусти через phpformatter.com . Также, если ты пользуешься IDE вроде PhpStorm, Netbeans, Eclipse, то в них эта опция встроена, подробнее: https://gist.github.com/codedokode/8759492
У ОПа нет аккаунтов и групп вконтакте, в фейсбуке, в твиттере, все "пхп-треды" там поддельные.
Платиновые вопросы
- Почему PHP? Потому что вакансий море, и учить легко.
- Сайт опять упал!!!!! — Не паникуй, а открой http://rghost.ru/6bfCY9lfl и получи личную немного устаревшую оффлайновую копию сайта (можно читать хоть на андроиде без интернета)
- Что надо знать чтобы найти работу - разработчику: PHP, SQL, HTML/CSS, JS, ООП, Git, композер, MVC, фреймворк. Верстальщику - HTML/CSS, JS, jQuery. У нас в треде были люди, которые практически с нуля учились и смогли найти работу.
- Что будут спрашивать на собеседовании если 0 опыта - гонять по теории, по официальному мануалу PHP, давать дурацкие задачки на переворачивание строк, гонять по SQL (транзакции, внешние ключи, напиши запрос), по JS (как сделать анимацию при нажатии кнопки), ну погугли, не ленись
- Можно подробнее про поиск работы, собеседования - нет, ОП писать не будет, но может кто из анонов захочет рассказать. Поищите тред перезвонивших, а также раздел /wrk/
- Сколько времени надо изучать все это? - все зависит от тебя, но не меньше 6-8 месяцев
- Нужен ли ООП, фреймворки, MVC, git, composer? — Да, однозначно. Посмотри любую вакансию.