Добро пожаловать в наш уютный тред. Тут мы изучаем язык PHP (а также JS/CSS/HTML/SQL), решаем задачки и даже делаем простые сайты! Зачем? Кто-то хочет научиться программировать, кто-то - делать сайты, кто-то - просто размять мозги и заняться чем-то полезным.
Это не чат! Пожалуйста старайтесь постить только вопросы, решения и ответы по теме. Сколько лет вы не можете найти работу никому не интересно. Высказывайтесь одним большим постом, а не цепочкой мелких
Это тред для начинающих. Не написал за свою жизнь ни одной программы? Ты наш человек.
Устанавливать пока что ничего не требуется, разве что редактор кода вроде Sublime Text 3, Notepad++, Netbeans PHP или PhpStorm (с ним будет удобнее).
Что самое главное для программиста? Умение аккуратно оформлять код (читай второй пост прежде чем писать код).
Почему PHP? Потому что фейсбук и википедия на нем написаны, и вакансий море, и учить легко.
Правила: ведем себя воспитанно, помогаем новичкам, постим ссылки на решения задачек, ОП их проверяет и дает советы и замечания. ОП заходит редко, где-то раз в 2-3 дня, у него мало времени, не жди его, решай задачки дальше. ОП отвечает на все вопросы по его задачкам и учебнику, а вот насчет каких-то других вещей - только если останется время. Но в треде немало анонимных экспертов разного уровня, так что вряд ли вопрос останется без ответа.
У нас есть уроки по основам PHP, они собраны и выложены по адресу http://archive-ipq-co.narod.ru/ Это учебник для изучающих с нуля, то есть если ты вообще ничего не знаешь, то надо начать с него. Он простой и понятный (по крайней мере в начале). Там есть задачи, их надо решать обязательно (чтобы стать программистом, надо писать код — иначе никак). Пости ссылки на решения в тред, мы их проверим, напишем замечания и дадим советы по улучшению.
Если не знаешь как решать, запости код, напиши в каком месте остановился и попроси подсказку.
Ты прошел весь учебник? Молодец, но это были лишь основы языка PHP, этого недостаточно. Вот что в идеале надо изучить еще: ООП, как работает веб-сервер, HTML/CSS, SQL, PDO, работа с таблицами в БД, работа с формами, MVC, git, composer, JS, фреймворки, автоматизированное тестирование.
Надо переходить к более серьезным задачкам, которые научат тебя всему этому.
Решения задач лучше показать мне, особенно на ООП,так как сам ты вряд ли увидишь все ошибки. Пости свой код на гитхаб и вкидывай ссылку в тред по мере решения. Я прокомментирую и укажу на ошибки.
Также, у нас есть задачи которые позволят тебе изучить или подтянуть до нормального уровня знания JS/HTML/CSS/SQL. Решай их параллельно с задачами выше.
Нужен ли ООП, фреймворки, MVC, git, composer? — Да, однозначно. Посмотри любую вакансию. Сайт опять упал!!!!! — Не паникуй, а открой http://rghost.ru/6bfCY9lfl и получи личную немного устаревшую оффлайновую копию сайта (можно читать хоть на андроиде без интернета) Оформляй код аккуратно!!! — например пропусти через phpformatter.com . Также, если ты пользуешься IDE вроде PhpStorm, Netbeans, Eclipse, то в них эта опция встроена, подробнее: https://gist.github.com/codedokode/8759492 ОП, сделай за меня мою работу или домашнее задание? — Это конечно, хорошая идея, но нет. Подскажи сайты для поиска работы, я не умею гуглить? — hh.ru, geekjob.ru, moikrug.ru (склеен с brainstorage.me), fl.ru, upwork.com (бывший одеск). Имей в виду, что кроме фриланса есть еще постоянная удаленная работа (remote job) когда тебе не надо тратить время на поиск заказов и переговоры с неадекватными заказчиками.
Код нужно писать не как попало, а аккуратно и по правилам. Почему? Потому, что на неакуратно написанный код не хочется даже смотреть.
Если тебе лень выравнивать код руками, закачай его на 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 пробела)
Вот ссылка на стандарты, где все это описано подробнее и даны примеры оформления:
Итак, ты зашел в тред и решил помочь какому-то анону, дав ему совет или подсказку. Спасибо! Но прочти сначала эти напоминания, чтобы твоя помощь действительно была полезной.
Давай удочку, а не рыбу
Лучше не давать готовое решение проблемы, а рассказать как его искать. Может дать ключевые слова для гугла или ссылку. Но помогай, а не пытайся показать превосходство. Если даешь ссылки на нерусскоязычные статьи, упомяни об этом.
Будь доброжелателен
Не годится: «Ты мануал хоть раз в жизни открывал, обезьяна?» Не годится: «В гугле забанили?» Не годится: «Твой код плохой» Хорошо: «Вот, как можно улучшить этот код: ...» Хорошо: «Ты неправильно используешь функцию abc(). Вот ее описание: ссылка, и как видишь ей надо передать строку, а не массив»
Не придирайся к знанию английского языка.
Объясняй
Не очень хорошо: «сделай как в этом коде» Хорошо: «если ты вставляешь текст от пользователя в SQL запрос, то получается SQl-инъекция, которая позволяет взломать твой сервер (ссылки). Чтобы этого избежать, надо вставлять данные с помощью плейсхолдеров (ссылки)» Хорошо: «Помни, что код пишется для людей. Если писать такие большие функции, то в них становится трудно разобраться...»
Не проповедуй
Мы учим использованию самых распространненных подходов, стандартов, библиотеки фреймворков. Если ты не любишь ООП, пробелы в коде, jQuery, сам PHP, то рассказать об этом стоит в каком-нибудь другом треде.
Не придирайся к знанию английского языка, анон пишет как умеет.
Ах да. Если тебе кажется, что что-то в учебнике или задачах можно сделать лучше — пиши, обратная связь всегда очень полезна.
>> $this->sign ^= true; > ^ это не булев, а целочисленный (побитовый) оператор. Он работает с числами а не true/false.
У меня была идея использовать его вот так: вот есть знак, допустимое множество принимаемых им значений: ['+', '-']. В таком случае логичнее знак выразить через булевый оператор, да и в PHP нет enum'ов. Знак дроби нужно будет менять. Для смены знака можно использовать код вроде "Если знак true, выставить ему false, если знак false - выставить true". А можно сделать без условий вот так: $this->sign ^= true; Этот код будет всегда менять знак на противоположный, пример на пике [NUMBER] На пике часть его таблицы истинности. XOR ведь ещё для шифрования из-за обратимости используется, поскольку false ^ true ^ true даст false. Если знак инвертировать 2 раза, то мы получим тот же знак, что и был у нас изначально. Я в упор не вижу какого-то более простого и очевидного решения? В любом случае, как я и говорил, это подразумевает необходимость возиться со знаками. Хотя ещё была идея абсолютно все действия выражать через Addition (Power выражается через Multiplication, который в свою очередь выражается через Addition). Это позволило бы возню со знаками сконцентрировать в одном месте, в классе Addition.
> Чему равен корень из 2? Это так называемая бесконечная дробь, которую нельзя представить в виде рационального числа. Получается, надо либо запретить возводить в дробные степени, либо запретить возводить в степени, которые дают иррациональное число (метод Роскомнадзора), либо придумать метод выразить результат приближенно (увы, теряя точность). > Неплохо бы помечать полученные в результате округления значения специальной пометкой. То есть делать для каждой SimpleFraction флаг, отвечающий за точность/неточность? И исходить из того, что точная дробь оператор неточная дробь даст неточную дробь? Всё-таки склоняюсь к тому, чтобы запретить возводить число в степень дроби, предварительно делая проверку на логарифм. То есть 9 ^ 1/2 возводить можно, потому что 2 - логарифм 9-и по основанию 3. 9 ^ 1/3 возводить уже нельзя, потому что ни одно число в 3-й степени не равно 9-и.
>> return (string) floatval(bcdiv(...)) > floatval делает преобразование в float. float даже в 64-битном пхп сохраняет не более 14 значащих цифр Там precision у bcdiv 20, то есть он всегда дробную часть добивает нулями. Тогда нули убирать регулярками/фунциями для манипуляций со строками?
>>793705 (OP) Привет, аноны-мастера. Есть тут кто-то, кто поможет не опытному разобраться с проблемой? Суть, собственно вот в чем: делаю сайт на Codeigniter(ТЗ, на должность джуниора) и все в общем хорошо получается, но вот не могу раздуплиться с Базой Данных. Мне нужно создать БД с тремя таблицами - не вопрос. создал (написал запрос SQL и отправил на сервак) и дальше прекрасно с ней работаю, но я не пойму как мене отправить это работодателю. Просто вложенный файл с запросом, или написать дополнительный метод метод и объяснить им что он делает. Собственно не имея опыта я и хочу разобраться как лучше сделать
>>773648 >И наконец, в некоторых местах, ты обращаешься к массивам вроде $_GET или $_COOKIE, не проверяя перед этим, есть ли в них такой элемент:
>Helper::redirect($_GET['go']);
>Но ведь он может и отсутствовать. Лучше использовать функцию, вроде $this->getQuery('go'), которая делает нужную проверку. А куда поместить метод getCookie('cookieName')? Мы скорее обращаемся к ним и на заглавной странице и в хелперах, а не в контроллере. И нужен ли метод getPost('postName')? Все равно данные пришедшие из $_POST обрабатываются в классе формы: https://github.com/someApprentice/Students/blob/master/app/Model/Entity/Forms/RegisterStudentForm.php#L19
>>773648 https://github.com/someApprentice/Students/blob/master/app/Model/Helper/Helper.php#L6 >Редирект, кстати, я подумал, логичнее было бы поместить в базовый класс контроллера. Тогда редиректить можно будет только из контроллеров. А это разве не задача модели? Контроллер же должен только работать с пришедшими данными и обращаться к модели.
В твиттере и фейсбуке разлогинивание происходит тоже через форму. Правда там какой-то странный синтаксис. Выглядит это примерно так:
Как это сделано? Ведь тэг button и форма никак не связанны. С помощью js? А если пользователь отключил его то такой способ не подходит? Почему нельзя просто добавить <input type="button"> внутри формы?
Ребята, столкнулся с проблемой с CRON Есть скрипт который добавляет строку в таблицу Базы Данных. Запускаю чего через CRON каждую минуту. Настройки выставлены правильно, техподдерка моего хостинга так же говорит что проблема с моей стороны. Итак как видно на пике, я выставляю как положено настройки чтобы скрипт запускался каждую минуту, но вот каждый час скрипт запускается лишний раз. Я так понимаю, скорее всего и каждый день\месяц и т.д. будет лишний запуск. Возможно я неправильно пишу команду? Может wget здесь нужно заменить на что-то другое? С кроном никогда не работал, гугл молчит, схожих проблем я там не смог найти, как починить не знаю, уже отчаялся, спасайте.
Поясните чем плоха такая конструкция в контексте производительности: (SELECT FROM `filmmeta` WHERE id =10) union (select ,null,null,null from filmfields where filmid=10)
> А можно сделать без условий вот так: $this->sign ^= true; Нельзя, попробуй сдампить var_dump(true ^ false ) - будет число а не булевое значение. Можешь еще заодно посмотреть например чему равно 35 ^ 63. ^ работает с числами.
Знак представляют в виде +1/-1 и тогда его можно умножать. Но тут в этом нет смысла, можно сделать чтобы знаменатль был всегда положительным и тогда знак дроби зависит только от числителя.
> Хотя ещё была идея абсолютно все действия выражать через Addition (Power выражается через Multiplication, который в свою очередь выражается через Addition). Это будет нереально медленно.
> То есть делать для каждой SimpleFraction флаг, отвечающий за точность/неточность? И исходить из того, что точная дробь оператор неточная дробь даст неточную дробь? Да, как вариант. И такие неточные дроби всегда выводить как десятичные например.
> Всё-таки склоняюсь к тому, чтобы запретить возводить число в степень дроби, предварительно делая проверку на логарифм. А нельзя проверять что получилось целое число? Хотя, при работе с float гарантий что оно дейсивтельно целое, нету... Можно попробовать получившееся число возвести обратно в квадрат с bcmul и проверить что ответ совпадает с исходным, точным числом.
> Там precision у bcdiv 20, то есть он всегда дробную часть добивает нулями. Тогда нули убирать регулярками/фунциями для манипуляций со строками? У тебя по идее знаменатель и числитель целые ведь. Зачем что-то добивать?
> В контроллерах нужны оба этих класса. Если наследовать их, то можно будет обойтись только одним. Это не повод для наследования. Наследование это отношения вида "А является Б" и тут это явно 2 отдельных не связанных друг с другом класса.
> А куда поместить метод getCookie('cookieName')? В хелпер например.
> И нужен ли метод getPost('postName')? Можешь сделать если хочешь.
>>Редирект, кстати, я подумал, логичнее было бы поместить в базовый класс контроллера. Тогда редиректить можно будет только из контроллеров. > А это разве не задача модели? Контроллер же должен только работать с пришедшими данными и обращаться к модели. ты не понимаешь MVC. Модель не взаимодействует с внешним миром и не отвечает за интерфейс пользователя. Она управляет данными, внутренним состоянием программы (в твоем случае - списком стдентов).
Редирект это взаимодейсвтие с браузером пользователя, это интерфейс. Вот представь что мы работаем с твоей программой из командной строки. Какой смысл имеет в командной строке редирект? Никакого, это часть протокола HTTP. Значит, в модели ему делать нечего так как модель - это код, который не зависит от способа взаимодействия пользоваетля с программой.
> Как это сделано? Ведь тэг button и форма никак не связанны. С помощью js? А если пользователь отключил его то такой способ не подходит? Да, наверно через js. Хотя в HTML5 вроде есть какой-то атрибут чтобы привязать кнопку к форме по id.
> Почему нельзя просто добавить <input type="button"> внутри формы? Не знаю, спроси у автора кода.
>>794749 А хуле в вакансиях пишут по 5-8к хрювен? Или я что то не так делаю и не там смотрю(смотрю сайты типа работы.юа, доу.юа и т.д.)? Как "правильно" искать первую работу? Мб есть какие-то вакансии о которых я не знаю? Мне говорят в моем городе есть дохуя вакансий и типа все ищут но на том же доу и работе нихуя нет вообще.
>>794753 1) Джун это 0.5-1 год опыта работы, зп обычно 600-800 2) Тебе нужна стажировка/интернатура/трейни, там как раз платят 300 баксов и тебя скорее УЧАТ чем ты работаешь
Где искать? В любой крупной компании. Циклум, люкс, софтсерв, епам и глобал по 200-400 человек в год набирают.
>>794768 Упс, слегонца тредом ошибся, думал это в МЫ ВАМ ПЕРЕЗВОНИМ, лол. Ну, на пхпшников они набирают заметно меньше, но если ты хорошо знаешь жс, то можно найти и там нечто подобное. Обычно на пхп набирают компании попроще, ибо в сириус интерпрайз говне пхп особо не живёт.
>>794753 Значит город у тебя маленький или ты смотришь вакансии на которых оформляют по трудовой. Нормальная ЗП джуна в украинском городе с населением от миллиона это начиная от $500. Есть еще вакансии стажеров, но это вообще рабский труд, не рекомендую.
>>794780 Это пиздец какой плюс, особенно если ты можешь по ним всё объяснить и это не хеллоу ворлд. Проектик на фреймворке, с тестиками и прочим в глазах работодателя будет выглядеть просто збс.
В таблице mysql записи вида user (id, name) values (1, 'Иванов Иван Иванович'), (2, 'Иван Иванович Иванов'), ... (33, 'иван(несколько пробелов)иванович иванов')
Задача: как убрать повторяющиеся записи, если они не посимвольно совпадают?
Есть ли книги по пыхе для НОВИЧКОВ? Писать хеллоуворлды для школьников по смищному найду из народа сру не хочу, меня все же интересует архитектура языка, веб-сервера, взаимодействие с бд и т.д. То что в оп-посте нацелено на уже знающих пыху. Мимо собираюсь учить пыху паралельно с джавой аналог книги которую я хочу это хуйня по джаве от Г. Шилдта
Оп, как доставать превьюшки, если они в папке file_sharing/uploads/2016/месяц/день/thumbnails, а корень сервера, где лежит индекс и ксс, в file-sharing/public? Перенести их в public (корень сервера)? Перенести не только их, а все загруженные файлы в public?
>>794931 То чувство, когда пошел качать книги порекомендованные оп-ом, они в формате djvu, полез качать ридер под это дело, зашел на первый в списке гугла сайт с приятной наружностью. Скачал их читалку, а эти пидоры поимели меня, установив кучу параши уровня амиго, мейл.ру, одноклассников и вообще блядь просто реально около 10 софтин без спроса в том числе новый какой-то сраный браузер и блядь сломали старые браузеры. Сука я от злобы нахуй аж винду снес блядь.
Вот ты на своем примере убедился насколько убого сделаны с точки зрения безопасности настольные ОС. Любая установленная программа получает полный доступ к твоему компьюетру. С таким подходом ставить можно только какие-то широко известные программы с открытым кодом.
Мне в этом плане нравится как сделаны айфоны (где все модерируется), ну и андроид (он похуже: разрешения при установке показывает но отключить например доступ в интернет не позволяет).
Не забудь после удаления программ переустановить браузеры и сменить пароли - возможно что доступы к сайтам тоже украдены.
Посоветуйте какую-нибудь библиотеку для написания парсера. Типа чтобы удобно было вытаскивать нужный контент со странички. Где-то видел название одной, но забыл.
Есть строка. SELECT * FROM stat WHERE datetime_now = (SELECT max(datetime_now) FROM stat) Достает из базы строку с последней датой. Как мне достать теперь строку с датой на минуту меньше? Всякие dateadd не работают, ну или я рукожоп. Тип DATETIME если что.
Котаны, нужно сделать сайт риелтору. На сайте должен быть каталог с его недвигой и собственно поиск по этому каталогу с помощью ключевых тегов. Самому риелтору нужна админка, чтобы добавлять и удалять недвигу из каталога.
> попробуй сдампить var_dump(true ^ false ) Я забыл скастовать в bool. Примеры на пике. Но я таки увидел простое и очевидное решение - это оператор отрицания. В таком случае операция смены знака могла бы выглядеть так: $this->sign = !$this->sign. Стыдно, что раньше не заметил, сам оператор даже называется "отрицание".
>> Всё-таки склоняюсь к тому, чтобы запретить возводить число в степень дроби, предварительно делая проверку на логарифм. > А нельзя проверять что получилось целое число? Хотя, при работе с float гарантий что оно дейсивтельно целое, нету... Да, var_dump(pow(9, 1/2)) выдаёт float(3). А вот JavaScript для Number.isInteger(Math.pow(9, 1/2)) выдаёт true.
> Можно попробовать получившееся число возвести обратно в квадрат с bcmul и проверить что ответ совпадает с исходным, точным числом. Не понял что значит "возвести обратно в квадрат с bcmul" и зачем там bcmul. Возьмём пример 9^1/2 Исходное число 9 нужно возвести в степень 1/2, делается только так: pow(9, 1/2). Как я уже писал раннее, функция pow - единственная функция, которая может возводить в дробные степени, но она ограничена битностью ОС, на которой запущена. Короче от pow(9, 1/2) получили float(3). Теперь нужно проверить, что 3^2 === 9. Опять берём pow, bcpow не подходит, так как: 1) Отдаёт результат в строке, проверка float(3) === string(3) не пройдёт; 2) Мы изначально пользовались pow, может возникнуть ситуация, когда pow(очень_длинное_число) != bcpow(то_же_самое_очень_длинное_число)
Вот взял я pow, но pow(3, 2) !== int(9), так как pow возвращает float. Использовать нестрогое равенство (==) нельзя, так как pow(pow(9, 1/3), 3) == 9, что неправильно. Вот здесь подробнее: https://ideone.com/I6onbw Да и что делать с очень большими числами, которые pow не может обработать? Чувствую, что во мне говорит леность и слабость, но всё-таки: может PHP не самый удачный язык для настолько точных расчётов и больших чисел? Алсо, если вводить ограничение на длину вводимых чисел, как определять, что число слишком большое для данной битности ОС?
// $a и $b преобразуются во float - возможная потеря точности $result = pow($a, $b);
// $result имеет тип float - он неточный
Затем мы делаем такой трюк: возводим $result в квадрат с помощью bcpow (без потерь точности). Сравниваем результат возведения (строку) с $a (строкой). Если они совпали - результат (после преобразования в строку) оказался точный, если нет - мы потеряли где-то на конвертации во флоат или при взятии корня и имеем приблизительный результат.
Вообще, конечно, правильнее не писать это самому, а искать готовую библиотеку. Но с дробями сложность в том что корень из некоторых чисел (например корень из 2) в принципе невозможно посчитать точно. Он будет бесконечной непериодичной дробью, иррациональным числом, не представимым в виде a/b. Потому библиотека вроде bcmath ничем помочь не может.
Я уже писал выше, что чтобы работать с иррациональными числами, нам нужно хранить их как есть, то есть "корень степени a из b" и это приведет нас к тому что надо оперировать не числами, а выражениями вида "корень из 3 плюс корень из 2".
В твоем примере результат неточный, потому после возведения в куб не совпадает с исходным числом.
> Да и что делать с очень большими числами, которые pow не может обработать? Ничего не поделать. Хотя имея точное представление числа можно определять что оно выходит за диапазон флоата.
> Чувствую, что во мне говорит леность и слабость, но всё-таки: может PHP не самый удачный язык для настолько точных расчётов и больших чисел? Сам по себе - не удачный, нужна мат. библиотека.
> Алсо, если вводить ограничение на длину вводимых чисел, как определять, что число слишком большое для данной битности ОС? Посмотреть пределы в мануале или погуглить IEEE 754. на хабре есть статья.
Решил вместо работы над ошибками в задаче Кошки-мышки, систематизировать все свои ошибки в предыдущих задачах, на которые указывал ОП. Вот что получилось.
>>795255 > то есть "корень степени a из b" и это приведет нас к тому что надо оперировать не числами, а выражениями вида "корень из 3 плюс корень из 2".
Я не смогу это реализовать. Даже если я добавлю объект "Иррациональное число" с дробью и подкоренным выражением. Как вклинить, например, выражение "V(2) + V(3)" (Корень из 2-х + корень из 3-х) в алгоритм сортировочной станции, это выражение не вычисляется. Просто игнорировать сортировочная станция его не может, так как потом может появится ещё один корень из 3-х и его уже нужно будет считать вместе с предыдущим V(3). Может быть более сложное выражение, вроде того, что на пике, нужно из начального 3-х этажного корня получить упрощённый.
Ребят, накидайте каких-нибудь задач небольших, для нереального тупого человека, что бы заставить мозг немного думать. Что-то уровня вывести Х звездочками в прошлом треде, что бы нормальный человек справлялся за 5 минут.
И желательно несколько, что бы не сидеть на одной вечность в случае чего, а решить например 2 из 10, и вроде как и не совсем отбитый.
Если что, то заача с иксом:
Дано число на ввод например 5, нужно на выходе сделать вот такую хуйню: | | | | | *
Сап. В общем решил вкатиться в PHP. И посему ищу себе для этого дела наставника\преподавателя который обьяснит мне что к чему и куда идти. Мои навыки довольно плачевны и опыт работы с PHP наверное чуть больше 10 чсасов. Моя конечная цель - написать полноценный блог. Написать магазин. Написать форум.
Если кто-то из местных заинтересован, пожалуйста отзовитесь.
За работу плачу деньгами. Связь будем держать по скайпу или RC. Для наставничества есть TeamViever. Если кто-то заинтересован - отпишитесь пожалуйста.
Есть SVG <symbol id="svg-5-star" viewBox="0 0 5120 1024"> <path d="M0,1v1024h1024V1H0z M982.029,44..... в таком виде, добавил их в футер, почему отображается только на главном домене и на поддоменах без параметров в адрессе? (Только на site.com, *.site.com и соответственно не отображаются уже если site.com/index.php или site.com/?blabla=x)
>>793705 (OP) Прошел учебник в ОП-посте, очень понятный и оформлен круто, жаль что там мало. Спасибо тому кто это сделал. Перешел к задаче с абитуриентами, возник вопрос какую sql-api мне юзать? mysql, говорят, устарел и к применению не рекомендуется.
>>795984 Остановился на mysqli, он как то проще выглядит. Чет я немного подохуел с резкого скачка сложности между уроками ОП-поста и документацией sql-api. Но в целом норм.
>>794751 >Редирект это взаимодейсвтие с браузером пользователя, это интерфейс. Я не знал об этом. Хоть это и логично, я не смотрел на это с такой стороны. Спасибо.
https://github.com/codedokode/pasta/blob/master/student-list.md#Постраничная-навигация >Можно сделать удобный класс для расчета числа страниц и формирования ссылок на переход на нужную страницу. В конструктор мы передаем общее число записей, число записей на странице, шаблон для ссылки, после чего может генерировать ссылки для перехода: >$pager = new Pager($totalPages, $recordsPerPage, 'index.php?page={page}'); А обязательно шаблон для ссылки передавать? Ведь можно в самом шаблоне писать <a href="?page=<?= $page ?>">, и ссылка будет перенаправлять на текущую страницу + запрос с гетом.
>>794768 Какой пиздец. Аноны, расскажите какой верх мечтаний у пхп погромиста? 99% вакансий это гавностудии, что поддерживают интернет магазины с женским бельем и штопают разовые сайты-визитки.
>>796419 Завтра ищешь в интернете книжку Джанед Вайленд "PHP5 для чайников" - полное руководство, похуй если ничего не поймешь. Затем идешь на http://php.net/manual/ru/ и изучаешь стандартную библиотеку от корки до корки. Потом зубришь, именно, сука, вызубриваешь конвенцию по написанию питоньего кода - PSR-2, чтобы от зубов отскакивало. Когда напишешь свою первую имиджборду, по пути изучив верстку на html+css, скачиваешь и изучаешь любой асинхронный вебсервер, рекомендую nginx. Как переделаешь имиджборду, чтобы выдавала по крайней мере 5 тысяч запросов в секунду, можешь идти дальше - тебя ждет увлекательный мир фриланса. CRM'ки, стартапы, сверхбыстрые HTML5 браузерные игры, MySQL. Отсос хиккующих выблядков / просто неудачников типа рейфага или сисярп/джава-хуесосов, которые сосут хуй по жизни не заставит себя ждать и уже через пол года ты будешь получать такие суммы, что любая баба будет теч при одном упоминании твоей зарплаты.
>>794753 расскажи нахуя программисту искать вакансии только в родном городе/стране? тебя забанили на upwork? не умеешь в английский? пиздуй вон из профессии даже это не беда! hh.ru яндекс.работа | grep поргомист | grep удаленка ... PROFIT
>>796712 Composer де-факто стандарт. Либо качать архив с исходниками.
>sompfony Symfony
>>796470 Там автотестов (когда твоё решение проверяется на сайте) нет что ли? Или решения на PHP не поддерживаются сайтом? Попробуй leetcode ещё. Там PHP нет, я на JS решаю, но разница в задачках на алгоритмы небольшая.
>>796357 Да никак, если это твой проект и ты пишешь всё с нуля, а не за кем-то говно чистишь, то лучше перепроектируй с нуля так, чтобы глобальные переменные вообще не использовались. И возьмись за PDO. Если интересно, то про глобальные состояния ОП писал в пасте про DI.
Написал едва рабочий и очень простой вариант кошек-мышек. Такое даже стыдно наверное показывать должно быть, но ничего, придется через этот стыд пройти. http://ideone.com/GF79ti
Вангую что это нифига не правильное ООП. Хз что пытался изобразить. Разгромите, кому не лень читать этот говнокод, меня в пух и прах.
В общем я пытался сделать так, что бы животные друг с другом воздействовали через "мир", ведь они что бы видеть друг друга, должны как бы смотреть вокруг себя, ну вы поняли. А делать так что бы животные смотрели на всех других животных перебирая массивы - как-то НЕРЕАЛИСТИЧНО ЧТО ЛИ Поэтому попытался вот такое вот реализовать. Ну а дальше весь этот бред оттуда и вытекает.
Я не понимаю, почему композер скачивает там много файлов на библиотеки js, если я буду пользоваться двумя файлами (в данном случае video-js.min.css и video.min.js? Что мне делать с этой папкой? Искать эти два файла и копировать в корень сервера?
>>794978 Такой же вопрос опу теперь по видео. С превьюшки я думаю еще допустимо хранить в корне сервера, но куда видео то ложить, если папка с загрузками выше корня сервера.
$pager = new Pager($records, $currentPage = $this->getQuery('page'), $recordsPerPage = 10);
...
У меня getQuery($query) вбросит исключение если запроса не будет существовать, но ведь этого запроса может и не быть. Например, если мы только открываем страницу, то запроса о номере страницы быть не должно, и по стандарту должны выводиться записи с первой страницы. Я не правильно написал метод getQuery и не понимаю когда должны вбрасываться исключения?
Аноны, вопрос, как вообще разобраться сколько контроллеров нужно использовать?
К примеру, я пишу файлообменник. Там 3 страницы, проще будет сделать один контроллер, но с другой стороны было бы логичней под одну страничку один контроллер, вообще не понятно
>>796949 Не люблю, когда куча говна, которое не используется никак. Вот часть файла, которая идет с бутстрапом. Вся эта лапша вида .style-1, .style-2, style-3{} - какое же говно говняное и говнистое. Ради пары колонок, нескольких таблиц и кнопок держать всю эту парашу ебааааную? Чтобы просто былО? Приходится, потому что потом можно взять и что-то ещё использовать, но бесит такое.
Каждой странице соответствует одно действие (экшен). Иногда на каждое действие делается свой контроллер, но обычно действия из одного раздела сайта группируются вместе в один контроллер. Ну например список новостей и просмотр новости можно сгруппировать в один контроллер новостей.
Если ты используешь микрофреймворк слим то все контроллеры - это функции в index.php
Ты можешь сделать свою сборку только с нужными тебе вещами (всем советую делать именно так).
Ты в принципе не обязан использовать бустрап. Можно верстку делать самому. Но бутстрап экономит время + позволяет тебе его изучить. Его довольно части используют для всяких внутренних страниц (админка) чтобы не возиться с стилизацией таблиц и форм.
Ты пишешь как будто это что-то плохое. Я наоборот считаю что плохо не уметь верстать. Ленивые и некомпетентные разработчики любят придумывать предлгоги чтобы что-нибудь не изучать.
>>Некоторые пытаются возложить на объект Pager лишние функции, например чтение параметров поиска из $_GET или подсчет числа записей в базе. > Значит этим должен заниматься контроллер? Да. Надо уметь писать более универсальнй код. Не надо писать функции которые берут данные из GET - лучше писать функцию которая получает на вход аргументы.
> $pager = new Pager($records, $currentPage = $this->getQuery('page'), $recordsPerPage = 10); Не надо так писать. $currentPage = $this->getQuery('page') это отдельная команда которая должна быть на отдельной строке.
> У меня getQuery($query) вбросит исключение если запроса не будет существовать Тебе нужна другая функция которая не выбросит исключение, а вернет 1.
> Я не правильно написал метод getQuery и не понимаю когда должны вбрасываться исключения? Скорее всего неправильно. Все GET параметры приходят от пользователя и могут отсутствовать.
Либо держать файлы в публичной папке либо настроить сервер на отдачу их из непубличной папки. Например есть расширение Апач x-sendfile которое позволяет php-скрипту выдать заголовок, апач его перехватит и начнет отдавать пользователю файл. Также можно сделать переназначение УРЛ через mod_rewrite
"лень разбираться" не приветствуется в нашем треде и не считается уважительной причиной. Есть мануал, прочитай, в идеале - английскую официальную версию.
У тебя должна быть система публикации скриптов. В простейшем случае - просто скрипт копирующий файлы в публичную папку, в сложном случае - система, склеивающая и минифицирующая файлы. Просто композера недостаточно.
Запускать эту систему можно автоматически - композер позволяет задать скрипт который вызывается после установки или обновления зависимостей.
Ну либо есть еще вариант не использовать композер и руками загрузить нужные файлы.
>>797253 >Если ты используешь микрофреймворк слим то все контроллеры
нет, я решил сразу освоить нужный мне фреймворк самый популярный Laravel, хотя понимаю, что для такой задачи подойдет и простенький, но хочется убить два зайца сразу
> public function move (World $world) { Вместо того чтобы передавать сюда World, удобнее передавать его в животное при создании либо при размещении на карте и сохранять в свойстве.
> if ($this->dead == false && $world->field[$this->x][$this->y] != $this->icon) { Вот тут мышь занимается не своим делом. Она лезет во внутренности мира: $world->field[$this->x][$this->y]. Но разве это задача мыши - определять, кто где находится? Очевидно, это задача мира. мышь просто должна вызывать метод вроде "есть ли кто-то на этой клетке?".
Мир спроектирован неудачно. Как в твоей реализации получить объект-животное по координатам? Или список животных в определенном радиусе? Ты хранишь маловажную информацию (иконку) а важную (сам объект со всей информацией) не сохраняешь.
Также, у тебя очень плохо сделано хранение информации о расположении животных. Допустим я поменял у мыши координату x или y. Где гарантия что массив $world->field всегда отразит это изменение? У тебя информация о животных хранится сразу в 2 местах: в самом животном и в $world->field и появляется риск расхождения, в животном будет одна координата, а на карте оно будет в другом месте.
Более того, у тебя иконка животного тоже хранится в 2 местах - в world и underworld и тут точно такая же проблема синхронизации.
От этих проблем проще всего избавиться, храня информацию только в одном месте без дубликатов.
И вообще, у тебя слишком много публичных полей. Надо закрывать к ним доступ и разрешать только делать ограниченный набор действий через методы. Это называется инкапсуляция. Сделай все поля непубличными. Плюс, не выдавай массив field наружу, а сделай методы вроде "получить список животных в радиусе вокруг точки".
То есть для начала придумай какие у тебя классы, за что они отвечают и какие у них будут публичные методы. А потом уже пиши код.
Функцию move надо разбивать на подфункции, а не писать код стеной.
> if (isset($world->field[$this->x][$this->y - 1]) and ($world->field[$this->x][$this->y - 1] == $world->filler)) { > $directions[] = array($this->x, $this->y - 1); > } Это копипаста. не копипасть.
Алгоритм оценки ходов, который я рекомендовал, не рализован.
Имей в виду что в ларавели много сомнительных вещей - например злоупотребление статическими методами и глобальными функциями, это первое что бросается в глаза. Как у них сделана работа с базой данных. мне тоже не нравится.
>>797271 может быть, но согласись, многие так же думают про php, в плане сомнительности, но ничего живет и развивается же как-то, учу из-за того, что самый популярный, а значит больше шансов найти работу
Я не совсем еще не дошел до этого, но вроде как там используется ActiveRecord или Eloquent, мол создаешь модель и это таблица в бд, создаешь обьект и создается строка в той таблице, свойства обьекта - атрибуты таблицы.
Их подход приводит к тому что один класс занимается несколькими вещами - хранит информацию о объекте, работой с базой данных, валидацией. Это известный недостаток active record и он здорово портит код в больших приложениях, так как модели сильно раздуваются.
Но в общем, я думаю, изучить фреймворк будет полезно.
> function inclineWord($number, $word1, $word2, $word5) { Последний if не нужен.
> if ($number == 0) > return "ноль"; надо ставить фигурные скобки.
> array_push($temp,$spelling[$hundreds]); Удобнее писать $temp[] = ...
Кстати название $temp не годится, оно ничего не значит.
> $text = preg_replace("/ноль/u", "", $text); > $text = preg_replace("/ +/u", " ", $text); Это кривые костыли и они затрудняют понимание и поддержку кода. Если у тебя ноль сотен, не надо просто класть такое слово в массив.
> array_push($temp," (".$number.") ".inclineWord($ones,"рубль","рубля","рублей")); > } else { > array_push($temp," (".$number.") рублей"); Эту строчку не надо копировать 2 раза, достаточно написать один раз.
> 2. http://ideone.com/qFJOX5 Здесь лучше разбивать preg_split с флагом PREG_SPLIT_NO_EMPTY так, что сразу получится массив только из чисел.
> 3. http://ideone.com/SA4FYT Надо ставить фигурные скобки. Вместо копипастоы ифов лучше сделать массив с цифрами и словами и циклом искать совпадения в нем.
> 4. http://ideone.com/Of9mKI Не читал условия, но разбивать лучше preg_split (чтобы поддерживалось любое число пробелов), а для перемножения любого числа элементов есть готовая функция array_prod по моему
Модель это такая вещь в себе, которая управляет данными (списоком студентов) и никак не взаимодействует с внешним миром. И она не знает откуда ей приходят команыд и куда уходят ответы. Потому за редиректы она никак отвечать не может. Она получает все данные через аругменты при вызове функций.
> А обязательно шаблон для ссылки передавать? Нет. Не передавать даже будет правильнее, так как задача пейджера считать номера страниц, а не генерировать ссылки.
> Ведь можно в самом шаблоне писать <a href="?page=<?= $page ?>">, и ссылка будет перенаправлять на текущую страницу + запрос с гетом. Можно но лучше вынести генерацию ссылки в отдельную функцию, тем более что там нужно добавлять параметры для сортировки и поиска. И для первой страницы параметр page не требуется.
https://github.com/TheSidSpears/Students/blob/master/router.json Вот тут я не уверен что в роутере должен указываться вью. зачем? Ты планируешь один вью с несколькими контроллерами использовать? Это вряд ли получится, так как вью привязан к своему контроллеру и не совместим с другими. И даже если он совместим, при правке это легко сломать. Ангалогично мне кажется нет смысла в роутере указвать заголовок страницы (если только ты не используешь это еще например для меню - и то, наверно выгоднее как-то в контроллере это хранить).
Опять же, редактирование переусложнено. Надо радикально упрощать код, убрать наследование, убрать код из конструктора. Свойства во многих случаях проще заменить на обычные переменные.
Метод showView тоже назван неудачно. Логчинее назвать его "обработать запрос" и сделать абстрактным в базовом контроллере.
> $array=file_get_contents($filename,FILE_IGNORE_NEW_LINES); Имя переменной не соответствует тому что она хранит
> LIMIT :y OFFSET :x"); Неудачные названия плейсхолдеров
> $rows = $this->db->prepare("SELECT FROM `students` ORDER BY $sortBy $orderBy LIMIT :y OFFSET :x"); > if (isset($search)) { > $rows = $this->db->prepare("SELECT FROM `students` WHERE CONCAT(`name`,' ',`sname`,' ',`group_num`,' ',`points`,' ',`gender`,' ',`email`,' ',`b_year`,' ',`is_resident`) LIKE :search ORDER BY $sortBy $orderBy LIMIT :x,:y"); Получается первый prepare был сделан зря? зачем тогда его делать?
В student->addInfo есть проблема. У тебя нет фильтрации по разрешенными полям и пользователь может менять любые свойства студента в том числе те, которых нет в форме. ну например что если мы добавим колонку is_admin - пользователь сможет передать $POST['is_admin'] = 1 при редактирвоании. И кстати об этом было написано в моем уроке.
Так да, я это и писал, если мы разрешаем иррациональные числа то мы вынуждены оперировать выражениями произвольной сложности так как упростить их невозможно.
Потому варианты такие:
- запретить брать корень вообще - запретить брать корень если результат нерациональный - разрешить брать корень, но округлять результат с потерей точности до десятичной дроби
Превьюшки можно перенести в публичную папку, да и загружаемые файлы в общем тоже. Либо настраивать их скачивание: через mod_rewrite либо через x-sendfile.
> https://ideone.com/t2U2f3 С "а" или "но" ненадежно сделано - перед ним может быть не только запятая, но и например двоеточие или другой знак. Пробел не обязательно будет ровно один.
Не знаю, может обратиться в техподдержку? Это ведь не официальный крон а веб-морда к нему. Также, плохая идея рассчитвать что скрипт будет вызван определенное число раз - а что если сервер перезагрузят?
>>797257 >> Я не правильно написал метод getQuery и не понимаю когда должны вбрасываться исключения? >Скорее всего неправильно. Все GET параметры приходят от пользователя и могут отсутствовать. Но ведь исключения нужны для программистов, которые могут неправильно написать запрос...
>>797315 Поменять мышление: вместо "не могу" - "не хватает упорства". Затем распределить свое время на мелкие отрезки чтобы упорства хватало. Рим тоже не один день строился.
Всё по максимуму переведено на bc-функции, можно использовать большие числа. Токены из лексем определяются поточно (если я правильно понял "поточно"), с использованием стека, позволяющего учитывать предыдущий токен (чтобы отличать унарные операторы от бинарных). За отображение точности/неточности отвечает тильда.
>>795255 > У меня идея такая: > Затем мы делаем такой трюк: возводим $result в квадрат с помощью bcpow (без потерь точности). Сравниваем результат возведения (строку) с $a (строкой). Если они совпали ... Не знаю, что бы я делал без этой подсказки, спасибо. Всё упиралось в то, что pow(1.4142135623731, 2) округляет результат до двойки.
>> Там precision у bcdiv 20, то есть он всегда дробную часть добивает нулями. Тогда нули убирать регулярками/фунциями для манипуляций со строками? > У тебя по идее знаменатель и числитель целые ведь. Зачем что-то добивать? Мне следовало весь контекст обсуждения запостить. Суть: bc-функции не умеют сами определять, с какой точностью после запятой отображать результат. Если не указывать scale (количество знаков после запятой), то по умолчанию bc-функции отображают только целую часть ответа. Если указать scale, к примеру 50, то в bc покажет именно 50 символов после запятой, не забывая добить результат нулями справа. Я счёл логичным написать мелкую обёртку, которая эти нули с конца будет удалять. В результате SimpleFraction будет быстрее упрощать себя, так как числа меньше. (0.1 => 1/10, а без удаления нулей было бы 0.100...N => 100...N/100...N+1, где N - кол-во нулей).
>>792629 >Ну а НОК легко считается через НОД. Реализуй алгоритм Евклида Нашёл функцию gmp_gcd. Взял её, так как моё решение будет медленнее.
>У тебя парсинг оказался разделен на 2 части: проверка синтаксиса и сам парсинг. Сейчас объединил парсинг и валидацию. Это позволило вообще не использовать регулярки для валидации, но код, как это обычно происходит в моём случае, стал ещё запутанней.
>> str_pad("Выражение в инфиксной нотации", 61) > Она не умеет считать русские буквы, имей в виду. Я так понял, это справедливо для всех str_* функций без префикса mb? А как тогда выравнивать? Сделал sprintf'ом.
В какой кодировке сохранять файл cli php или что прописывать в нём, что-бы не было такого
Какой фреймворк выбрать для проектаАноним16/07/16 Суб 13:52:57#115№797484
Привет, анон! Попался мне большой проект который я хочу выполнить качественно и хорошо (онлайн конструктор для оформления дома). Подскажи, на каком фреймворке его писать, что лучше юзать в процессе разработки над большим проектом?
>>797484 Symfony2 Но сам по себе он тебе ничего не даст. Symfony - просто инструмент, позволяющий реализовывать любые паттерны ООП. Вот они то тебе для большого проекта и нужны
Виндовая консоль не может отображать utf-8. Какие есть варианты?
- писать код в кодировке cp1251. Минус в том что код перестанет работать с utf8. То есть ради винды придется себя ограничивать. Под линуксом который по умолчанию поддерживает utf-8, буквы выводиться не будут.
- сохранять вывод скрипта в файл и просматривать файл редактором:
php script.php > result.txt
- не использовать кириллицу
- запускать свой код под линуксом. Линукс можно установить в виртуалку либо зарегистрироваться на c9.io (бесплатно) и запускать там. PHP там уже стоит.
Блять, просто ебаный пиздец, ненавижу сука, ебанный пхпсторм, почему сука его все так любят если хуй поймешь как вообще его юзать, блять, в нетбинсе за 2 секунды настроил дебаггер, а сука в пхпшторм уже два дня ебусь с ебучим дебаггером, куча сука непонятный настроек, хуй пойми для чего.
Вот на какой хуй мне нужно заполнять всякие ебанные веб сервет руты, если при написании web path, он продолжает мой сервер рут и выходит говно с слешем на конце, а нахуй мне всрался ебанный слеш на конце? Я хочу без него, а нихуя если сотрешь, то это будет не правильно, а может оставить пустой веб сервер рут и правильно заполнить web path? А вот нихуяшечки.
Обьясните нахуя я должен заполнять два поля если сайт сука у меня один, как вообще блять правильно вписать эти два ебаных поля, да и хуй там на каждом ебаном шаге ошибки хуишибки, делаешь сука, все в точности по инструкции и нихуя не работает, говно ебаное
>>797556 про зенд ничего не скажу Yii идеальный фреймворк для скоростного "хуяк-хуяк и впродакшн". Но в долгой перспективе на большом проекте подобный подход до добра не довоидт
>>797567 Спасибо. У меня есть еще такой "детский" вопрос. Например на кодигнайтере я могу с легкостью построить MVC и за минуту сделать пагинацию или валидацию и остальные муторные задачи, С симфони так же все, просто ты сказал что он сам по себе ничего не даст и я немного запутался.
Просто ты с одним фреймворком работал больше чем с другим.
Ты говоришь "могу настроить валиадцию" - а ты можешь валидировать не данные из POST, а например просто из массива или в объекте-модели?
Кодеигнайтер очень убогий, насколько я помню. Там контроллеры наследуются от ядра фрйеморка или как-то так. КАкие-то странные хаки вместо DI и автозагрузки.
>>797583 Это всё, само собой, есть и в Symfony Просто там, к примеру, та же валидация сделана так, что ты с помошью симфониевского встроенного валидатора можешь валидировать ВООБЩЕ любой обьект в своём проекте А в том же Yii - встроенным валидатором ты можешь валидировать только модели, унаследоанные, кажется, от ActiveForm. Но при этом он проще настраивается и проще разобраться, как им пользоваться. В итоге говнокодить получается куда быстрее. Аналогично со всеми остальными компонентами. В симфони - сложнее, но гибче. В Yii проще, но дубовей.
>>797608 Олсо Будет много таблиц в БД и мне хочется сделать все хорошо и правильно. Работаю с MySQL и PHP. До этого использовал БД в который максимум 5-7 таблиц и не шибко связанны между собой, а этот проект сулит большой объем. Так вот собственно моя просьба: подскажи, пожалуйста, какие посмотреть материалы для работы (книги, статьи). Особенно хочется понять как правильно построить архитектуру БД и оптимизировать ее. Никто не ответил в треде про БД так что пишу сюда
>>797631 https://symfony.com/doc/current/index.html Официальная дока, она у симфони очень хороша. Также обязательно прочти cookbook оттуда же >>797635 Уфф, это целая наука, которую в 3 словах не опишешь. В симфони используется ORM Doctrine2. Её главна фишка в том, что она любые обьекты со всеми их связями с другими обьектами позволяет нативно сохранить в БД. Поэтому ты должен проектировать не таблицы в БД, а (очень важно!!!) доменную логику своего приложения. Тобишь проектировать классы, которые будут делать то, что хочет от программы заказчик, и их взаимодействие между собой. А потом, особо не парясь про БД с помошью доктрины всё это хозяйство сохранять в БД.
>>797665 >Авось разберешься Добавлю ещё, что это все - высший пилотаж обьектно-ориентированного программирования. Если честно, я не уверен, что ни разу не варившись в больших проектах, в которых хотя бы частично применялся подобный подход, можно вот так вот легко взять и сходу во всё это врубиться.
Кстати именно по этому говорят, что Symfony - фреймворк для опытных разработчиков.
То, с чего я начинал - гибких фреймворк, позволяющий реализовывать самые продвинутые практики ООП. Но проблема в том, что сначала эти практики надо научиться применять....
>>797679 Спасибо! Я не в чем толком не уверен. времени есть месяца три для получения хоть каких-то результатов, но программистов набирают не ахти- пока я один и совсем не опытный. поэтому думаю что проект может быть лажовым.
>>797682 А, ну если заказчики неадекваты и набирают на сложный проект нубов - ну чтож, сами себе злобные буратины.
Значит делай любую херню за их счет. Хочешь симфони - бери симфони. Проект несомненно провалится, но ты не парься про это - это будет виной жадных заказчиков, жадничающих на сложный проект взять нормального опытного лида\архитектора.
Проект провалится - ты наберешься опыта - свалишь в место понормальнее. Дерзай.
>>797692 Если это французский повар с 20-летним стажем, то да, претензии в кассу, и его за такое надо уволить.
Но если владелец ресторана на должность шеф-повара берёт первого попавшегося мальчика с улицы, без опыта, только потому, что мальчик просит 500$ (вместо 4000$ которые надо платить профессионалу) - то какие могут быть претензии к мальчику?
Мальчика может и выпрут, но я бы на его месте не расстроился бы совсем. Опыта набрался - и ладно.
>>797688 ну я объяснил свой скудный опыт, но парня это не смутило. не знаю чего так. может никто из серьезных программеров не хочет браться за проект и остался только я. но все же ради опыта я согласен это сделать.
>>797694 >парня это не смутило. Он всё прекрасно понимает, но жадность - страшная вешь. Ну ничего - скупой платит дважды. АЛСО проваленный проект - тоже отличный опыт в копилку. По крайней мере в следующий раз ты уже будешь знать, как НЕ надо делать, и почему. Авось сможешь сделать выводы, почитать книжки, как надо делать, ещё раз сделать выводы и в следующий раз всё сделать правильно.
>>797688 А мне кажется связываться с заранее обреченным проектом это фэил. Ведь у тебя в портфолио будет провальный проект. Что ты будешь отвечать если спросят: "Ты работал над "ххх", почему оно не взлетело?" А ты такой "Ну потому что заказчик был злобный буратино" или "Была слабая команда" или "Проект был слишком сложным, запутанным и не продуманным". И каждый ответ против тебя, во всех случаях ты перекладываешь ответственность на кого-то другого, ведь ты сам вызвался работать над ним. А по поводу опыта, в первую очередь это будет опыт провала. Лучше найти что-то, что тебе по силам, и сделать это максимально хорошо, насколько ты можешь, даже если масштабам будет меньше.
>>797699 По пододу даже полного фейла я написал выше.
Кроме того между полным фейлом и полным успехом вообще то хуева туча промежуточных состояний. Не пугайте человека, совсем не обязательно всё пойдет по самому плохому пути. Вероятнее всего получится просто весьма хреново, но как-то там оно работать будет. Просто на определенном этапе станет очень сложно вносить изменения в проект и работать с кодом в стиле "взрыв на макаронной фабрике" неимоверно заебёт. Вот тогда и можно будет вал ить дальше. Предварительно сделав выводы из результатов работы.
>>797712 Врать ни в коем случае нельзя. IT сфера - большая деревня, все друг друга знают. Достаточно просто ... скажем так... умолчать о некоторых деталях прошлого проекта.
>>797689 >Сможешь сделать короче? Делать нечего ОПу, как письками меряться с нами. Померялся с тобой, у меня влезло в 102 символа: https://ideone.com/dgEMLQ
>>797885 1) Убери знак доллара у функции mt_rand. Знаком доллара предваряются переменные. 2) Функции mt_rand нужно передавать 2 параметра, ещё раз перечитай задание и объяснения, которые ему предшествовали.
>>797889 >>797889 блин всё было только из-за знака доллара. и с объяснения пропущенное сквозь глаза уловил... Спасибо за ответ теперь я тут буду завсегдатаем походу
Памагити!!! Положим, что у меня есть матрица размером 2 х n, dв одном столбце у меня даты формата 00:00:00, а в другом какие-то данные, в зависимости от этих данных я меняю текущую дату на день вперёд.
Привет, подскажите верно ли я разделил структуру приложения для задачи "Еще один кредит":
index.html - это html страница содержащая форму с тремя полями ввода и отправкой данных в "action.php" методом POST;
action.php - это php скрипт, который рассчитывает кредит и загружает шаблон template.html с помощью функции include;
template.html - это html страница в которой содержится логика отображения сообщений.
Получается, после отправки данных с помощью формы, пользователь попадет на страницу template.html, изменится ли адрес в адресной строке в браузере? Для того чтобы изменить данные и рассчитать кредит еще раз, пользователю нужно нажать назад, или кликнуть на ссылку ведущую на страницу index.html (для этого, мне нужно сделать эту ссылку на странице template.html)? Можно ли выводить сообщения на странице index.html, не переходя на template.html средствами PHP?
>>797315 https://github.com/TheSidSpears/Students/blob/master/router.json > Вот тут я не уверен что в роутере должен указываться вью. зачем? Ты планируешь один вью с несколькими контроллерами использовать? Это вряд ли получится, так как вью привязан к своему контроллеру и не совместим с другими. И даже если он совместим, при правке это легко сломать.
Мне на самом деле эта строка нужна была, чтобы указать в какой папке вью. Если заменю "view": "status/register_ok" на "folder": "status" - будет норм?
> https://github.com/TheSidSpears/Students/blob/master/app/container.php#L7 > Более того, ты возвращаешь массив непонятной структуры. Не лучше ли возвращать объект с методами для получения данных? - В чём заключается непонятность структуры? Ты предлагаешь делать методы типа getDBLogin(), getDBPass() и т.д. или как?
Аноны, можно ли сделать архитектуру в пхп полностью на классах как в джаве или я должен делать <?php ?> в хтмле и писать обыкновенные скрипты используя свои классы и функции в них?
>>798266 Почему? Файл template.html содержит и php код и html и наверное правильнее было бы дать ему расширение .tpl, но первый файл index.html полностью состоит из html'а?
И еще, как правильно писать в шаблонах конструкции с открывающимися и закрывающимися фигурными скобками ({}) или двоеточие (:) и endif (endfor) Например <?php for ($i = 0; $i < 5; ++$i): ?> Hello, there! <?php endfor; ?> или <?php for ($i = 0; $i < 5; ++$i){ ?> Hello, there! <?php } ?>
>>798300 ну как представление подключать я не ебу, я в джаве шарю на уровне написание консольной программки, ну по сути если без гуи создавать прогу, то аналогично как в джаве выходит.
А как присобачивать ко всему этому еще html уже хз
>>798301 >Сайты на Java Знатное извращение >>798302 Не аналогично. В джаве ВСЕ с чем ты работаешь - классы, здесь же дохуя скриптов которые как каша и это меня раздражает. Я бы просто хотел управлять хтмл файлами из классов
>Не аналогично. В джаве ВСЕ с чем ты работаешь - классы, здесь же дохуя скриптов которые как каша и это меня раздражает. Я бы просто хотел управлять хтмл файлами из классов
Сука почему нет то блять??? Ты думаешь зачем в пхп ООП сделали, по приколу?! Пишешь класс для взятия данных из базы. Пишешь класс для манипуляций данными. Пишешь класс для отображения данных( в html/xml/yml/xaml/json/rss/nebo/allah e.t.c.)
При альтернативном синтаксисе тело управляющей структуры заключается не в фигурные скобки а помещается между двоеточием и ключевым словом. Управляющие структуры, имеющие альтернативный синтаксис с закрывающими ключевыми словами: if - endif; while - endwhile; for - endfor; foreach - endforeach; switch - endswitch;
ВАЖНО: Смешивание синтаксиса в одной и той же управляющей структуре не поддерживается. Использовать альтернативный синтаксис удобно при использовании PHP в роли шаблонизатора - когда небольшой код PHP необходимо интегрировать в html шаблон. Например:
Мне кажется, шаблон лучше сделать один. Он должен отображать и форму, и результат, если тот есть. Тогда можно подправить какие-то параметры и снова отправить форму.
>Мне кажется, шаблон лучше сделать один. Он должен отображать и форму, и результат, если тот есть. Тогда можно подправить какие-то параметры и снова отправить форму. Один шаблон для формы, другой для вывода результатов. А возвращать шаблон, в котором подключен шаблон для формы и шаблон для вывода информации.
>Через шаблонизатор. Можно через встроенный в пхп. Php -это и есть шаблонизатор.
>Непраивльно писать без фигурных скобок или двоеточия. Ты ахуеешь, но можно.
Смотри, условно говоря всё так. У тебя есть логика, которая как раз ООП там классы и вот это вот всё. В ней ты как раз управляешь всем, в том числе и аштээмэлем.
Потом в одном классе, который отвечает за вывод будет написано что-то в духе:
$viewData['name'] = $user->name; $viewData['friends'] = $user->friends; ну и дальнейший сбор инфы, которая тебе нужна для вывода на сайте. далее ты пишешь например:
$main->loadView("userPage.php", $viewData); Это допустим метод подгрузки шаблона, с перешачей туда аштээмэль-параши.
>>798309 В каких еще скриптах? При нормальной архитектуре в php у тебя нет никаких скриптов, только классы, вызывающие другие классы, наследование, абстрактные классы, интерфейсы, полиморфизм. Скрипты только говнокодеры пишут.
>(анонам домашнее задание: разберите что делает эта регулярка) >preg_replace("/\d(?!$)/",'$0+','-123') Почитал немного, понячья магия какая-то. Как я её понял: Первый символ дефис, пропускаем его (но кладем в whole match). Следующий символ 1, подходит под \d. За ним не конец строки, значит negative lookahead заматчил единицу, в $0 добавляется 1+, -1+ в результате. $0 сбросился, так как lookahead отработал (именно из-за этой особенности, насколько я понял, для lookahead нельзя указывать квантификаторы, например вот так /\d(?!${1,2}), ведь проверяется только следующий символ. Дальше двойка, за ней не конец строки - матчим двойку, заменяем $0 (там сейчас только 2) на whole match с плюсом, конкатенируем с результатом, сбрасываем whole match. Следующий символ 3, за ним конец строки, тройку не матчим, но она добавляется в whole match.
Пацаны, какие цветовые темы вы используете? Я писал на с++, потом на с#, очень привык с темам vs, но на саблайм текс и пхпшторм они очень кривые какие-то. Нет тут дрочильщиков на темы vs? Перекидываться на другие как-то очень нет желания, у меня уже цвета в подсознании сидят.
Ты как-то странно объяснил работу preg_replace. Она ничего не накапливает. Она идет от начала строки к концу посимвольно и проверяет ее на совпадение с регуляркой. Если совпало - заменяет и идет дальше, если нет - переходит к следующему символу. Между проверками ничего не накапливается.
> Первый символ дефис, пропускаем его (но кладем в whole match). Мы никуда не кладем дефис, а просто оставляем как есть, не заменяя, так как он не совпал с регуляркой. Заменяется только то, что совпало.
?! нужен только чтобы сказать "за цифрой не конец строки". Как альтернатива можно писать (?=\d) но это длиннее.
> ${1,2} Тут ошибка, я не знаю, можно ли применять квантификатор к утверждению, но даже если и можно то это было бы бессмысленно. Ты можешь хоть 10 раз проверить условие конца строки, это ничего не меняет.
Упомянутые там ограничения относятся к lookbehind и связаны с особенностями реализации, чтобы проверять строки неизвестной длины, движок регулярных выражений должен уметь двигаться в обратную сторону по строке, и видимо не все реализации это умеют.
А при фиксированной длине строки можно просто отодвинуться на N символов назад и сравнивать их слева направо.
То есть это лишь особенность конкретного движка, возможно что есть и такие, в которых ограничения нет. Принцпиального ограничения тут нет.
Получается структура будет такой: index.php - я не знаю что это, но оно грузит (include) либо template.html в которой и форма и вывод результата, либо по отдельности form.html и result.html. template.html (или form.html и result.html) - это шаблон. action.php - это скрипт с логикой.
Или сделать просто 2 файла index.html - шаблон с формой и выводом и action.php - это скрипт с логикой. Тогда схема: index.html -action/post-> action.php -include-> index.html
>>797289 > 3. http://ideone.com/SA4FYT > Надо ставить фигурные скобки. Вместо копипастоы ифов лучше сделать массив с цифрами и словами и циклом искать совпадения в нем.
Я ничегошеньки не понял как это делать, кто-нибудь может подсказать?
Странные вакансии иногда попадаются, вот например: >Опыт не менее 3-х лет в роли веб-разработчика (желательно ecommerce). >Наличие в портфолио хотя бы одного проекта, реализованного на Framework, >Плюсом будет, если знаешь:
>>799458 Ну не всегда PHP-программист пишет что-то на фронте. Знаю студию, где проекты делятся между бекендщиками и фронтендщиками. Алсо, вот что я как-то нашёл на бирже фриланса. Меня хватило на минут 30 скроллить такое, больше я там не появлялся.
ОПчик и посоны, подскажите, каким средствами можно отследить, что грузит mysql? Переодически, где-то раз в неделю процесс mysql занимает триста процентов в топе. Я не знаю, как искать то, что пораждает такую нагрузку.
>>793705 (OP) Ребята, поясните в двух словах, что такое Cron ? Из того, что прочитал, понял что если я поставлю себе Cron задачу на сервере, то она будет выполнятся с определённым интервалом.
Вопрос, могу ли я залить php документ с запросом в базу данных, в крон задачу, чтобы автоматически удалялись устаревшие данные из базы , м ?
>>799729 >Ребята, поясните в двух словах, что такое Cron Ты настолько обленился, что википедию не осилил? На сервере что стоит, debian\ubuntu наверно? Тогда лучше погляди на таймеры systemd для этого.
>>797986 >Положим, что у меня есть матрица размером 2 х n, dв одном столбце у меня даты формата 00:00:00, а в другом какие-то данные, в зависимости от этих данных я меняю текущую дату на день вперёд. >Как это сделать? >матрица Фуф, еле вспомнил как это работает. Я такого со времен первого курса вуза не слышал. Где такое нужно сделать?
Тебе помогут такие функции - array_map, array_walk
Как правильно выводить шаблоны через php? Иметь в каждом шаблоне <!DOCTYPE ...> и <head> или иметь отдельные шаблоны для этого? Если второе, то должны ли они содержать тэги <body> или их можно выводить в рабочем шаблоне?
>>799932 >321.5+3/2-5=157.25 >'7+2/2='; //4.5 Это неправильные ответы. Операции деления и умножения должны выполняться раньше, чем операции сложения и вычитания. Погугли алгоритм сортировочной станции. Для каждого оператора выставляй приоритет в виде цифры.
>>799912 В других тредах тоже норм, только там вряд ли кто-то будет много твоего кода проверять. Да и у нас это только ОП делает. В общем, если нормально спросить, то нормально ответят. Можешь погуглить "how to ask questions smart way".
>>799911 Смотря что валидировать. Если только email или тип данных (список констант есть в мануале по filter_var), то подойдёт. Если нужно, чтобы поле содержало только определённые символы, то бери регулярки.
>>799824 Из комментов: >С другой стороны js\node могут привлекать существенно лучшим дизайном языка в мелочах, чем у того же php
>>799891 Если у тебя 1 шаблон на весь сайт, то просто делаешь 1 шаблон без разделения и всё.
Если у тебя шаблонов несколько, но есть общая для всех шапка и подвал, то просто выносишь шапку и подвал в отдельные шаблончики.
ну и в завимимости от того какую ты страничу собрался отдавать, то инклудишь в своем коде подходящее наполнение между шапкой и телом
require ('head.php'); include ('page1.php'); require ('footer.php);
>Если второе, то должны ли они содержать тэги <body> или их можно выводить в рабочем шаблоне? Я бы сделал так на твоем месте, что бы в случае "проебанной страницы", у тебя ничего не сломалось, и вывелся хотя бы пустой хедер с футером, поэтому все главные теги разместил бы в них.
>Что из этого "шапка"? <head> или <header>? <head> - содержит в себе служебную инфу, которая на странице не отображается.
<header> - новый тег в хтмл насколько я понимаю введенный для семантической простоты, что бы в него именно и писали все шапку. а не воротили <div class="header"> </div>
>>800002 ><head> - содержит в себе служебную инфу, которая на странице не отображается. > ><header> - новый тег в хтмл насколько я понимаю введенный для семантической простоты, что бы в него именно и писали все шапку. а не воротили ><div class="header"> </div> Я знал об этом. Но что из этого "шапка"
Запилил процедурную реализацию алгоритма валидации формы как в уроке, теперь пытаюсь сделать тоже самое, но с ООП подходом. Пикрил - диаграмма классов. Есть пара вопросов по уроку: В разделе урока ООП-подход, второй абзац. Не совсем понятно, что имелось ввиду. Класс ошибок FormErrors - подразумевается, что этот класс хранит все ошибки, допущенные при заполнении всех полей формы, и соответственно, тогда каждую ошибку нужно как-то ассоциировать с полем, значением и сообщением, и хранить в виде массива, или в виде объекта Error в этом классе (композиция)? А в классе User хранить ссылку на него? Или можно хранить только одну ошибку, для каждого поля формы в классе Error, а все объекты Error хранить в массиве класса User (у меня на диаграмме Values)? Или вообще не стоит хранить ссылку на ошибки в классе User? Тогда, т.к. они возвращаются в методе класса Validator, то вызывать этот метод должен не User, а главный скрипт (MainScript), он же будет принимать решение, печатать сообщение об ошибках или создавать класс User. А класс User будет обладать только одним методом - конструктором, которому в качестве аргументов нужно передать корректные значения всех полей? А в самом конструкторе будет достаточно только указать тайп-хинт для значений, т.к. получается, что они уже прошли проверку до того, как были переданы в конструктор?
И второй вопрос, я сделал валидацию с помощью функции filter_var, тип фильтра я храню в константе, которая обозначает формат значения, который нужно ввести в поле формы. Но нужно где-то хранить отношения "поле_ввода=>формат_значения" и где-то объявлять константы. Мне кажется логично хранить константы в классе User, т.к. для каждой формы весь скрипт валидации отличается только этим классом? Но тогда, этот же класс и должен передавать значения на проверку в класс Validator? Но можно добавить класс Форма, в котором указать допустимый формат для каждого поля, и он же будет вызывать метод проверки, а потом создавать класс User. Но в этом случае, для каждой формы придется изменять уже два класса: Форму и User.
>>800010 Я это понимаю так: <head> используется один раз, например в шаблоне head.* Он содержит служебную информацию. <header> может быть использован неограниченное кол-во раз на странице. Он содержит информацию для пользователя. Обозначает заголовок смыслового блока. В заголовок обычно помещается название и иногда короткая информация о содержимом блока. Вся страница сайта, это некий блок, и у него есть заголовок, который обычно содержит название или логотип. Содержимое страницы то же можно разделить на блоки по смыслу, например, статья, последние записи, форма обратного звонка. Каждый такой блок будет содержать как минимум название. Даже подвал страницы может иметь <header>. Точно также обстоят дела с тегом <footer>.
>>800010 "Шапка сайта" - обычно имеется ввиду верхняя часть, где логотип названия, контакты, иногда меню. В WordPress эта часть шаблона называется header.php. По новым правилам ее нужно заключать между тегами <header></header>. Но эти теги можно использовать не только в шапке сайта, но и в шапке статьи, в шапке подвала и т.д.
>>800075 Ну сойди с неба на землю и поясни смертному, в чем дело то? И там и там же "Хуй", проверяю я их сходство вроде правильной функцией с методички. Почему они не одинаковые?
>>800090 Теперь ты одинаковые хеши передаёшь в метод валидации пароля. Ты не понимаешь разницу между хешем и паролем, рано тебе во фреймворки лезть. Решай студентов из ОП-поста, задача содержит множество полезной информации, с которой ты не знаком.
Однако ты прав, написал в $a 'хуй', не хешируя его - вернуло тру. Однако в методичке четко написано: >Когда пользователь попытается войти, отправленный пароль должен быть хеширован и сравнён с ранее сохранённым хешем
>>800074 Этот метод автоматом хешириует второй (или первый аргумент). Получается, что один из хешей отхеширован второй раз. Запихивай один пасс плейнтекстом
> >С другой стороны js\node могут привлекать существенно лучшим дизайном языка в мелочах, чем у того же php - нет тайп хинтов - нет нормального ООП - обращение к несуществующему полю не взывает ошибки - деление на ноль не вызывает ошибки
Класс Value с одним полем - не очень понятно, зачем он. Мне кажется, он не нужен и это переусложнение. Ни разу такого не видел.
Не уверен что в классе Values должны храниться ошибки. Мне кажется, их можно хранить отдельно. Более того, тут появляется проблема что при изменении значений ошибки становятся неактуальными.
Также, обычно вместо него используют модель, то есть класс примерно такого вида:
class Student { public $name; public $surname; }
Там правда есть подвох что поля в форме не всегда соответствуют модели один-к-одному. Ну например в форме регистрации будет 2 поля ввода пароля, а в модели студента - поле с хешем пароля. Где хранить эти пароли...
Ты пишешь универсальные классы для любой формы или для какой-то конкретной? Как минимум валидация в каждой форме будет своя.
У валидатора по моему должен быть один публичный метод - validate(Values) -> errors. Или, что лучше, валидировать конкретную модель без привязки к форме: StudentValidator->validateStudent(Student) -> errors
Также надо помнить что не все поля можно проверить отдельно от других. ну например при вводе пароля при регистрации надо проверить что пароль совпадает с подтверждением пароля.
Не понимаю, что делает метод Values#createValues() ? createValue()? Так как мне кажется что класс Value не нужен то и эти методы тоже получаются ненужными.
Также, мне кажется что в Values не должно быть метода validate. Зачем? Валидация это задача другого класса.
В FormError вместо value лучше хранить к какому полю относится ошибка.
MainScript я думаю не надо разбивать на методы. Алгоритм будет лучше читаться если он написан в одном методе и небольшой. Название стоит поменять на ....Controller.
В общем:
- посмотри, какие классы универсальные, а какие пишутся индивидуально для каждой формы - определи задачу каждого класса - убери из него то, что к ней не относится
>>800136 Уже разобрался, спасип. Есть еще вопрос: В Yii2 валидация формы на стороне клиента осуществляется по событию - onblur. Как можно это изменить?
> Класс ошибок FormErrors - подразумевается, что этот класс хранит все ошибки, допущенные при заполнении всех полей формы, и соответственно, тогда каждую ошибку нужно как-то ассоциировать с полем, значением и сообщением, и хранить в виде массива, или в виде объекта Error в этом классе (композиция)? Можно в виде массива, можно в виде объекта Error. Если ты хочешь максимум ООП то конечно в виде объекта.
> А в классе User хранить ссылку на него? Это на мой взгляд неправильно. Ошибки это не часть информации о пользователе. Это лишь результат валидации пользователя внешним классом. Он устаревает со временем и потому хранить его в юзере неправильно.
> класс User будет обладать только одним методом - конструктором, которому в качестве аргументов нужно передать корректные значения всех полей? Полей может быть много, конструктор будет нечитаемым. обычно делают пустой конструктор и мето принимающий массив полей для установки (setAttributes(array $values)) либо ставят свойства в цикле.
> А в самом конструкторе будет достаточно только указать тайп-хинт для значений, т.к. получается, что они уже прошли проверку до того, как были переданы в конструктор? Тайп-хинты не имеют отношения к валидации. Тайп хинты это проверяемые подсказки для программистов, какие данные надо подавать на вход. Они не способны проверить, правильно ли пользователь заполнил форму. Или я не понял твой вопрос?
> И второй вопрос, я сделал валидацию с помощью функции filter_var, тип фильтра я храню в константе, которая обозначает формат значения, который нужно ввести в поле формы. Не, ты слишком ограничиваешь себя. Валидация может быть произвольной. Ну например проверить что год рождения указан от A до B или что данного значения нет в базе данных. Валидация может связывать несколько полей, например проверить что поля совпадают или что значеие одного поля не противоречит другому.
filter_var тут не хватит. Должна быть возможность писать произвольный код.
Более того, правила могут еще меняться в зависимости от ситуации. Ну например может быть правило "заголовок статьи можно менять только в течение 1 часа после публикации". Или "заголовок может менять только модератор".
> . Но нужно где-то хранить отношения "поле_ввода=>формат_значения" и где-то объявлять константы. Информацию о типах значений можно хранить в 2 местах:
- в модели User если эти правила актуальны в любой ситуации. Например, правило "длина имени никогда не может быть более 50 символов". - в форме если эти правила относятся только к форме, а в принципе в модели могут быть и другие значения. Не могу сейчас придумать пример.
> Но можно добавить класс Форма, в котором указать допустимый формат для каждого поля, и он же будет вызывать метод проверки, а потом создавать класс User. Но в этом случае, для каждой формы придется изменять уже два класса: Форму и User. Возможно, что придется. Если подумать, часть информации относится к модели пользователя. а часть только к форме.
>>800010 >>800014 Ну смотри, давай разберем, что тебе нужно. У тебя должна после всех твоих инклудов и сборов по частям, просто получиться правильная по структуре и содержанию ХТМЛ страница, верно? Вот такого в общем вида как ты сам принес:
<!DOCTYPE html> //начало шаблона head.php - назвать можно как угодно на самом деле, лишь бы тебе было понятно <html>
<head> ... //обязательная служебная инфа </head>
<body> //тут уже пошел "видимый юзеру хтмл <header> ... // сюда ты запихнешь шапку, которая повторяется у тебя на каждой странице, с меню, контактами, логотипом и прочим </header> //конец шаблона header.php
<div class="content"> //начало шаблона page1.php например ... а вот тут у тебя уже контент который зависит на странице от того какой пользователь пришел к нам, или чего он хочет </div> //конец шаблона page1.php
<footer> // начало шаблона footer.php ... // здесь будет подвал, который тоже одинаков для каждой страницы, </footer> </body>
</html> //конец шаблона footer.php
>>800174 >Почему для разных шаблонов используются разные функции require/include?
Ну допустим за тело самой страницы может отвечать юзер, создавая какие-нибудь товары и прочее. Поэтому написал инклуд, что бы если страница вдруг проебется, то не было бы фатал ерора. Поясни если не прав
По сути, обычный MVC, только немного переименованный, видимо с целью запутать людей:
- они зачем-то называют контроллер "роутом" - они называют набор данных для view "моделью" - они делают типичную ошибку начинающего, думая что 1 контроллер = 1 модель - нагородили свою систему объектов с Ember.Object. Напомню, что когда у вас появляется желание наследовать все свои объекты от одного базового класса - с вашей ООП моделью что-то не так. - лезут в стандартные прототипы - интеграционный тест из примера https://guides.emberjs.com/v2.6.0/tutorial/simple-component/ ужасный, содержит много знаний о внутреннем устройстве страницы и скорее всего очень легко ломается
Хотя конечно в сравнении с каким-нибудь ангуларом или реактом он еще относительно прилично смотрится.
>>800265 Не ОП, но по своему скудному опыту скажу, что в небольших приложениях одна страница - один контроллер. Много страниц (много контроллеров) могут работать с одной и той же моделью. На сайте статей модель Article может использовать как ArticleController (для показа статьи обычному пользователю), так и AdminController (для управления статьями).
гайс , решил с одного треда спарсить кортиночки file_get_contents получаю html код себе на localhost , рву относительные ссылки изображений "../" на "https://2ch.hk/..." но картинок не получаю в чем я не прав помогите!
>>793705 (OP) ОП! Я хочу сделать сайт с независимой навигацией двух или трех типов (отдельные меню, возможность нахождения в двух или трех категориях одновременно и т. д.)? Как это правильно делать и как быть с поисковой оптимизацией (ссылки на одни и те же материалы сайта будут встречаться в разных категориях), как быть с содержимым адресной строки, которую хочется сделать логичной? Было бы здорово, если бы ты показал простейший пример. Очевидные теги использовать не хочется, потому что в моем случае это будет выглядеть как сайтнейм.ру/тэгс/статья+стратегия+андроид+айос+винфон+платные+популярное, лол. Кроме того, теги я итак хочу, но в них будет совсем другое (компания-дистрибьютор например, авторы и прочее) Конкретно: хочу сделать сайт про игрушки (не пинай за это, вопрос ведь не об этом), эти игрушки с одной стороны подразделяются по жанрам на стратегии, шутеры, гонки и ммо, с другой стороны по платформе (мобильники, десктоп, консоли), с третьей - на платные и бесплатные и так далее. А материалы про них - на статьи, обзоры, сравнения, новости и другие. Вот хотя бы жанр и тип материала хотелось бы вынести в два независимых меню, остальное оставив на теги. Возникают описанные выше проблемы с содержимым юрл-бара, индексацией, способом хранения.
> сайтнейм.ру/тэгс/статья+стратегия+андроид+айос+винфон+платные+популярное, Это ерунда какая-то.
Для начала можно попробовать сделать минималистичную схему, убирая все лишнее:
- страница игры /game/final-fantazy или /game/123 - информация о платформе и играх для нее /platform/android - список игр в жанре /genre/strategy
Но если ты делаешь страницу /genre/strategy то хорошо бы чтобы это была именно страница про стратегии, например статья с кратким обзором популярных стратегий, а не тупо список ссылок на игры. Я не разбираюсь в СЕО, но сомневаюсь что поисковик будет высоко ценить страницу на которой 0 уникального контента. Да и нужна ли она посетителям твоего сайта?
Для страниц которые включают в себя поиск по нескольким критериям вообще не надо делать отдельные УРЛ. Пусть это будет поиск вроде /games?genre=strategy&platform=android. Все равно эти автосгенерированные страницы имеют нулевую ценность для поисковиков. Это просто модификация страницы /games со списком ссылок на игры.
В общем, я тебе советую придерживаться такого принципа: уникальный УРЛ = уникальная страница. Список, отфильтрованный по какому-то критерию, новой страницы не создает.
Что касается статей и обзоров, подумай, как пользователю будет удобнее их читать. Может быть стоит вывести ленту последних статей, как на хабре, может стоит на главной сделать топ обзоров, может как-то еще. Может люди в основном захоядт из поиска в гугле по названию игры.
>>800174 Я гуглил array_rand, но у меня с ним не получается, выдаёт непонятно что. Если тебя не затруднит, то не мог бы ты пару строчек с array_rand мне показать?
А ты мануал читал? Ты знаешь что возвращает array_rand? Она возвращает случайный ключ из массива. Ты должен после этого по ключу взять значение элемнета. Ты знаешь, как это сделать? для этого используются квадратные скобки.
>Также, обычно вместо него используют модель, то есть класс примерно такого вида
То есть в моем случае, т.к. это форма для ввода значений для расчета кредита, модель будет выглядеть так: class Credit { public $amount; public $percent; public $payment; }
> Ты пишешь универсальные классы для любой формы или для какой-то конкретной? > Как минимум валидация в каждой форме будет своя.
Я делаю ее для задачи расчета кредита, но хочу чтобы ее можно было использовать для последующих задач.
>Как минимум валидация в каждой форме будет своя. >Или, что лучше, валидировать конкретную модель без привязки к форме: StudentValidator->validateStudent(Student) -> errors
А как связать поля формы и модели? И нужно валидировать и форму и модель, т.е. два валидатора?
Controller будет отправлять форму (модель) на валидацию?
>>800172 Спасибо за ответ, это один из лучших тредов )
>Тайп-хинты не имеют отношения к валидации.
Имел в виду, какой класс должен отправить значения полей формы на валидацию, Controller (MainScript) правильно? Класс User (Модель) - этим не занимается?
>Валидация может быть произвольной. Ну например проверить что год рождения указан от A до B или что данного значения нет в базе данных. Валидация может связывать несколько полей, например проверить что поля совпадают или что значеие одного поля не противоречит другому.
Получается Валидатор должен иметь несколько методов на все случаи жизни, или делать под каждый случай новый Валидатор? Тогда и контроллер должен знать в какой Валидатор отправить значения, или какой метод запустить? Ила Валидатор может получить эту информацию из Модели (User\Value) и решить как правильно проверять значение?
>Информацию о типах значений можно хранить в 2 местах:
То есть нужно проверять и модель и форму на соответствие формату введенные значения?
Для формы расчета кредита использовать столько классов - переусложнение. Ну пусть там будет класс CreditParams (чтобы не возиться с массивами), пусть там будет класс Errors, наверно этого хватит. Валидацию можно сделать просто функцией, расчет кредита - другой функцией. При желании валидацию и расчет кредита можно даже объединить.
Не переусложняй систему бед надобности. В коде на 50 строчек не надо делать много классов. Дойдешь до задачи про студентов и там развернешься.
> А как связать поля формы и модели? И нужно валидировать и форму и модель, т.е. два валидатора? Зависит от ситуации. Если у тебя форма не совпадает с моделью, то да, 2 валидатора, один для модели, другой для формы (вызывает валидатор модели для тех полей которые есть и там и там). Но это не очень часто бывает.
> Controller будет отправлять форму (модель) на валидацию? Контроллер принимает данные из GET, вызывает валидацию и получение результата, вызывает шаблон для вывода данных.
Убрал где можно. Но как я понимаю в контроллеры всё равно контейнер придётся передавать целиком, так?
> Сам класс авторизации странный, половины функций связанных с авторизацией, в нем нет, они в контроллере.
Добавил setHash(). Еще что-то нужно? У меня нет идей
> В student->addInfo есть проблема. У тебя нет фильтрации по разрешенными полям и пользователь может менять любые свойства студента в том числе те, которых нет в форме. ну например что если мы добавим колонку is_admin - пользователь сможет передать $POST['is_admin'] = 1 при редактирвоании. И кстати об этом было написано в моем уроке.
Я подразумеваю, что всё что нельзя редактировать пользователю, то protected. А get_object_vars возвращает только public свойства. Разве не элегантно?
https://github.com/TheSidSpears/Students/blob/master/app/classes/StudentValidator.php#L66 > function __construct(Student $s, $container, $id=NULL){ > Почему ты пишешь код валидации в конструкторе? И почему передаешь контейнер? Почитай про DI. - Я переписал __construct так $this->table=$table; $this->validate(); return $this->errors; потому что этот класс используется только так и никак иначе. Создать, проверить на ошибки, вернуть ошибки. Верно так делать? Это сокращает работу с классом до одной строки: $validErrors=new StudentValidator($student,$this->c['table'],$id);
> Но как я понимаю в контроллеры всё равно контейнер придётся передавать целиком, так? Да, это обычно удобнее. В Симфони тоже так сделано.
>> Сам класс авторизации странный, половины функций связанных с авторизацией, в нем нет, они в контроллере. > Добавил setHash(). Еще что-то нужно? У меня нет идей Принцип единой ответственности подразумевает, что каждый класс решает свою задачу, соответственно класс авторизации должен содержать в себе функционал, позволяющий:
- авторизовать пользователя - убрать авторизацию (разлогиниться) - проверить наличие авторизации, может быть определить авторизованного пользователя
Метод setHash на мой взгляд, это не "залогинить пользоваетля". Как минимум его надо переименовать.
Тут опечатка: if (empty($isAuthorized)) { - пропущено this. Если бы ты не использовал empty, ты бы сразу увидел ошибку. Потому - не применяй empty к отдельной переменной.
> Я подразумеваю, что всё что нельзя редактировать пользователю, то protected. А get_object_vars возвращает только public свойства. Разве не элегантно? Откуда я могу об этом догадаться? И нет, не элегантно, так как могут добавиться новые поля и неизвестно, можно ли их редактировать. Что если там будет публичное поле isAdmin? Нужна фильтрация, может быть в контроллере, может в модуле отвечающем за формы.
> потому что этот класс используется только так и никак иначе. Создать, проверить на ошибки, вернуть ошибки. Верно так делать? Это сокращает работу с классом до одной строки: $validErrors=new StudentValidator($student,$this->c['table'],$id); Во-первых, конструктор не может вернуть значение. Во-вторых, ООП не подразумевает такого использования объектов. В-третьих, если получать валидатор из контейнера, то будет опять же одна строка.
Конструктор лишь подготавливает объект к работе. Он не должен заниматься валидацией.
Контейнер надо убрать. Также, я вижу как минимум что тут смешан класс для генерации УРЛ и класс с статическими функциями-утилитами. Для функций надо расставить private/public. название тоже неправильное. Можно подумать что это универсальный класс но на самом деле он умеет генерировать УРЛ только для таблицы студентов с разными видами сортировок - это надо отразить в названии.
> Имел в виду, какой класс должен отправить значения полей формы на валидацию, Controller (MainScript) правильно? Класс User (Модель) - этим не занимается? Не занимается. Задача модели - хранить информацию о пользователе.
> Получается Валидатор должен иметь несколько методов на все случаи жизни, или делать под каждый случай новый Валидатор? Тогда и контроллер должен знать в какой Валидатор отправить значения, или какой метод запустить? Ила Валидатор может получить эту информацию из Модели (User\Value) и решить как правильно проверять значение? Для каждой модели нужен свой класс-валидатор. Однако, для многих полей испоьзуются стандартные виды проверок (проверить что поле заполнено, проверить длину, проверить по регулярке) и можно наследовать валидаторы от базового класса, предоставляющего стандартные методы для наиболее частых случаев.
> Ила Валидатор может получить эту информацию из Модели (User\Value) и решить как правильно проверять значение? Это годится только для типовых случаев, например проверка на длину. А если у тебя нестандартная проверка, как ты эту информацию закодируешь?
Это именно независимый компонент, он не требует наличия полной версии симфони и может использоваться отдельно (это большой плюс компонентов симфони).
>>Информацию о типах значений можно хранить в 2 местах: > То есть нужно проверять и модель и форму на соответствие формату введенные значения? Если у формы есть каике-то поля, которых нет у модели то для их проверки нужен отдельный валидатор. Если поля совпадают то проверять данные формы можно валидатором модели.
Один контроллер может использовать несколько моделей.И наоброт. Я правда перепутал, в эмбере функция model() возвращает не модель, а набор данных для шаблона (ViewModel?).
> Ну допустим за тело самой страницы может отвечать юзер, создавая какие-нибудь товары и прочее. Поэтому написал инклуд, что бы если страница вдруг проебется, то не было бы фатал ерора. Поясни если не прав
> "/(^ )/u", //пробелы в начале строки Их наверно проще через trim удалять
> $regExp[1] Это не очень хорошо читается так как надо искать нужный элемент глазами. Лучше класть регулярки в переменные или сразу вписывать в preg_replace напрямую.
> $letters = preg_split("//u", $text,-1,PREG_SPLIT_NO_EMPTY); > $letters[0] = mb_strtoupper($letters[0]); тут излишне разбивать на символы - проще взять первый символ через mb_substr
Чтобы не было проблем с троеточием, надо модифицировать регулярку "/ ([.,?!:]) */u", а то, что у тебя больше напоминает "костыль".
> for ($participant = 0; $participant < $total; $participant++) { > $seats[$participant] = $participant + 1; Тут нельзя использовать функцию range()? Или array_fill?
> for ($participant = 0; $total >= $skip; $total--) { Немного сбивает с толку то, что используются разные переменные.
> if ($participant <= $total - $skip) { > $participant = $participant + $skip - 1; Запретить значению выходить за определенный предел удобнее с помощью операции "деление с остатком", %.
> unset($seats[$participant]); > sort($seats); Для перенумерации выгоднее использовать array_values. Однако для удаления элемента из массива с перенумерацией есть готовая функция array_splice.
> for ($PlacesToEnd = $skip; $PlacesToEnd > 0; $PlacesToEnd--) { > $placeInNewCircle++; По моему весь этот цикл можно заменить на сложение и остаток от деления.
В общем, код стоит упростить. Пока он переусложнен.
>>801171 олсо. прочитал в одной вакансии про самостоятельное поднятие сервера и начал гуглить. Понял что ничего об этом не знаю, кроме того что описано в обычных учебниках по php. Прочитал про сервера, нашел туториалы как их настраивать, но мне ни как не дойдет как это сделать. Как мне тестово настроить сервер? мне нужно его покупать или можно это сделать на своем компе? сейчас ничего не пойму, прошу помощи объяснить
>>801171 >>801191 >пытаюсь найти работу стажером по php >Как мне тестово настроить сервер? мне нужно его покупать или можно это сделать на своем компе? Орнул с тебя. Про Apache не слышал? Как ты вообще изучал PHP тогда?
>>801171 >>801191 > Погуглите за меня сайт с вакансиями > Объясните как подымать сервер Почему ты такой несамостоятельный? Какой сервер, ты хочешь, чтобы сайт из твоей локальной сети был виден всему миру? Вот: http://varkon.biz/2010/08/kak-sdelat-dostup-k-apache-iz-interneta/ Если вообще нулячий, то можешь попробовать следующее: 1. Поставить на виртуалку Ubuntu, засетапить там LAMP, залить туда сайт. 2. Научится заходить на этот сайт из хостовой ОС (той, на которой ты запустил виртуальную машину). Если разберёшься, то многое прояснится. Но это если хочешь что-то понять. Если понимать не обязательно, то бери heroku. Ну и обязательно нужно знать про домены-хостинги, всё разжёвано донельзя: http://www.postroika.ru/hosting/ Погуглил за тебя.
>>801219 Видимо, пользовался денвером-большой-красной-кнопкой.
>>801231 я нашел много сайтов с вакансиями на каждом нужно регаться, хочу узнать про один толковый, а не сотню хуйпойми чего. Про сервер тоже прогуглил но ничего не понял вот и пытаюсь узнать. Это же блядь имиджборда.
>>801263 Apache посмотри.. Ты где учился языку-то, как ты смотрел, что код исполняется вообще? Троллишь так, что ли, чертяка? Это же как устраиваться работать в такси, но не иметь водительских прав. Анон выше тебе всё расписал.
>>801231 вообще нулячий в серверах. с первым я разберусь, а что дальше? что на нее ставить где почитать? нихуя не пойму пока и не прошу все по полочкам раскладывать, просто ссылки на инфу покидайте
>>801739 >$difference = $paymentTotal - 40000; Если хочешь потом посчитать разницу, то лучше изначально $creditBalance сохранить дополнительно в соответствующей переменной: >$parentCreditBalance = $creditBalance; А затем уже в самом конце отнять от $paymentTotal этот $parentCreditBalance. В этом случае легче обслуживать код - не надо менять цифру в самом конце, когда, допустим, меняешь сумму кредита изначально. А так всё хорошо выглядит, задача правильно решена.
Есть бд, на сайт должны выводиться выборки с этой бд. Мне эту хуйню надо разработать и протестить на своём компутере (что называете локальным сервером, так?) Т.е. для разработки мне нужно установить: 1. сервер (какой?) 2. среду разработки (как я понял в тредне пхпшторм, пойдёт?) 3. настроить эту среду (тяжело ли настраивать пхпшторм? компиляторы, хуяторы, проверку синтаксиса, дебаг, есть там это всё из коробки или надо поставить 200 плагинов?) 4. браузер, в котором можно видеть результат (а можно без браузера? консоль там или ещё что)
Где про это можно подробно почитать? Вообще про взаимодействие сайта с сервером. Что пишется на js, что на php, как запросы формировать, вот это всё, как данные выдавать, асинхронность, вот это всё, рожь, зелень.
Я к вам из c++ пришёл и голова с вашей хуйни забубённой просто пухнет, думал за вечер установлю всё необходимое, в итоге не установил нихуя.
>>801774 >1. сервер (какой?) Обычный веб-сервер, который слушает определенный порт и отдает веб-страницы пользователям которые к нему обращаются. Их существует много, но для новичков тут часто советуют апач (Apache HTTP Server - https://httpd.apache.org/ ). Но одного веб-сервера мало, он умеет только отдавать только обычную статику (т.е. файлы html которые лежат в его корневой директории), для динамики к серверу нужно будет поставить интерпретатор PHP. Как это сделать и как оно работает можешь почитать тут https://github.com/codedokode/pasta/blob/master/soft/apache-install.md там есть секция Q&A которая поможет тебе разобраться во всем получше. >2. среду разработки (как я понял в тредне пхпшторм, пойдёт?) Необязательно среду, тут уже вкусовые предпочтения. Некоторые используют редакторы типа Sublime Text или Atom. Они легче чем пхпшторм, не так нагружают компьютер, и для старых ноутбуков самое то. Конечно функционала там меньше, но все самое необходимое (линтер, дебаггер) можно настроить с помощью плагинов. Конкретно за пхпшторм рассказать не смогу, я им не пользуюсь. Может кто из анонов подскажет. >а можно без браузера? консоль там или ещё что Если к своему приложению сможешь написать клиент для работы с командной строкой - тогда можно. Я не думаю что тебе будет приятно читать в консоли html разметку файлов которые отдал сервер.
>>801774 Окей смотри, меня ща обоссут местные устанавливатели ВРУЧНУЮ ПОДНЯТИЕ ЛИНУКСА + ПХП + МУСКУЛЭЛ + АПАЧ на локальном компе что бы лампово пердолится вечерами на локалхосте, но уверен что тебе я помогу.
Устанавливаешь её, придложит еще доп компоненты мб установить тип библиотеки для винды и прочее, тоже ага.
1. В той папке куда ты установил всё, у тебя будет папка domains
2. Заходишь значит в domains, создаешь в ней папку с именем например loh.pidr
3. В этой папочке создаешь файл index.php
4. В этом файлике пишешь например: <?php echo "hello world" ?> сохраняешь
5. Запускаешь в значит open server x64.exe
6. В трее повяится красный флажок, правой кнопочкой по нему и жамкаешь запустить
7. После того как всё запустилось и флажок стал зелененьким заходишь в браузер и в адресной строке вбиваешь адрес http://loh.pidr (опционально можно http://loh.pidr/index.php, но к этому файлу и так будет автоматом цепляться при заходе на просто loh.pidr)
8. Вот собственно ты и поднял у себя связку APACHE + PHP + MYSQL на винде
9. Редактируешь свои скрипт_нейм.php в папке loh.pidr, смотришь результат в браузере loh.pidr/скрипт_нейм.php
10. Удачи, если что спрашивай
11. Если вдруг лень качать open server, а без пожертвования он будет качаться часа 2, (могу залить куда-нибудь что бы быстрее скачать если не ссышь от левого анона брать файло) то можешь скачать http://www.denwer.ru/ и по их мануалу всё настроить, там немного отличается подход создания локального домена, но суть та же. Просто денвер устарел и не обновляется.
ассоциировать .php файлы с ним и в нем лампово работать
Весь этот "манулал" что бы тебе просто и безболезненно начать работать у себя на компе и делать полностью свои сайты на локальном серве, а не сидеть пердолиться несколько суток с установкой софта, в который нубу сложно въехать будет
Как подкачаешься в этом, то перейдешь на полностью настроенные самостоянельно серваки и прочие убунты.
>Есть бд, на сайт должны выводиться выборки с этой бд.
Тогда тебе надо разобраться как работать с базой данных с помощью php и вывести в читабельном (html) виде всё это на сайт. Просто напишешь свой скрипт для начла, который коннектится к бд, шлет запрос, получает ответ, и выводит его в браузер.
Ща опять все навалятся, что mysql_ функции в php это деприкейтед и зашквар, но ты сделай для тренировки как тут, а потом на pdo или mysqli_* перейдешь.
Не вижу смысла устанавливать какую-то кривую сборку, когда установка компонентов по отдельности займет не намного больше времени.
Плюс в сборках часто устаревшие версии программ.
Плюс ты потеряешь время, когда захочешь например что-то настроить или поменять, так как все советы в интернете расчитаны на чистый апач, и на твоей сборке просто могут не заработать.
Убрал где можно. Но как я понимаю в контроллеры всё равно контейнер придётся передавать целиком, так?
> Сам класс авторизации странный, половины функций связанных с авторизацией, в нем нет, они в контроллере.
Добавил setHash(). Еще что-то нужно? У меня нет идей
> В student->addInfo есть проблема. У тебя нет фильтрации по разрешенными полям и пользователь может менять любые свойства студента в том числе те, которых нет в форме. ну например что если мы добавим колонку is_admin - пользователь сможет передать $POST['is_admin'] = 1 при редактирвоании. И кстати об этом было написано в моем уроке.
Я подразумеваю, что всё что нельзя редактировать пользователю, то protected. А get_object_vars возвращает только public свойства. Разве не элегантно?
https://github.com/TheSidSpears/Students/blob/master/app/classes/StudentValidator.php#L66 > function __construct(Student $s, $container, $id=NULL){ > Почему ты пишешь код валидации в конструкторе? И почему передаешь контейнер? Почитай про DI. - Я переписал __construct так $this->table=$table; $this->validate(); return $this->errors; потому что этот класс используется только так и никак иначе. Создать, проверить на ошибки, вернуть ошибки. Верно так делать? Это сокращает работу с классом до одной строки: $validErrors=new StudentValidator($student,$this->c['table'],$id);
>>793705 (OP) Посоны. Учил JS полгода, решил вкатиться заодно в PHP. Смотрю в основном видосы 2011 года с thenewboston.com, попутно пилю чатик используя php для логина-куков и для ajax-запросов. Появилось два вопроса: Не слишком ли я устаревший материал изучаю? Нормально ли использовать пхп только как веб апи?
>>802321 Не старое, пхп, как и жс - мёртворождённое говно, но даже несмотря на это человечество его использует столько лет, что натворило на этом дерьме почти все интернеты, и будет использовать его ещё больше.
>>802321 >Не слишком ли я устаревший материал изучаю? php и js маловато будет, нужны фреймворки. >Нормально ли использовать пхп только как веб апи? Что это значит?
>>802210 Спасибо анонас, именно то что нужно, в этом опен сервере и отладчик есть, всё по уму. Желаю твоей матери крепкого здоровья и долгих лет жизни.
>>802334 Ясно. >>802335 >php и js маловато будет, нужны фреймворки. Оно понятно, на жс я react уже поковырял, но без серверной части ограничен в пилении своих задумок был, а ноду я с первого захода как-то не осилил + из веб-хостингов её не все поддерживают. >Что это значит? Что я, возможно, выдумываю терминологию на ходу. Я имею в виду, что пхп у меня почти только принимает ажакс запросы и отдает жсон, или же принимает жсон и записывает в .тхт файлик, я до баз данных еще не дошел ололо.
Аноны помогите пожалуйста учу symfony1.4, по офф. курсу http://symfony.com/legacy/doc/jobeet/1_4/ru?orm=Doctrine и на 15 дне возникла трабла, прописал routing как написано в курсе affiliate: class: sfDoctrineRouteCollection options: model: JobeetAffiliate actions: [new, create] object_actions: { wait: get }
symfony app:routes frontend показывает нужные маршруты affiliate_new GET /affiliate/new.:sf_format affiliate_create POST /affiliate.:sf_format affiliate_wait GET /affiliate/:id/wait.:sf_format но при обращении в браузере на http://jobeet/frontend_dev.php/affiliate/new ошибка 500 Unable to find a matching route to generate url for params "array ( 'action' => 'index', 'module' => 'affiliate',)". как решить проблему. кровь из носа за оставшиеся 5 дней я должен его освоить, помогите пожалуйста.
иди на хуй симфони, убрал из роутинга actions: [new, create] кол.-во маршрутов увеличилось но ошибка пропала, думаю ладно пока аноны не ответили буду работать дальше, дальше по книге мы строим экшены и темплейты для этого модуля, в конце у меня вышла новая ошибка Array to string conversion in D:\OpenServer\domains\sfprojects\jobeet\lib\vendor\symfony\lib\widget\sfWidgetFormSelectCheckbox.class.php on line 102 начал гуглить, так как ошибка была явно не в моем коде, нагуглил вот это http://trac.symfony-project.org/ticket/9985 поправил как там изложено и все заработало, и че то меня дернула опять попробовать роуты из примера, и оно блять заработало, как блять так?! суки!
>>802427 пошел устраиваться на работу джуном, сказали мол у них все пишут на symfony1.4, дали 2 недели на обучение. дали этот учебник, я блять думаю что не спроста они мне дали этот учебник, там у меня уже были приколы где приходилось править файлы фреймворка что бы он коректно работал
Сап программач Помоги нубу, скажи ЧЯДНТ! Скинули мне backup сайта и cms и бэкапы баз для них. Как это запустить на локальной машине? ОС MacOS X 10.11 вроде настроил apache(на локал хост заходи, папки видит) Mysql тож вроде настроил phpmyadmin
я положил в папку которая настроена для localhost этот бэкап, он мне выдает когда захожу туда Error database: Acces denied for user...
Я пока могу только в верстку. Мне нужно этот бэкап запустить у себя, и понять как натянуть новую верстку на "самописную" CMS на codeIgniter. Аноны спасайте!
Такие проблемы решаются не так. Надо посмотреть (поиском по тексту ошибки или по стектрейсу, что намного удобнее), где выбрасывается исключение. Там отладчиком или временным var_dump посмотреть значения переменных. Если они приходят из какой-то функции - залезть туда и тоже посмотреть. И так постепенно ты скорее всего дойдешь до причины ошибки.
Алсо, у тебя ошибка не при роутинге. У тебя ошибка при попытке сгенерировать УРЛ, например при выводе шаблона или еще чего-то.
Надо делать как я написал выше. Ты вместо того, чтобы найти причину и чему-то научиться пытаешься просто убежать от ошибки. Так не пойдет. На работе ты тоже так же поступать будешь?
>>802508 У тебя в бекапе сайта, среди файлов кодигнайтера должен быть какой-нибудь конфиг файл. Причем не далеко в ядре, а где-то почти на поверхности. Попробуй в application/config/config.php
Судя по ошибке, у тебя твои скрипты просто не могут подцепиться к базе, если ты конечно её сложил к себе на локальный mysql сервер, если он у тебя конечно поднят 100%, а не ВРОДЕ БЫ
В общем берешь и настраиваешь в этом конфиге что бы скрипт ломился на локалхост и под юзером которого туда пустят.
Защита от csrf-атак с помощью csrf-токена, правильно ли я понял систему: 1.Юзер заходит на сайт - проверить есть ли у юзера кука csrf_token, если нету - сгенерировать и установить 2. Когда юзер отправляет любую форму - взять эту куку и навесить на скрытый инпут либо в гет запрос добавить 3. Обработчик сравнивает полученный токен с тем который установлен у юзера в куках, если == обработать форму
В начале лета у меня закончился курс по теории баз данных и основам защиты информации в БД. Посоветуйте какую-нибудь актуальную литературу о SQL-инъекциях всех видов и XSS/CSRF-атаках. А то одни говностатеечки гуглятся.
Это единый тред макак? Похуй, напишу сюда. Короче, мой хуев начальник уже второй месяц заебывает меня чтобы я поднял интернет магазин А я не в зуб ногой в веб программинг, я блядь админ!, посоветуйте движок на котором это говно проще всего поставить? На шаблон бабки дадут, да и хуй с ним
>>793705 (OP) Вчера ебался с шаблонизаторами, чтобы здоровенные функции PGSQL с похожим кодом в файлы миграций БД в несколько строчек генерировались. И это пиздец. Шаблонизаторы (которые себя таковыми позиционируют) - нефункциональное говнище. Причём я не говорю о функциях работы с данными, а именно о работе с выводимым текстом - тем во, что шабонизатор должен мочь больше всего. Остановился на Nunjucks и чуть не сгорел от баттхёрта, когда там фильтр функции отступа (просто, блядь, 4 пробела!) сжирал весь текст внутри себя и переменные не присваивались. Причём репорты на ГитХабе висят.
А потом попробовал писать шаблоны прямо таки в php, компиля gulp-ом через 'php -f %файл%'. И это охуенно, аноны! PHP - охуенный шаблонизатор! Минималистичный синтаксис, куча встроенных функций и сторонних библиотек, быстрая скорость компиляции, большое комьюнити. Не повторяйте моих ошибок, пацаны. Нужно сгенерировать статические файлы с шаблонизатором - берите PHP. 10/10, базарю!
>>802975 >мой хуев начальник уже второй месяц заебывает меня чтобы я поднял интернет магазин А я не в зуб ногой в веб программинг, я блядь админ!, посоветуйте движок на котором это говно проще всего поставить? Лучше посоветую тебе нахуй послать своего начальника.
>>802975 Проще всего - OpenCart. Он устаревший и плагины ставятся ректальным путём (вообще всё, что не из коробки, ставится ректальным путём), однако своё дело делает. Ставится и настраивается просто. У клиента на нём уже второй год запиленный мной сайт вертится. Ни одной жалобы, торговля идёт, сайт жив.
Мне нужно получить среднее значение максимальных значений каждого раунда сгруппированных по уровням.
На пике мои натуги. Получилось вытащить максимальное значение раунда для каждого уровня и дальше я чет совсем загрустил. Записей в бд много, несколько миллионов, и с каждой неделей увеличивается еще на миллион.
>>803111 WITH t AS ( SELECT games.level AS level, MAX(logs.score) AS score FROM games LEFT JOIN logs ON games.id = logs.game_id GROUP BY games.level ) SELECT t.level, AVG(score) ... FROM t Стоп, я нихуя не понял, но этого тебе должно хватить.
>>803187 На больших объёмах join всё равно индексы не использует, а других критериев у тебя и нет. Возможно завести индекс по времени логов, или партисипировать таблицу логов по времени, и в запросе указывать границы времени, за которое считать статистику.
При партисипировании можно актуальные логи при держать на быстром хранилище, а старые перемещать в архивное.
Простите, аноны. Хотели с знакомым заняться веб-проектом. Чтобы он учил js, css, html, а я серверную часть. Если я правильно называю это. Серверная чать - это ведь например RoR, Python + django, PHP? Наверняка эта тема уже обсасывалась много раз, но я не понимаю. Как использовать PHP в сайтах? То есть надо как-то сервер запускать? А как тогда это всё на полноценный хостинг/сайт перенести? Не понимаю. И как сейчас вообще PHP живёт? Не помер надеюсь? Даже если ничего не получится, то плевать, главное, что тема эта интересна.
ОП, ты как-то упомянул, что можно не прописывать в ручную неймспейсы в проекты, а есть автоподстановщики в IDE. Не могу нагуглить, есть такое для Sublime?
>>803301 С сервером разобрался. Опять же он только локальный, чтобы протестировать работу например php. А как это всё дело на хостинг рандомный занести?
Помогите решить проблему с GitHub, я запутался. Создал новый проект, залил удаленный репозиторий на GitHub. Затем удалил папку из локальной директории, и решил обновить проект, чтобы на удаленном репозитории тоже удалилось, но push возвращает "everything up-to-date" и не хрена не делает, хотя statuse пишет что есть изменения и перечисляет удаленные файлы и папку.
Я погуглил-погуглил и нехрена не понял что делать. Какой есть вариант кроме - удалить нахуй проект с гитхаба и создать заного?
Что я сделал не так, что гитхаб меня так наказывает?
>>803328 >git add . Да, если из корня проекта, после этого изменения добавляются в индекс. Потом git commit -m "Я сотворил неведомую херню" Твои изменения закоммичены, их можно пушить.
>>803335 Пушатся только коммиты. При выполнении git add изменения заносятся в индекс. Индекс - кандидат на коммит, закоммичены будут изменения, внесенные в индекс. Изменения не внесенные в индекс(не добавлены через git add) закоммичены не будут, их нельзя будет пушнуть.
Вечер в хату товарищи вебмастера. Ламповая kоHфepенцNя вордпресс-джиквери-интеграторов нуждается в вашем высоком интеллекте. Сосёмся в дёсны, поясняем за хаскель и функциональщину на самом деле нет, реакты с редуксами, пайтон, джанго, правильный UX и другие никому не нужные вещи. Треш и угар гарантируем. С собой иметь плавки и бальзам Звёздочка.
Доброго времени суток, товарищи. Имеется небольшой проект для государственной организации, в которой работаю. На данный момент поднят сервер (Апаче 2.4 + PHP 5.5 + MySQL) на одном из компьютеров внутренней сети, проект лежит и все прекрасно работало. Однако, тетушкам стало пригорать, что скучно работать и в одноклассниках не посидишь, "2016 на дворе! а мы без интернета", как результат нам подключили модемный интернет через телефонную линию (512kbps(!), но не в этом суть). Параллельно руководство заставило поставить специальную учетную программу, работающую через интернет, но сохраняющую локально данные. После чего сервер мой снесли, мотивируя конфликтом этой программы с установленной мною БД MySQL. К делу: Купил на собственные деньги недорогой хостинг, и собираюсь переносить свой проект туда. Тем более плюсы есть (доступность 24/7 из любого девайса с интернетом). Проблема в том, что данные, которые будут там храниться, никак не должны попасть случайным лицам. И если раньше все было легко, то как обеспечить безопасность на сервере я никогда даже не задумывался. Прошу советов мудрых, хинтов, лайфхаков, может быть литературу или статьи в интернете (к сожалению, из-за работы не получается уделять много времени этому хобби, учился по php.net).
>>803546 Проект - моя инициатива, упорядочивает данные и экономит кучу времени на бумажной волоките. Руководство не волнует как я делаю свою работу, с помощью программ или без, за 8 часов или остаюсь сверхурочно, нужно чтобы все было сделано и в срок. Так что это мне выгодно в первую очередь, остальные все равно ничего не понимают в интернетах дальше одноклассников. Без нее вернусь в дремучие времена, которые даже вспоминать страшно и уволюсь.
>>803567 БД удалили уже (после того как я ее сохранил на флешку), да и я не вижу проблемы использовать БД моего хостинг-провайдера, про безопасность PHP в работе с mysqli уже начал читать.
Буду задавать конкретные вопросы itt, начну вот с чего: структура папок на хосте выглядит так: корневой каталог(1)/мой_юзернейм(2)/public_html(3) папка (3) доступна из интернета, в ней открываются все файлы. Есть ли смысл держать в ней html, css, js и одинфайл php, содержащий строку "<?php include_once '../index.php' ", а всю php-составляющую положить на уровень (2), куда доступа извне нет? Соответственно, просмотреть содержимое файлов (пароли к бд, конфиги) будет нельзя даже если что-то на сервере пойдет не так с php-компилятором.
Вечер в хату товарищи вебмастера. Ламповая kоHфepенцNя вордпресс-джиквери-интеграторов нуждается в вашем высоком интеллекте. Сосёмся в дёсны, поясняем за хаскель и функциональщину на самом деле нет, реакты с редуксами, пайтон, джанго, правильный UX и другие никому не нужные вещи. Треш и угар гарантируем. С собой иметь плавки и бальзам Звёздочка.
>>803578 Админ у нас...это просто космос. В прошлый раз он переустановил виндуус не спросив никого и потер ВСЕ данные на компе, получил пизды, но он сын начальника и продолжает работать без образования, рашка такая рашка, да. Он сто процентов заниматься этим не будет. >секретную базу данных В том-то и дело, что хранятся там транзакции закупок, договора и другая документация. Конечно, организация у нас не секретная, но я не уверен что имею право размещать эту информацию где-либо, государственная же! Сидеть потом еще. В общем, ты советуешь наладить все внутри и не париться? Эх. Я сам понимаю, что должен такими вещами заниматься профессионал, но блжад их нет у нас.
>>803589 .htaccess - первое, про что я подумал. Но меня остановило наличие аж двух папок вверх по каталогу, и предположил я что они для этого и созданы. (Хотя конечно нет, там хранятся логи, и вообще их использование не моего ума дело, но почему бы не урвать кусочек безопасного места?).
> Есть ли смысл держать в ней html, css, js и одинфайл php, содержащий строку "<?php include_once '../index.php' ", а всю php-составляющую положить на уровень (2), куда доступа извне нет Именно так и нужно делать. В публичную папку кладется только то, что предназначено для раздачи.
Зачем искать какие-то костыли когда можно просто не выкладывать код наружу? Это костыли для CMS которые будут разворачивать неквалифицированные пользователи, не понимающие что такое публичная папка.
Не стоит выгружать это на хостинг. Думаю, правильнее переставить mysql на другой порт и держать все внутри. В крайнем случае ты можешь ведь на свой компьютер все поставить.
Еще можно попробовать внутри виртуальной машины приложение развернуть если ресурсы позволяют.
Вообще, конечно если ты делаешь программу для себя, а не веб-сайт, то ты выбрал не те технологии. Я бы писал на каком-нибудь С# десктопную программу с базой на sqlite. Или, если меня не очень беспокоит производительность, то писал бы программу на яваскрипте и запускал в electron (это штука, пакующая твое яваскрипт-приложение вместе с браузером в виндоуз-приложение).
> Если я правильно называю это. Серверная часть - это ведь например RoR, Python + django, PHP? Да. И базы данных.
> То есть надо как-то сервер запускать? Настраиваешь веб-сервер Апач и интерпретатор php и они будут принимать запросы от браузера и запускать твой код.
> А как тогда это всё на полноценный хостинг/сайт перенести? Копируешь по SFTP. Лучше бы не руками, а написать bash-скрипт, который ты запускаешь и который обновляет сайт.
Некоторые деплоят через гит. Выгружаешь изменения в гит, а на сервере запускаешь скрипт, который вытягивает эти изменения.
В этом тебе помогут баш-скрипты, но если ты в них не силен, то придется освоить, на пхп это писать не очень удобно (хотя и возможно).
тут конечно есть недостатки что нет атомарности деплоя, то есть замена файлов происходит постепенно и в какой-то момент времени часть файлов старая, часть новая, а один файл наполовину записан. Ну думаю у тебя не такой посещаемый сайт чтобы об этом беспокоиться.
Для атомарности деплоя надо скриптом создавать новую папку, выгружать туда код, прогревать кеши (если они есть), собирать статику (если есть) , переключать путь к корню сайта в конфиге веб-сервера и затем дть ему сигнал перечитать конфиг. Тогда обновление происходит атомарно и без багов.
перебор большого числа строк нельзя оптимизировать. тебе надро выполнять этот запрос в офлайне, то есть не при генерации страницы, а например раз в час по крону и класть результаты в кеш или в отдельную таблицу.
Ну вообще, представь что у тебя задача считать среднее из миллиона строк. Никакие индексы не оптимизируют перебор миллиона строк. даже если все данные в памяти, это все равно минимум пару секунд займет.
Как тут запрос оптимизировать? Считать раз в час по крону. А если нужно мгновенно обновлять среднее, а не раз в час? Тогда заводим 2 ячейки, в одной храним сумму значений, в другой их количество. Обновляем эти ячейки при каждой вставке в исходную таблицу.
>>803613 >не те технологии А я догадывался. Однажды спросил: что легче всего выучить и применить? Мне ответили PHP. ИЧСХ, все так и оказалось, работает же! Но теперь вот такая засада. Спасибо за electron, рассмотрю подробнее, ибо javascript уже использую, а всякие C пугают сложностью тестирования. Конечно десктопное приложение в моем случае идеально подойдет, нужно просто взять себя за яйца и посидеть разобраться. Жаль по образованию далеко от программирования.
Алсо запрос неправильный. У тебя внутренний подзапрос группирует по level, и внешний группирует по level, и среднее там посчитать не получится так как ты его считаешь из одного значения. в запросе явно ошибка.
Наверно во внутреннем запросе надо группировать по раундам.
Зачем генерировать SQL скрипты? Почему на том же пхп не написать код который в цикле будет вызывать нужные запросы? По моему ты чем-то странным занимаешься.
> шаблоны прямо таки в php, компиля gulp-ом Наркоман? зачем тут гульп если можно просто напрямую запустить php или сделать bash скрипт из 1 строки?
Вот ты странные вещи пишешь. Токен можно держать в куках. Сессия - это хранилище на сервере, которое идентифицируется куками. То есть те же куки, просто более сложный способ хранения. Зачем?
> 1.Юзер заходит на сайт - проверить есть ли у юзера кука csrf_token, если нету - сгенерировать и установить А если есть - то продлить ее жизнь, переустановив
если у тебя уже есть пхп приложение то наверно нет смысла его переписывать, если это не несет какой-то выгоды. Что касается запуска - при желании ты можешь даже сам себе сборку сделать, собрав вместе mysql, php, апач с конфигами и запуская их bat-скриптом когда тебе нужно.
К вопросу о инкапсуляцииАноним23/07/16 Суб 19:55:43#399№803638
// создание новой $newNews = new News(); $newNews->title = 'Сенсация!'; $newNews->text = 'Текст новости'; // вставка в БД $mapper->save($newNews);
VS
// создание новой $newNews = News::create('Сенсация!', 'Текст новости'); // вставка в БД $mapper->save($newNews);
?
К вопросу об инкапсуляцииАноним23/07/16 Суб 20:03:50#400№803642
>>803623 В моем приложении разделенная логика: интерфейс через html+js асинхронно посылает команды на php, который генерирует только json, из которого js рисует таблицы, списки, графику и тп. В общем, путь полной генерации страниц в php я прошел. С ajax-ом намного быстрее, плюс не засоряю мозги и код. Так что скомпилировать гуй в отдельное exe-приложение а не вкладку в браузере будет норм (бывает хромог без плагинов зависает на некрокомпах с антивирусами при открытых 5 вкладках со всякой ерундой)
>>803646 >Но в твоем примере массив никакой выгоды не дает. Как не дает? А если у модели со временем появятся новые поля, значение которых надо будет устанавливать в зависимости от значений 'title' и 'body'? С таким массивом нам не потребуется менять код, вызывающий метод News::createFromArray(). А логику установки этих новых полей придется разрулить только в одном месте -- методе News::createFromArray(). Всё. Причем не обязательно использовать массив:
// создание новой $newNewsData = new NewsData(); $newNewsData->title = 'Сенсация!'; $newNewsData->body = 'Текст новости'; $newNews = News::createFromArray($newNewsData); // вставка в БД $mapper->save($newNews);
Разумеется, в NewsData мы опишем свойства title и body.
Любители ноды пишут такие вещи на gulp, любители php пишут самописные скрипты на пхп, любители bash - на баше. Еще в линуксе есть make, который можно задействовать для этой цели (причем, что хорошо, он умеет обновлять только изменившиеся зависимости).
В общем, вариантов много. Самый известный это наверно gulp, но он завязан на ноду (яваскрипт), и на мой взгляд, там довольно уродливый синтаксис. Вообще, мне он не нравится, это выглядит как убогий велосипед в сравнении с make которому уже лет 40.
Либо делать не статическими, либо прокинуть методы как глобальные функции твига.
Я подозреваю, там по каким-то причинам не хотят такое разрешать. Чтобы например не вызывали все подряд, а пользовались только предоставленными переменными и функциями.
Это по сути синтаксический сахар, который позволяет записывать вызов сеттера короче.
Твой подход с массивом проблему никак не решит.
> А логику установки этих новых полей придется разрулить только в одном месте -- методе News::createFromArray(). Всё. Нет. Он не решает проблему изменения поля позже.
> Причем не обязательно использовать массив: Это уже переусложнение - ты создал 2 класса, решающих одну и ту же задачу - хранение информации о новости.
С аяксом вряд ли быстрее, отобразить готовую страницу гораздо быстрее (и браузер умеет делать это по мере загрузки), чем ждать пока загрузится страница, куча скриптов, пока все отрендерится.
Конечно есть случаи когда это необходимо: например, интерактивные приложения со сложным интерфейсом. Но если делать какой-то простой сайт, например учебник или блог - это только ухудшает удобство использования.
То есть надо смотреть по ситуации. А чтобы другие неопытные аноны сделали правильные выводы, я чуть-чуть прокомментирую твои высказывания.
> С ajax-ом намного быстрее, Это надо постраться чтобы на пхп код работал медленнее чем код на пхп + передача данных + рендеринг страницы в яваскрипте.
> плюс не засоряю мозги и код. Вообще, ты его усложняешь. Теперь в генерации страницы принимает участие не только пхп, но и яваскрипт.
> бывает хромог без плагинов зависает на некрокомпах с антивирусами при открытых 5 вкладках со всякой ерундой) Это зависит от того, каике сайты открывать. реклама и следящие скрипты могут сильно нагружать браузер. Я как-то смотрел - простая хтмл страница без яваскрипта потребляет довольно мало ресурсов. Хотя Хром да, он потребляет много памяти, я подозреваю они просто кешируют все, что можно в надежде ускорить приложение.
Так, в общем, хорошо сделано. надеюсь, в следующий раз ты будешь использовать для вещей вроде Request готовые библиотеки.
https://github.com/applejacky/students/blob/master/dump.sql > `cookie_token` varchar(100) NOT NULL, Я бы тут добавил уникальный ключ для защиты от глупых ошибок, например когда туда вставляется пустая строка или что-то такое. И комментарий стоит добавлять, так как назначение поля не очевидно.
https://github.com/applejacky/students/blob/master/app/Lib/StudentValidator.php#L36 Здесь странно что проверки email и пароля делаются только для новых студентов. А что, редактировать email или пароль нельзя? Уж email-то наверно можно? Нет ли тут ошибки, что пользователь может при обновлении передать емайл или пароль и они принимаются без валидации? Хотя конечно метод save() и не сохраняет измененный email, но догадаться об этом не просто.
> "Баллы должны быть в диапазоне между {$this->minRating}-{$this->maxRating} включительно"; > включительно"; А судя по коду - не включительно.
В реализации роутов у тебя есть подвох. Параметры роута определяются по порядковым номерам, а не по названиям. То есть можно легко написать в роуте плейсхолдеры /:a/:b/:c, а в контроллере function doSomething($c, $b, $a) и не заметить ошибки. Лучше либо передавать массив именованных плейсхолдеров либо через рефлекшен проверять имена аргументов метода, как это делает Симфони.
Друзья анонимусы, кто скажет, как запилить собственный пхп движок? Ибо хочется попробовать не просто ковырять всякие PHPNuke или Joomla, а прописать что-то под себя лично. Вопрос заключается в чём - какой костяк у любого мало-мальски годного движка?
>>803797 Спасибо тебе, видно что разбираешься хорошо во многом. "Это надо постраться чтобы на пхп код работал медленнее чем код на пхп + передача данных + рендеринг страницы в яваскрипте" - самая первая версия включала функцию, которая в цикле делала запросы и вызывала еще функцию, которая тоже делала запросы, в БД. К концу года цикл был в 1000 витков на каждую отправку формы из одного поля. Так что можно. Далее вопросы только по php.
Привет, анончики! хочу попросить вас пояснить за установку composer. Ставлю его себе на винду. ранее был установлен денвер. при установки из экзешника нужно было ввести путь к файлу php.exe. нашел этот файл в папке денвера, но установка прошла с ошибками. Что делаю не так? что нужно установить? сейчас ничего не пойму.
>>804123 олсо, хочу поставить yii2. уже прочитал документацию, но плохо разрулился с установкой так как composer не установил. Собираюсь поставить себе фремворк на бесплатный хостинг и оттуда уже и работать, прочитал, что это можно сделать по ssh, но мне еще не дал доступ провайдер.
>Далее, нет логики в наследовании хелперов. Вот у тебя есть Helper и есть LoginHelper, который его наследует. Непонятно, а зачем? Там все равно почти все методы статические. Точнее, часть статическая, а часть нет, и почему, непонятно. >Там все равно почти все методы статические. Точнее, часть статическая, а часть нет, и почему, непонятно.
>>А разве в одном классе все методы должны быть либо статические либо не статические? Почему?
>Такого ограничения нет. Но должна быть какая-то логика по которой ты делаешь метод статическим или нет. Например, одинаково ли его поведение всегда или разное для разных объектов. Можно ли его вызывать не имея объекта или наоборот, он имеет смысл только если есть объект. У тебя там такой логики нету, слово static поставлено произвольно.
>>797257 >> Я не правильно написал метод getQuery и не понимаю когда должны вбрасываться исключения? >Скорее всего неправильно. Все GET параметры приходят от пользователя и могут отсутствовать. Действительно, я неправильно понимаю зачем нужны исключения, когда они должны вбрасываться и как с ними работать. Я перечитал заново мануал по исключениям, и у меня возникли вопросы, которые почему-то не возникли с самого начала:
>Все GET параметры приходят от пользователя и могут отсутствовать. Разве программы не созданы для того чтобы работать с данными пришедшими от пользователя? Всегда будут ситуации в которых от пользователя приходят неверные данные и нужно с этим что-то сделать. Разве исключения не для этого созданы?
Обработать ошибку значит сделать что-то при вбрасывании исключения? Допустим какой-то метод someMethod вбрасывает исключение SomeMethodException, значит где-то в начале программы я должен написать set_exception_handler(function (SomeMethodException $exception) { $exception->вывестиОшибкуВЛог(); $exception->вывестиЗаглушку(); ... });
https://github.com/someApprentice/Students/blob/master/app/Model/Helper/Pager.php#L56 Мне не хотелось писать функцию получающую из БД определённое количество отсортированных студентов, т.к. чтобы вызвать её сначала нужно рассчитать значение OFFSET, а не просто создать Pager и передать его в шаблон, и я подумал что можно передать в Pager все записи и получить нужное количество\отсортировать уже внутри него.
Сначала я хотел написать аналогичную usort функцию для spl, но потом подумал что ведь можно использовать массив вместо него. Какие преимущества у spl перед массивом? Я вижу только недостатки в том что его нельзя отсортировать, отфильтровать, пройтись по каждому элементу применив к нему функцию (аналогично array_walk). Придётся писать эти методы с нуля мы уже такое делали.
В мануале написано: Класс SplObjectStorage предоставляет соответствие объекты-данные или набор объектов, игнорируя данные. Эта двойная цель может быть полезна во многих случаях, включая необходимость уникальной идентификации объектов. >соответствие объекты-данные или набор объектов Что это значит? У меня не получилось загуглить. Уникальная идентификация мне не особо нужна, верно?
Как можно переименовать переменную $n, чтобы сразу было понятно зачем она нужна?
https://github.com/someApprentice/Students/blob/master/app/Model/Helper/Pager.php#L119 В какую сторону должна указывать стрелка сортировки в ссылке "SAT Scores ↓"? У меня логика такая: Если ссылка ведет на страницу с сортировкой по убыванию, значит и стрелка должна указывать вниз. Или же нужно сделать чтобы она указывала в ту сторону в которую стоит сортировка в текущий момент на странице?
Ведь можно же задавать переменную в условии и тут же её проверять?
https://github.com/someApprentice/Students/blob/master/app/Controller/Controller.php#L22 Здесь есть баг: если передать $_GET['sort'] = 'hash' или 'salt', то все записи отсортируются по хешу или соли. Но на практике это ничего не даст - всё равно никак не получится взломать пользователя зная только его позицию в сортировке хешу или соли. Стоит ли исправлять такие баги?
Не пишу ли я переусложненный код? Например в функции getSortLinkBy() https://github.com/someApprentice/Students/blob/master/app/Model/Helper/Pager.php#L107 я сначала пишу $queries = $this->queries, что само по себе выглядит как-то странно, затем ниже еще делаю какие-то, наверно непонятные для других, манипуляции с ней. Но чтобы функция работала именно такие действия нужно совершить: Я не могу в этом методе менять $this->queries['sort'] потому что при генерации новой ссылки всегда будет меняться это свойство, а именно по этому свойству делается сортировка записей, и сортировка делается в конструкторе чтобы не делать её вручную, а просто один раз создать Pager и передать его в шаблон.
>>803622 >У тебя внутренний подзапрос группирует по level Неа, по id ака раундам >>803617 >Как тут запрос оптимизировать? Считать раз в час по крону. А если нужно мгновенно обновлять среднее, а не раз в час? Тогда заводим 2 ячейки, в одной храним сумму значений, в другой их количество. Обновляем эти ячейки при каждой вставке в исходную таблицу. Спасибо, примерно так и сделал. Тот запрос сутки выполнялся и так и не выполнился, пришлось завести два новых столбика, которые обновляю по крону. К слову, авг двух полей по около 15ккк записей занимает около 5 секунд, я этим очень доволен. Как сильней разрастется, тоже на крон перевешу.
>>804203 пробовал по ssh, только нет доступа есть вариант какой-то типа архивом. как вордпресс или кодигнайтер? не понимаю что за сложности такие с этим yii/
>>804234 Разворачиваешь на хостинге композер, устанавливаешь через него yii, делаешь инит комит и клонируешь его себе на локалку. Потом настраиваешь свою идешку для работы с удаленным сервером и собственно работаешь.
Существует таблица в базе данных, где есть такие поля:
message_id message_body message_recipient user_id
Primary key = message_id user_id привязан к другой таблице
Если я делаю запрос по типу mysqli_query($link, $query);, то получаю обьект mysqli_result.
Тут начинаются интересности.
Мой запрос - "SELECT * FROM messages WHERE user_id='".$_COOKIE['id']"'"
Мне нужна информация о каждом сообщении, принадлежащем этому пользователю, чтобы отправить в таблицу. Я полагаю, что я могу получить ассоциативный массив(где ключ - это айди сообщения) с ассоциативными массивами, содержащими информацию о каждом отдельном сообщении, где я уже буду вставлять это в HTML. Но я не знаю, как получить такой результат. mysqli_fetch_assoc() возвращает единичный массив.
2) WHERE user_id='".$_COOKIE['id']"' мне кажется, нельзя доверять $_COOKIE в данном случае и напрямую вставлять его в запрос.
3) Массивы это чудесная вещь - можно вкладывать один в другой сколько угодно. Здесь ты создаешь массив пустым, чтобы не было ошибки; далее ты делаешь выборку из БД и перебираешь по одной все строки, записывая как ключ к $_list значение поля message_id (ключи уникальны), а как данные ключа - остальные поля.
Нельзя вставлять переменные, тем более пришедшие от пользователя, в SQL запрос. Это SQL-инъекция. И даже если инъекции нет, все равно читается плохо. Почитай про плейсхолдеры и подготовленные запросы.
А еще лучше исользовать PDO. Вот вы тут пишете код с mysqli, а что будет если произойдет какая-то ошибка? В вашем коде она просто игнорируется, никто о ней не узнает. Чтобы ее не пропустить, надо ставить if (и это написано в мануале который вы принципиально не читаете).
PDO в отличие от mysqli умеет выбрасывать исключения при приходе ошибки от базы.
Ты можешь установить зависимости композером на своем компьютере, запаковать в архив. Но автоматизируется ли этот способ? Я советую автоматизировать выгрузку кода иначе ты будешь как обезьяна при каждом обновлении вручную делать одни и те же действия. Плюс, можешь забыть что-то выгрузить и потом удивляться почему не работает. Времени своего не жалко?
https://github.com/someApprentice/Students/blob/master/app/Model/Helper/LoginHelper.php Тут со статическими методами все ок, но почему у тебя методы вроде хеширования пароля публичные? Лучше инкапуслировать (скрыть внутри класса) принципы хеширования пароля, а наружу предоставить методы вроде "задать пароль", "проверить пароль". То есть пройдись по своим методами подумай, какие ты выставляешь наружу, а какие являются внутренней логикой класса.
Зачем нужна инкапсуляция? Ну например если у тебя логика хеширования скрыта внутри класса и ты захочешь поменять ее, тебе достаточно будет поменять только этот класс и не искать, не вызываются ли методы где-то еще.
Ну и это гарантирует что работа с хешированием пароле будет заключена в одном классе, а не разбросана по коду.
Вообще, это мелочь, но все же, я хотел бы чтобы ты при написании класса задумывался, какие методы мы выставляем наружу, а какие закрываем.
Вот кстати в твоем коде, смена пароля сделана не в классе авторизации. В принципе твой вариант тоже имеет право на жизнь, но если бы ты перенес смену пароля в класс авторизации, степень инкапсуляции был бы выше. Ну к примеру, если мы поменяем алгоритм генерации пароля, у тебя придется лезть еще в класс Student.
Не то чтобы он идеальный (он завязан на использование пароля), но ты можешь просто для сравнения посмотреть на его код.
Насчет авторизации - по моему, у тебя там многовато кук ставится. Целых 3 куки. зачем так много?
Одна кука, допустим (id), идентифицирует пользователя Другая (hash), допустим, аутентифицирует его (то есть подтверждает что это он, а не хакер, подделавший id)
Ну то есть 2 куки - это что-то вроде формы с логином и паролем. Логин идентифицирует, пароль подтверждает подлинность.
Но третья-то зачем?
Более того, так как у нас хеши (в отличие от паролей) уникальные, мы можем и id не использовать, а ограничиваться только 1 кукой с хешем.
> В этом ведь есть логика иметь эти методы статическими? Да
> Действительно, я неправильно понимаю зачем нужны исключения, когда они должны вбрасываться и как с ними работать. Исключения - это исключительные ситуации, которые по идее не должны бы происходить. ну например, база сломалась и перестала выполнять запросы. Или в функцию, принимающую положительные числа, кто-то по ошибке передал отрицательное. Исключения обычно идут в логи и программист потом их смотрит, ищет причины и исправляет.
То, что в ГЕТ-параметрах что-то отстуствует - это вполне нормальная и ожидаемая ситуация. Мы понимаем, что пользователь может передавать нам любые параметры. И тут вместо исключения лучше бы например выдавать ошибку из серии 4xx.
У меня такая логика: мы не хотим замусоривать логи сообщением, что пользователь не передал какой-то параметр, так как мы это исправить все равно не можем. Значит, лучше предусмотреть такую ситуацию, и выдавать какой-нибудь подходящий HTTP-код из серии 4xx (ошибка пользователя).
Исключение конечно можно использовать, но в итоге ты получишь записи об ошибке в логах, с которыми ты ничего не можешь сделать.
> Разве программы не созданы для того чтобы работать с данными пришедшими от пользователя? Всегда будут ситуации в которых от пользователя приходят неверные данные и нужно с этим что-то сделать. Разве исключения не для этого созданы? Ну вообще, не совсем. Их можно тут использовать, если ты ожидаешь что таких запросов быть не может, но ведь пользователь может передать нам все, что угодно. Мы просто получаем исключения с которыми ничего не можем сделать.
> Обработать ошибку значит сделать что-то при вбрасывании исключения? Допустим какой-то метод someMethod вбрасывает исключение SomeMethodException, значит где-то в начале программы я должен написать Да, сделать что-то. Поймать исключеие можно либо глобально как в твоем коде, либо локально в каком-то месте кода через tyr/catch
> Мне не хотелось писать функцию получающую из БД определённое количество отсортированных студентов, т.к. чтобы вызвать её сначала нужно рассчитать значение OFFSET, а не просто создать Pager и передать его в шаблон, и я подумал что можно передать в Pager все записи и получить нужное количество\отсортировать уже внутри него. Это неффективно. Неправильно выбирать из базы 1000 студентов чтобы потом отобрать из них только 10, а 990 выкинуть. зачем? Используй LIMIT и отбирай только тех, кого нужно.
> Чтобы отсортировать студентов с помощью usort мне пришлось spl переводить в массив, а затем снова в spl. Не проще было изначально тогда в массиве хранить?
> Какие преимущества у spl перед массивом? Главное преимущество такое: в Spl можно в качестве ключей использовать объекты, в массиве - только строки. Допустим что у нас есть массив объектов (например студентов) и надо каждому сопоставить какое-то значение (например процент вероятности поступления). Мы можем создать SplOS в котором ключом будет студент, а значением - нужное нам число.
Также, использование объектов в ключе позволяет делать быстрые проверки вида "есть ли этот объект в списке". Ну допустим у нас есть огромный список объектов list и надо провеирть, есть ли в нем объект X или нет. В случае массивов мы конечно можем использовать in_array($x, $list. true). Но эта функция делает полный обход массива что имеет сложность O(N), то есть не очень быстро. А вот в SplOS мы делаем проверку через contains(), и поиск по ключу имеет сложность O(1), то есть делается быстро.
Если ты забыл, то напомню, что массив и SplOS позволяют очень быстро делать поиск по ключу, а вот для поиска по значению приходится обходить все элементы по очереди, и это медленно на больших списках.
Вот это основные сценарии, для которых нужен SplObjectStorage. Есть еще один плюс, что в отличие от массива с ним можно работать как с объектом, вызывать методы, наследоваться. Но если тебе нужна ООП-замена массиву то есть класс ArrayObject.
> Я вижу только недостатки в том что его нельзя отсортировать, отфильтровать, пройтись по каждому элементу применив к нему функцию (аналогично array_walk) Вообще, по SplOS можно пройтись циклом foreach так как он реализует специальный интерфейс Iterable: http://php.net/manual/ru/class.splobjectstorage.php
foreach ($spl as $object) { .... }
> Класс SplObjectStorage предоставляет соответствие объекты-данные или набор объектов, игнорируя данные. Эта двойная цель может быть полезна во многих случаях, включая необходимость уникальной идентификации объектов. > Что это значит? Это немного корявый перевод.
> соответствие объекты-данные Это значит что мы можем внести в SplOS объект как ключ, и какие-то данные (число, строку, другой объект) как значение. То есть использовать его как массив с ключами-объектами. И каждому объекту-ключу сопоставить и сохранить произвольное значение, и позже достать его из SplOS.
Ну например, поставить в соответствие студенту место, которое он занимает в списке лучших по баллам:
$place = 10; $spl[$student] = $place;
А позже можно взять это значение:
printf("%s занял %d место\n", $student->name, $spl[$place]);
> включая необходимость уникальной идентификации объектов. Это просто значит проверить есть ли объект в списке или нет.
> или набор объектов, игнорируя данные. Это значит, что в SplOS можно заносить объекты, не привязывая к ним данные. То есть использовать его как структуру аднных Set (множество). Ну например, мы можем сделать 2 множества, множество студентов, которые проходят на математический факультет по баллам, и на физико-технический:
$math = new SplObjectStorage(); $math->attach($student1);
$physics = new SplObjectStorage(); $physics->attach($student1); $physics->attach($student2);
А потом эффективно (без долгого перебора списка) проверить, есть ли объект в множестве или нет:
if ($math->contains($someStudent)) ....
Ну и может делать какие-то другие операции.
Вообще, в пхп у нас особо нет разных структур данных. У нас есть массивы, которые заменяют сразу несколько структур (Map, Set, Deque, Vector), но в других языках часто эти структуры есть по отдельности. То есть можно создать например Set, можно создать map и тд. Это имеет то преимущество, что мы ограничиваем операции которые можно делать со структурой.
Если тебе интересно, и если у тебя есть время, попробуй почитать что-нибудь про "структуры данных", например:
Зачем они нужны? Ну некоторые операции эффективнее выполнять с помощью одной структуры данных, некоторые с помощью другой. Например, хотя пхп массивы позволяют реализовать дек (двунаправленную очередь), но на больших объемах она будет неэффективна. Или например, операция вставки в середину в двусвязном списке очень быстрая, а в пхп массиве - не очень.
Ну и плюс, в программе использование конкретной структуры вместо просто массива помогает дать понять тому. кто читает код, что с ней делать можно, а что - нет.
То есть разные структуры данных заточены под разные сценарии использования.
Если есть вопросы, задавай.
> Это же копипаста верно? Я подумал что от неё можно избавиться поменяв результаты возвращаемые анонимной функцией местами:
Ну это небольшая копипаста. Можно добавить какую-то переменную, задающую порядок сортировки. Можно не добавлять.
Но эффективнее сортировать в базе, а не на стороне приложения.
> Как можно переименовать переменную $n, чтобы сразу было понятно зачем она нужна? Назвать напримр $direction, или $sortDirection, и добавить комментарий.
> В какую сторону должна указывать стрелка сортировки По идее стрелка указывает направление, в котором значения возрастают. Если сортировка по убыванию то вверх, если по возрастанию то вниз. Вроде так. Если ты под виндой, открой любую папку и посмотри как там сделано. (я посмотрел - в винде сделано наоборот - при сортировке по возрастанию стрелка указывает вверх).
То есть стрелка показывает текущее направление сортировки. Если сортировка идет не по этой колонке, то стрелки нет.
> Здесь есть баг: если передать $_GET['sort'] = 'hash' или 'salt', то все записи отсортируются по хешу или соли. Но на практике это ничего не даст - всё равно никак не получится взломать пользователя зная только его позицию в сортировке хешу или соли. Стоит ли исправлять такие баги? Можно не исправлять. Хотя лучше бы такого не допускать. В теории злоумышленник может зарегистрировать 100 аккаунтов, и по ним, зная их хеш, оценить чему примерно равен хеш других студентов. Это снижает число вариантов для перебора - примерно в 100 раз, если предположить что хеши генерируются случайно, то 100 аккаунтов разбивают множество хешей на 100 равных частей.
А еще, тут sql инъекции нет? Значения как-то проверяются перед подстановкой в запрос? Или они вообще в базу не идут?
> я сначала пишу $queries = $this->queries, Ничего страшного. Хуже то, что у тебя нет комментариев перед полем queries и нельзя понять что это значит (из названия "запросы" я ничего не понял).
Анончики, посоветуйте что почитать по ООП в пыхе. Алсо, вот наткнулся на видео https://www.youtube.com/watch?v=w3XUG6oyINI , вроде хвалят мол норм обьяснил парень, я вот сижу смотрю.
Только не изменилось ли кардинально ООП в семёрке?
>>804445 >В теории злоумышленник может зарегистрировать 100 аккаунтов, и по ним, зная их хеш, оценить чему примерно равен хеш других студентов. Это снижает число вариантов для перебора - примерно в 100 раз, если предположить что хеши генерируются случайно, то 100 аккаунтов разбивают множество хешей на 100 равных частей. Вот тут не понял. Можешь, пожалуйста, разъяснить поподробнее?
Салам ребят, вот недавно один анон посоветовал сайт https://www.freecodecamp.com/ - вот второй день тестю, уже часов 5 потратил точно, отлично выглядит, объсняет каждую мелочь. А теперь вопрос: этот сайт действительно помогает научиться программированию? Просто я закатился с нуля, поэтому даже не знаю определение "Класс", "Функция" и тому подобные, а тут меня сразу учат хтмлю. И чего еще посоветуете почитать/потренить для изучения языка?
Допустим в 10 аккаунтах злоумышленника хеши распределились случайно. Для простоты пусть это будут хеши
acc0 0aaaa acc1 1bbbb acc2 2cccc .... acc9 9xxxxx
Теперь злоумышленник сортирует список студентов по хешу. Допустим список выглядит так:
acc1 ivan ivanov acc2 acc3 acc4 ...
Злоумышленник теперь знает, что хеш ivan ivanov находится где-то между 1bbbb и 2cccc. Пространство для перебора сократилось в 10 раз.
То есть при случайном распроделении хешей имея N аккаунтов можно сократить число вариантов подбора в N раз. Если хеши длинные, то практически возможность взломать их то не даст, так как даже зная первые 3-4 цифры все равно остается еще много символов.
Но если удастся найти возможность задавать произвольный хеш для аккаунта (например через ошибку в форме регистрации или редактирования) то злоумышленник может методом деления пополам подбирать хеши других пользователей за короткое время.
Решил вкатиться в ит и начать с самого популярного js/php. Сколько времени займет обучение с самого нуля умею писать хеллоу ворлд на пыхп до состояния работаю макакой в днище конторе?
>>804795 ну раз макак то есть опыт, начинай решать задачи из учебника по 2-3 главы в день, что бы въехать в синтаксис и размять мозги алгоритмами, изучай параллельно как взаимодействовать с базой с одной стороны и как с юзером с другой (куки, сессии, формы, гет/пост и прочее) + можешь бутстрап навернуть. Хз, имхо если бы у меня под боком сейчас сидел падаван, я бы ему всё что знаю мпомог бы за 2 недели освоить, а если интенсивно, то и за неделю. Ну а далее мы бы с ним погрязли в ООП и прочих современных подходах к разработке, которые сука сам нихуя не понимаю :(
>>804795 >пыхп до состояния работаю макакой в днище конторе? Зачем тебе это? Да ты взвоешь после недели ковыряния в говне из Wordpress и Joomla, будешь ненавидеть свою работу, говорю из личного опыта. Куда все спешат? Не лучше ли годик-два поизучать дома, обзавестись знаниями, чтобы твоей квалификации хватало не только говно чистить, но и делать интересные, сложные задачи?
>>804808 Опыт, меня скорее всего отчисляют из ненавистной шараги, а значит я могу вкатиться туда, куда мечтал вкатиться еще года полтора назад, к тому же, даже в самой днище конторе я смогу научиться хоть чему нибудь и заиметь хоть какой то опыт.
Кароче начал читать Зандстру, и чет прихуел. Поначалу всё легко, ну основы я и так знал, но он помог в самом главном, как все ООП-примитивы (конструкторы, наследование) использовать правильно, и как строить простые классы не через жопу, а через геттеры и сеттеры и я наконец понял зачем нужны private & protected и всё такое.
Думал как же хорошо и всё ништяк, и буду ща по 100 страниц в день осваивать, и за недельку в книгу въеду, и буду у мамы молодцом, а хуй там. На 70-й халява кончилась, пошла муть про абстрактные классы и интерфейсы, и тут я завис, просто реально сидел пытался понять в чем суть написанного и зачем это вкручено в примеры кода, которые там приведены, и так НИФИГА И НЕ ПОНЯЛ, блин. Как же сложна то. Надеюсь что сегодня разберусь таки. Параллельно сейчас сяду писать вектор что ли, хоть я его и писал уже год назад >>803294 но сейчас пожалуй решу с 0, что бы хорошо всё закрепить и повторить, ну и решать не отпизды, а используя почерпнутые в книжке знания.
>>804811 Нет конечно, они дают только базовые знания о языке. Тебе нужно будет научится устанавливать и настраивать веб сервер с интерпретатором и базой данных, и на базовом уровне освоить хотя бы один MVC фреймворк, чтобы быть хорошим кандидатом в джуниоры. Вот как сделаешь три задачи из ОП поста (студенты, файлообменник и TestHub), тогда можешь считать себя джуниором.
>>804811 А, я тебя понял. Ты не работаешь в днищеконторе, а только стремишься. Ну кароче пару месяцев займет минимум, в общем прочитай ОП-посты и не спрашивай хуйню. Всё равно придется дохуя работать и писать что бы научиться с 0 МОЧЬ В ВЁБ
Поясните все же как надо реализовать MVC. Вот реально, все до этого изучал со скоростью сверхзвуковой макаки, но с MVC у меня случился факап. Что я делаю не так?
>>804835 >как стать твоим юным падаваном? Материализоваться в моей хате прямо здесь и сейчас со своей пекой/ноутом, что бы мне не приходилось отвлекаться на всякие скайпы и прочее говно, а тупо словами в свободное от своих дел время рассказывать как работают циклы и прочие функции.
секретный спойлер: тупо пересказывать тебе учебник опа и отправлять все равно перечитывать каждую главу по 2 раза, но если уж непонятно что, то сесть рядом и на примитивном уровне с 0 всё разжевать
Прост сядь почитать, попробуй пописать. Не будет для тебя никакого супер-легкого пути волшебного, при котором ты раз и уже джун. Придется всё равно всё освоить и всё проработать, что-то мб меньше, а что-то больше. ОТ себя могу посоветовать не сидеть долго на регулярках из учебника ОП-а, если не получается, а сразу переходить к сложным задачам и попытке сделать свои простейшие вещи.
>>804837 Я просто даже не понимаю с чего начать. Уже неделю наверное у всех выспрашиваю, ктото отвечает про то, что надо начинать изучать базы данных и строение сети интернет, ктото пишет, что нужен html и css, вы советуете php. В итоге какойто анон посоветовал https://www.freecodecamp.com - будет ли с выполнения тамошних заданий профит?
>>804829 >Поясните все же как надо реализовать MVC
В зависимости от того что и где у тебя на сайте пользователь накликал, запускаются разные контроллеры.
Например если пользователь заходит в раздел статьи (articles), то и запускается скрипт он же контроллер, он же класс articles.php У контроллеров соответственно могут быть методы вида(показать статью, редактировать статью, создать статью и прочее)
Если пользователь заходит в раздел с другим функционалом, то другой контроллер соответственно всё обрабатывает.
Контроллер так же в свою очередь пытается понять кто пришел, можно ли ему тут быть, что он хочет, и можно ли ему это позволить. (ну например если пришел просто пользователь, то он может статью только посмотреть, а если автор, то и подредактировать, а незареганных нашщ контроллер вообще отправит регаться)
Если пользователь после всех проверок достоен того что хочет, то можно начинать спрашивать с модели вещи, которые позволят нам ответить на его запрос.
Модель это то, что с базой будет работать в этом случае. И например у неё есть методы: сложить в базу статью, спросить с базы статью, переписать в базе статью на новую.
Вот контроллер такой спросил с модели статью. $article = Model->getArticle($id);
Ну и вот у тебя есть теперь информация, в виде какого-нибудь массива или объекта, которая нужна пользователю в переменной $article
Ну и ты передаешь её во вьюху, которая по сути является html-каркасом, с заготовленными вставками php-переменных.
Например у тебя во вьюхе будут места
<h1><?=$article->title;?></h1>
<p><?=$article->text;?></p>
и прочие ссылки на картинки и другие статьи.
Вот собственно и всё. ПОСМОТРЕЛИ КОНТРОЛЛЕРОМ ЧТО ЮЗЕР ХОЧЕТ, РЕШИЛИ ДАЕМ ЕМУ ЭТО ИЛИ НЕТ, СПРОСИЛИ ЧЕТ С МОДЕЛИ, ОБРАБОТАЛИ ЕСЛИ НАДО И ПЕРЕДАЛИ ВО ВЬЮХУ, В КОТОРОЙ ВСЁ РАССТАВИЛИ ПО МЕСТАМ.
>>804840 Епт. Начинай со стандартных для любых ЯП конструкций, типа переменных, массивов, циклов, функций и т.п. Эти вещи вообще почти одинаковые во всех Си-подобных языках, можешь вообще любой учебник открыть, там все одно и тоже. Потом ООП учи. Ну а дальше изучай уже конкретно интересную тебе технологию. Ну и конечно же, если ты хочешь в веб, то выучи хотя бы основые html/css, без этого никуда. Почитай еще кстати чем отличается бек-энд от фронт-энда.
>>804840 Что бы стать джуном в говноконтору, тебе нужно знать строение любой веб страницы, и что за ней за что отвечает. всякие блоки там, ссылки картинки списки таблицы и прочее. Это собственно html+css Можешь сюда сходить если всё лень и попробовать пол дня поизучать основы https://htmlacademy.ru даже регаться не нужно вроде, прост начал и пошел делать одно задание за другим.
Но в современном мире нам не достаточно прост страниц которые написаны на html, понимаешь? Интернет как бы ДИНАМИЧЕСКИЙ, возьмем тот же двач, он постоянно меняется, повяляются новые посты, новые треды, новые картинки и прочее, понимаешь?
Для этого и нужен php, потому что он как раз и делает такие сайты как двач динамическим.
Например какой-то вася написал пост, php его обработал и сложил в базу данных (допустим mysql) и когда следующий анон зайдет в тред, опять же специально написанный скрипт сгенерирует ему страницу так, что пост васи там уже есть. Хотя минуту назад его бы там не было.
То есть задача программиста сделать так, что бы наш php-код писал в итоге html-страницы и отдавал юзерам постоянно менающийся контент.
Надеюсь доходчиво пояснено. В общем и целом тебе нужно уметь воспроизводить весь этот цикл, тут мы изучением всего этого и занимаемся.
А задачи начинаются ясен хер с примитивов, ибо сначала нужно научиться писать helol world и складывать числа, а потом уже переходить к умным скриптам, ты бы кстати уже мог пройти 2 главы в учебнике пока тут ищешь легкий путь и выспрашиваешь, как бы тебе не выучить чего лишнего.
>>804847 > В самом примитивном виде наверное зачатки мвц 10 лет назад выглядели так:
файл допустим article.php на который юзер заходил site/article.php
всякие проверки if ($_GET) {
}
if ($_COOKIE) {
}
include('functions.php'); - некий предок современной модели где были свалены функции
$article = get_article($id); -запрос в самописную функцию которая лежит в нашей "модели"
include('template.php'); - подгружаем шаблон, а он же вьюха в современной интерпритации, в котором расставляем по местам всё и генерируем нашу страницу, которую отдаем юзеру.
Сейчас же всё на ООП и написано классами с умным роутингом и всё такое, и у тебя допустим юзер проходит по ссылке вида:
site/article/add и поподает в метод add, контроллера article
Но в целом общая схема не изменилась
Пусть меня обоссут если что, я не особо прошарен, mvc постигал на кодигнайтере.
>>804858 Ну это сложный вопрос. Что бы до совсем нубов довести, целые книги блядь по MVC пишут, я же не буду тебе книгу писать тут, задай конкретный вопрос, я тебе постараюсь ответить.
>>804863 Я сам не знаю как стартануть студентов на pure-php, как я уже говорил, я на примере уже готового фрейморвка знакомился с mvc, и сейчас сам сел за ООП конкретно и сосу в нем БОЛЬШИЕ АБСТРАКТНЫЕ ХУИ >>804813
У меня большие проблемы как стартануть и заткнуть всё с написанием ЯДРА так сказать, и роутинга, поэтому откатился назад и продолжу дрочить другие вещи для лучшего понимания.
Модель в студентах супер-легко
Вроде в этой задаче хватит 1 класса под модель, больше не вижу смысла.
Функции нужно реализовать примерно следующие:
....function getStudent($id) { ........тут всё просто, даем функции $id студента, который например зашел на свою страницу, она нам возвращает всю его инфу ....}
Class StudentModel { ....function getStudents($from, $to) { ........эта будет брать с базы несколько студентов, и возвращать нам большой массив с их именами или что там нужно для первой страницы, где будет весь список студентов. Например ты на первой странице списка и тебе нужно вывести с 1 по 10 студентов, соответственно твой контроллер должен передать этой функции аргументы 1 и 10, ну ты понял. ....}
....function addStudent (array $studentData) { ........Эту функцию будет вызывать контроллер когда студент будет регистрироваться и передавать в неё ту инфу которую студент ввел при регистрации, инфу конечно нужно проверить и обработать на каком-то уровне, сама функция еще всё это должна сложить в базу ....}
....function rewriteStudent($id, array $studentData) { ........Опять же, при редактировании, контроллер передает сюда $id студента которого мы собрались редактировать, а так же массив с редактируемыми данными, допустим такой передали array ('age' => 19, 'name' => 'petya'); соответственно функция должна разбирать этот массив на кусочки и перезаписывать в базе поля age и name у студента с id = $id ....}
Со вьюхами всё тоже предельно просто если ты знаешь хоть немного html
Хотя я не знаю опять же как красиво реализовать подгрузку вьюх в ядре нашего проекта, что бы в контроллере ты просто подгружал вьюху в конце как-то так:
View->load($viewData, 'studentsList.php');
а твой метод парсил $viewData и позволял к его элементам из вьюхи обращаться через переменные, сложна объяснить, игнайтеровское наследие в голове, блджад
а во вьюхе ты мог в нужные места вставлять <?=$name?> и <?=$surname?>
Охуеваешь попытки осмыслить все эти цепочки и что вообще тут делает $this в каждой строчке, если это обращение к методам/полям объекта в контексте себя? То-то же, представь как мой мозг искалечен этим всем.
Надеюсь тебе поможет это, если что спрашивай еще что-нибудь. Модельные методы можно сделать и умнее, что бы например у тебя была всего 1 функция возврата студентов а не две, и там внутри было условие, с разделением. Так же одна функция может отвечать и за запись в базу и за редактирование, но по мне так лучше.
>>804863 Есть у тебя сайт, есть такой запрос site.com/home/student/4
class FrontController обрабатывает входящий запрос и исходя из этого понимает, что нужно запустить class HomeController и функцию student($id){}
Ты получил запрос и в контроллере ты его обрабатываешь то есть в функции student($id){} ты обращаешься к модели у которой запрашиваешь студента с таким айдишником и модель возвращает тебе обьект Student со свойствами нужного тебе студента. ( модель это класс который работает с бд, зачастую делается одна таблица - одна модель, в данной ситуации модель будет называться Student )
Далее ты в контроллере либо запускаешь класс который запускает представление либо просто пишешь так reqiure ('твой файлик php') и каким-то хуем передаешь еще туда и свой обьект и уже в представлении показываешь свойства своего обьекта и человек получает инфу о студенте с таким-то айдишником
это тебе лишь примерно показал пример, очень простой и примитивный, конечно же делать такой запрос тупо как home/student/5 тупо потому что он очень длинный, можешь во фреймворках как -то реализовано
Далее можешь просто инклудить, можешь написать свой класс подгрузчик, который будет инклудить файлы вместо тебя.
например в том же игнайтере если ты в контроллере хочешь получить доступ к модели, то можно сначала написать $this->load->model('ModelName.php'); Ну и ты можешь что-то подобное реализовать у себя в "ядре"
>>804924 >Большинство разработчиков объектно-ориентированных приложений используют такое соглашение именования файлов, в котором каждый класс хранится в отдельно созданном для него файле. А зачем так делать?
>>804937 Наверное потому что в каком-нибудь проекте большом у тебя не одна моделька, а 100, а еще и не ты 1 работаешь над всеми этими модельками, а например еще 10 ребят. Ну и вот, тип для удобства, поиска класса в файлах.
Опять же что бы просто заинклудить файлик User.php, а не искать модель юзеров в MegaProjectModel.php среди 100500 других классов и всё такое. Наверное корни еще растут губоко в те времена, когда не было систем контроля версий и ты мог затереть чужие правки в файлах.
>>804849 Я ни в коем случае не ищу легких путей, просто два дня одно поизучаешь, потом оказывается что ты учил херню, потом два дня учишь другое, оказывается, ты не знаешь основ языка, учишь третье, в итоге получается херня, так еще и время потрачено. Вот смотри, выучусь я по твоим рекомендациям, и уже есть шанс пойти в говноконтору? Или по крайней мере фриланс?
>>804947 Значит я запутался, просто думал там типичный учебник по конкретным функциям языка, где не объясняются основы программирования. Сори за ебланство
>>804959 Ну там ну тип хочу, вот недельку ну тип поебланить и уже джун, что бы потом хуяк-хуяк и уже мидол через год, в общем ничего не делать и всё было, ну там зп 5к$, в японию потом уеду, там говорят всё есть))))
>>804959 Если конкретно, начать с основных основ программирования (что такое массивы, функции и т.д.), потому как вкатываюсь с нуля, после этого изучить html/css/php, по возможности вкатиться в Джаваскрипт, проблема в том, что, я даже не уверен, что именно это мне нужно. В общем, вкатиться в веб-программирование
>>804963 Даун, не? Заранее сказал, что готов учиться столько, сколько нужно, тому, чему нужно, но мне надо узнать что именно учить. Усидчивость есть, с людьми могу хоть неделями не разговаривать, работать и учиться всегда готов. Просто я серьезно не могу разобраться, потому что каждый советует по разному
>>804965 >Заранее сказал, что готов учиться столько, сколько нужно, тому, чему нужно... Я тоже готов каждый день ебать тянку своим 18см болтом, но проблема в том, что у меня тянки нету. А их столько вокруг ходит, что я прост не знаю какую выбрать, ага, хуй знает в общем, они все такие разные, вдруг прогадаю, выебу тянку, а она не та самая, зря время потратил тольк. Продолжу лучше по улице ходить да на тянок смотреть, но не подходить к ним.
>>804984 Двачую братишку, веб сука объемная штука. Тут дохуя всего задействованно, что бы обходить костыли устаревших до момента выхода протоколов и эмулировать работу обычных приложений. Надеюсь веб будущего будет куда лучше в этом плане.
>>804964 >Если конкретно, начать с основных основ программирования (что такое массивы, функции и т.д.), потому как вкатываюсь с нуля Так начинай, лол, в чем проблема?
>>805019 Читай шапку треда, там для старта в пыху более чем достаточно. До момента ООП вообще нихуя сложного. Тем более, что открыв учебник по любому си-подобному ЯП ты найдешь все тоже самое.
>>805026 Алсо твоя функция нихуя не возвращает же. Попробуей дописать в функции return $homoCreditTotal; И выводи echo getBalanceInFuture(какие у тебя там значения, ну ты понел);
>>805042 Мог бы и не пожлобиться на коменты, нуфагу, он может и так не понять. Короче слушай - функция должна всегда-то что-то возвращать, иначе она бесполезна.
>>805049 Нет не бесполезна. Функция может и просто эхать что-то на экран. Например целую html страницу готовую, почему бы и нет.
Просто он вызывает функцию внутри самой себя и ничего не ретернит и не понимает о том, что переменные доступные внутри функции и переменные снаруже - это два разных мира :(
Задачка Анон против Камплюктера. Интересно, что за удача "ждете" меня сегодня вечером. ) Надеюсь молния не ударит ) Переписал последнюю строку без условия просто else.
Нашел прикольный онлайн интерпретатор http://codepad.org/M7vtRNPd Указывает, что за ошибка и в какой строке. Тупанул с этой задачей )
>>805206 Привет, аноны. Пишу интернет магаз на yii2 и вот дошел до админки, назрел вопрос. как лучше сделать админку: 1) написать отдельный контроллер Admin? 2) создать директорию в корневой и названием Admin и там писать приложение? как делать правильно, какие плюсы и минусы?
>>805219 >1) написать отдельный контроллер Admin? Ну да, звучит разумно. Пишешь новый контроллер, ему делаешь свои вьюхи. По возможности расширяешь модель слегка, что бы можно было делать все то же что и юзер но больше.
>2) создать директорию в корневой и названием Admin и там писать приложение?
То есть хочешь как бы второе приложение написать с доступом к той же базе? Придется энивей копипастить код и модели, так зачем? Разве суть ООП как раз не в расширяемом без копипасты коде?
Сап, аноны. Собираюсь с другом писать разные инернет-магазы и вот решили выбрать движок, с которым мы будем работать, становится в нем джедаем и втюхивать его клиентам. Естественно важна гибкость движка и возможность допиливать на него модули. Сам работал с shop script 5, wordpress, joomla, modx (зарывался в них не глубоко поэтому мнение о движках поверхностное). какой вы подскажите?
>>805214 >Объясните плиз Учись сам добывать информацию, у тебя под носом гигантская база знаний. Допустим, у тебя есть переменная $a, равна она 1. Тогда: echo "qwe{$a}qwe"; // Выведет "qwe1qwe" echo "qwe$aqwe"; // Ошибка, так как интерпретатор будет искать переменную $aqwe
>>804386 >Зачем нужна инкапсуляция? Ну например если у тебя логика хеширования скрыта внутри класса и ты захочешь поменять ее, тебе достаточно будет поменять только этот класс и не искать, не вызываются ли методы где-то еще. Но тогда всё равно же придётся искать метод который предоставляем наружу. Если мы поменяем внутреннюю логику метода так, что он будет возвращать свершено другой результат, например заместо строки массив, то метод который мы предоставляем наружу, тоже нужно будет поменять, и для этого нужно так же искать где он вызывается.
Я перечитал твой мануал по инкапсуляции и могу сказать, что она нужно скорее чтобы скрывать внутреннюю логику, а не облегчение её редактирования.
Так же, мне теперь кажется, что я зря в некоторых сущностях делал свойства закрытыми, ведь при работе с ними нет никакой внутренней логики, мы просто их меняем. И чтобы их не поменяли на неверное значение есть класс валидации.
Я не могу вспомнить как я научился такому методу. У тебя случайно не было так написано в уроке по DI? Так вообще делают?
>>804386 >А ты кстати смотришь код других анонов? Да, смотрю, но только чтобы понять как работают отдельные функции, чтобы самому не запутаться. У них там всё равно всё сделано через роутер, а я даже не знаю откуда они берут эту задачу чтобы делать через него, не говоря уже о том, что я не знаю зачем он нужен и как он работает. Я бы хотел сделать свою задачу через него, но я не знаю даже что начать читать чтобы его сделать.
Еще у этого анона есть такие классы как от Request, Response - мне это тоже не понятно зачем они нужны.
Я не могу обещать что я сразу же возьмусь за эти задачи, т.к. я хочу побыстрей уже взяться за задачу на Slim'е, но я могу точно сказать, что если ты мне подскажешь с чего начать, я буду это изучать во время решения других задач.
>но ты можешь просто для сравнения посмотреть на его код. У него, в отличии от моего кода, логика регистрации, залогинивания, а так же хеширования и создания соли, сокрыта в хелпере. Раньше я думал, что контроллер отвечает за логику того или иного действия, а модель это, исходя из названий содержащихся в ней классов, всего лишь вспомогательные методы для него. Ведь как может отвечать за всю логику лишь Помощник? Валидатор тоже не может отвечать за всю логику. Класс с работой с БД - тоже. Это сбивает с толку. Так почему в Модели, которая отвечает за логику, за внутреннее состояние программы, мы не содержим классы как AuthModel или просто Auth(orization)?
>>804386 >Насчет авторизации - по моему, у тебя там многовато кук ставится. Целых 3 куки. зачем так много? > >Одна кука, допустим (id), идентифицирует пользователя >Другая (hash), допустим, аутентифицирует его (то есть подтверждает что это он, а не хакер, подделавший id) > >Ну то есть 2 куки - это что-то вроде формы с логином и паролем. Логин идентифицирует, пароль подтверждает подлинность. > >Но третья-то зачем? Так токен же, для csrf протекции. Я тоже сомневался стоит ли её создавать и при регистрации.
>>804434 >Ну например, поставить в соответствие студенту место, которое он занимает в списке лучших по баллам: > >$place = 10; >$spl[$student] = $place; > >А позже можно взять это значение: > >printf("%s занял %d место\n", $student->name, $spl[$place]); $spl[$place] вернет NULL. Ты наверно хотел написать $spl[$student] вместо этого?
>>804434 >Это значит, что в SplOS можно заносить объекты, не привязывая к ним данные. О каких данных здесь может быть речь?
>>804445 >А еще, тут sql инъекции нет? Значения как-то проверяются перед подстановкой в запрос? Или они вообще в базу не идут? Нет, не идут, но сейчас я буду переделывать используя LIMIT, а не перебирать n студентов. Я уже прочитал новый урок про инъекции и знаю как с этим бороться.
Застопарился. Не въезжаю, почему в index.php код $frontController=new Project\Controllers\FrontController($container); нормально читается (то есть автозагрузчик composer'а работает нормально), а в container.php строка 45 return new Project\Classes\Authorization($c['table']) уже выдаёт ошибку
Насчет системы публикации скриптов. Можешь объяснить или дать ссылку как это все работает (как например заставить бутстрап попасть в паблик папку)? Гуглю и ничего не понимаю, как-то сложно по сравнению с композером все вручную ставить. Поставил gulp (потому что он вроде в отличии остальных на виндоус и на него хоть что-то в гугле откопал) и завис в туториалах. Это все потом будет в таком файле как у анона https://github.com/foobar1643/filehosting/blob/master/post-install.sh и подцепляться в composer.json?
Не бросайтесь камнями, но не могу решить примитивную задачу. Вроде бы все делал из учебника ОПа, но запускать не хочет. Главный вопрос - где ставить exit? <?php
error_reporting(-1);
$humanDice1 = mt_rand (1, 6);
$humanDice2 = mt_rand (1, 6);
$compDice1 = mt_rand (1, 6);
$compDice2 = mt_rand (1, 6);
echo "У человека выпало ($humanDice1) и ($humanDice2)\nУ компьютера выпало ($compDice1) и ($compDice2)\n"; $humanSum = ($humanDice1 + $humanDice2);
Короче суть такова. Раз я уж решил в кодинг, то надо бы и среду разработки выбрать, правильно? Выбирал между нетбинс, пхпшторм и саблайном. Остановился на последнем, т.к. он самый шустрый. Может кто посоветовать маст-хев плагинов? Кроме автоформатирования пока ничего в голову особо не приходит, может есть еще какие-то интересные фишки?
>>805473 Алсо еще хотел поговорить про цветовые схемы. Недавно читал, что я кобы ЧБ схема меньше грузит глаза, это правда? Кто-то сравнивал по ощущениям, допустим 8 часов работы с черным и 8 часов работы с белым фоном?
>>805474 Я люблю светлые схемки. Но сижу только на чёрной, потому что в код на светлой схеме мне приходится вглядываться. На тёмной код читается сам собой.
Общая идея такая. При выгрузке сайта у нас может появиться необходимость что-то делать со статическими файлами (js/css/картинки), например:
- копировать файлы библиотек в публичную папку (твой случай) - склеивать css файлы в один и минифицировать ради ускорения загрузки сайта - конвертировать SVG картинки (которые не везде и не всегда корректно отображаются) в PNG-картинки, да еще и в разных размерах. - объединять мелкие картинки в спрайты и править соответствующий css ради оптимизации
Для решения всех этих задач надо сделать программу или скрипт, который будет это делать. Это может быть самописный скрипт или ты можешь использовать существующие программы: gulp, make.
foreach ($sources as $source) { copyToPublicDir($source); }
Примеры скриптов на make или gulp ты можешь попробовать написать сам, почитав мануалы и туториалы к ним.
Там еще можно придумать всякие оптимизации - например, на линуксе вместо копирования можно создавать симлинки, что быстрее.
Имея скрипт публикации, ты можешь вызывать его в любой момент чтобы скопировать статичесские файлы. Также ты можешь прописать его вызов в composer.json, чтобы он вызывался после установки или обновления зависимостей: https://getcomposer.org/doc/articles/scripts.md (англ, при желании наверно можно найти и русскую статью).
Главнвй принцип, что такие вещи надо автоматизировать. Чтобы для разворачивания сайта надо было выполнить несколько команд и не делать рутинных действий.
Уточни, что именно тебе непонятно.
> Можешь объяснить или дать ссылку как это все работает (как например заставить бутстрап попасть в паблик папку)? Либо написать скрипт руками либо настроить gulp или make. Я бы написал руками так как случай тривиальный и я знаю bash.
Скорее всего Project... отсчитывается от текущего неймспейса и надо писать \Project\.... Либо автозагрузчик еще не подключен. Либо опечатка в имени класса.
Ты можешь попробовать отдебажить ситуацию, натыкав echo или var_dump в autoload.php
Кнопку можно привязать к форме в новых бразузерах специальным HTML5 атрибутом. Можно обрабатывать нажатие скриптом. Но лучше конечно поправить кривую верстку и поместить кнопку в форме.
- сделать 2 отдельных приложения (модуля или как там это называется) - frontend (сам сайт) и admin. профит в том, что мы можем например централизованно разрешать доступ к админке только по паролю.
- сделать базовый админский контроллер и наследовать контроллеры админки от него. В базовом контроллере сделать проверку логина и всякие полезные функции. Недостаток в том, что если забыть отнаследоваться от нужного контроллера можно например случайно отключить систему авторизации.
Я бы делал через модули.
Вообще, я скажу что модули пригодятся при разработке огромных проектов. Потому что если у тебя 20 человек несколько лет пишет код и они валят все контроллеры в одну папку то скоро эта папка станет нечитамой. Разделение сайта на модули позволяет организовать код лучше.
Для основ - наш учебник из ОП поста или любой другой аналогичный, если найдешь.
Также заведи привычку гуглить все функции, которые встречаешь, и читать официальный мануал по ним. Официальный мануал на php.nat это справочник, он не совсем для изучения языка, а для изучения как та или иная фича работает во всех подробностях.
Насчет "много информации" - в хороших учебниках в начале всегда пишут, что надо знать чтобы его читать. Соответственно ты можешь отсеять те книги или статьи для которых у тебя пока маловато знаний.
Правило один класс = один файл также нужно чтобы не было гигантских файлов с которыми неудобно работать.
Вообще, в проекте нужны стандарты по любому поводу. Как называть файлы, как оформлять код, для чего какая папка, как работать с БД, и тд. Иначе в команде каждый начнет делать по своему и ты замучаешься исправлять все.
Не просто. Автозагрузчик позволяет вообще не писать реквайры/инклуды. Это избавляет от рутинных действий и убирает из кода пути к файлам.
> а не искать модель юзеров в MegaProjectModel.php среди 100500 других классов Правило: каждый класс в отдельном файле. Ничего искать не придется, если соблюдать PSR-4 то имя файла определяется именем класса. И в MegaProjectModel.php может быть только класс MegaProjectModel и ничего больше.
У меня обычно глаза устают от темной схемы так как в браузере все светлое и переключаться неудобно. Ну то есть не то, чтобы так уж устают, но светлая тема воспринимается лучше. Некоторые даже консоль делают черным по белому.
Установить советую php companion для работы с неймспейсами.
У меня такие плагины: php-twig, docblockr (вставляет doc комментарии), emmet (для html кода), jshint gutter или как-то так, который умеет проверять синтаксис и находить сомнительные места в js коде.
Решил я поиграться немного с типами данных в пхп: http://ideone.com/9aVD5D Так вот, объясните нуфагу, а почему оно так? Почему что бы я не делал, пхп все сводит к числам? Зачем оно так? Разве не логично, что строки и числа нельзя сравнивать?
>>805558 Если в строке первой идет число, то php при арифметических операция остальное обрезает и считает за число. Если первой идет буква, то дальше за строку считает, независимо от того, сколько там цифр дальше. Если надо как строки добавлять, используй . оператор, + для чисел же.
Уже семь часов это насилую. Уже не понимаю как убрать "озвучку" нулей в единичных числах (пятьсот сорок ноль тысяч) Что за функцию в целов, стоит учить дальше? Я безнадежен
Что-то я совсем не понимаю как сделать задачу с генератором имён по слогам. Вроде бы и понимаю, как рандомный элемент с массива вытащить, но как-то не понимаю. Может подскажет кто?
>>805708 Что именно ты не понимаешь? У тебя есть массив [a, b, c, d, e, f, g] Ты можешь сделать так что бы у тебя случайный набор из этих букв сгенерировался?
Берешь случайный элемент массива, потом еще один, потом еще один и так столько раз сколько тебе нужно
>>805708 Вот так получилось. http://ideone.com/xjzGHH Чёт мне уже страшно с этого языка. Особенно с преобразованием первого символа в заглавный. Наверное я чего-то не понимаю.
>>805733 И что тебя смущает? Вроде бы всё правильно сделал. Тут же главное в голове придумать алгоритм из зарание доступных тебе кирпичиков, а потом его в языке воплотить, и всё собственно.
Чем больше занимаешься, тем лучше видишь связь между придумыванием и воплощением в языке. >Особенно с преобразованием первого символа в заглавный.
Я бы делал через известную мне функцию mb_strtoupper(), причем достаточно калично, отрезал бы первый символ имени, перегонял его в большой, и потом приклеивал назад
В php7 вроде исправлили проблему с "10 котят" - это будет выдавать варнинг. Само преобразование нужно так как часто данные, пришедшие от пользователя (в $_GET), из файла, базы данных, представлены в виде строк и без этого надо было бы делать явные преобразования.
Тебе надо разбить длинную стену кода на отдельные функции. Что касается проблемы с нулем, то нало разбивать число на миллионы, тысячи, единицы, и если в какой-то группе ноль (ноль тысяч) то пропускать эту группу.
> $name = mb_convert_case($name, MB_CASE_TITLE, "UTF-8"); Эта штука у тебя стоит внутри цикла и поому будет выполнена 4 раза. По логике, преобразование надо делать только 1 раз, значит команду надо ставить после цикла.
Ты должен полностью понимать что ты делаешь, а не ставить строчки наугад пока не заработает.
У опа написано, что абстрактные нужны мол только как основа от которой потом будем наследоваться и всё. Ну тип создаем абстрактный класс машина а от неё наследуем уже бмв и мерседес. Вот тип объект бмв и мерседес мы можем создать, а вот объект машина нет. И с пониманием этой части у меня проблем нет.
Но неужели нельзя просто использовать абстрактный класс для целей просто инициализации чего-то.
Например нужен нам класс управляющий, который будет наводить движуху в нашем приложении. Почему не сделать его абстрактным? Он будет просто то-то проверять и вызывать. В нем и не нужно ничего кроме методов. А описывать такой класс как обычный что бы в коде потом была нахер не нужная, но при этом как бы необходимая строчка: $engine = new Engine;
просто что бы иметь возможность запустить движуху: $engine->run();
>>805857 >Почему не сделать его абстрактным? Ну тип короч абстрактный как бы подразумевает ёпта, что тип от него короч как бы обязательно тип наследников создавать, короче без них тип абстрактный класс нахер не нужен. Более того, абстрактный класс тип существует только ради наследников.
>Вместо простой и понятной Engine::run(); Это почти то же, что и обычная функция. Ты тянешь процедурное мышление в ООП. Попробуй почитать пасту ОПа про DI, есть в репозитории pasta.
>>805870 Да я и пытаюсь въехать. Я понимаю у нас тут ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ как бы, но всё же, зачем доводить до абсолюта? Если мне и не нужен в каком-то месте сам объект, то нахуя его плодить?
>>805940 >Почему в доках написано PHP 5.6.24 is released Потому, что тебе лень проскроллить страницу вниз. Параллельно несколько веток у PHP выпускается.
Приступил к задаче из ОП-поста на мини файло обменник. В связи с этим у меня возникло несколько очень тупых вопросов. Первый и самый главный: зачем мне использовать фремворк, что это такое, что оно мне даст? На нем же ебаный хелло ворлд занимает 10 строк.
Не ну класс только для наследования это раз, объектов этого типа я создавать не буду, только наследников потом. Конструктор для каждого дочернего класса будет таким же, так что тоже не вижу смысл не писать его тут.
>>805954 https://ideone.com/NCoM6P вот, зацени мой велосипед. Если таки все хорошо (что маловероятно, так как наверняка можно было обойтись без вложенного фоича через рекурсивные итераторы, но я не нашел на stackoverflow как заставить прочитать вложенные папки), то куда его положить этот класс? В хелперы?
>>806127 А если ты просто в консоли напишешь ./postInstall.php, то у тебя ведь ничего не заработает, верно? Нужно было ставить Linux. Вообще, команда ./script обозначает "запустить скрипт из текущей директории с помощью интерпретатора, путь к которому указан в первой строке скрипта после #!". Это для Bash, насчёт других шеллов не знаю. Например, у меня интерпретатор PHP имеет абсолютный путь /usr/bin/php, поэтому я бы указал в качестве первой строки #!/usr/bin/php, Bash бы всё понял и запустил скрипт.
Короче, попробуй запустить скрипт из консоли, если у тебя путь к интерпретатору PHP есть в переменной окружения PATH, то команда "php path/to/script.php" должна заработать. Если заработает - то эту команду и пихай в конфиг композера.
>>806141 Ну я в принципе так и понял что такое инкапсуляция. Короче, насколько я соображаю, на производительность кода это не влияет, только на безопасность, не? ООП учу второй день, если что. Алсо, все фишки ООП в других языках выглядят так же, как и в пхп? Ну и еще вопрос - а зачем нужны интерфейсы? Это типа на начальном этапе разработки их делают как наброски, а потом имплементируют?
>>806150 Прости, больше я ебе помочь не могу, я сам учу ООП 3 месяца но не продвинулся дальше тебя. Про другие языки я не скажу, а про интерфейсы нихуя не понял сам :(
>>806127 И ещё: 1) Зачем в скрипте ООП? Простые одноразовые вещи нужно реализовывать просто, а не тянуть избыточные абстракции. 2) В твоём случае можно создать bat-скрипт. Считай, что это как Bash-скрипт, только очень ограниченный и под винду. Запускается тоже в консоли. Тебе нужно просто нагуглить команды для копирования файла и папки в bat-скрипте. Например, так копируется папка: http://stackoverflow.com/questions/4601161/copying-all-contents-of-folder-to-another-folder-using-batch-file
Я тут конечно еще со вчера нащитпостил, но все же. Анончики, я вот тут решил вообще почитать за житуху веб-погромирования, бэк-энда и такого всего. И вот что меня интересует - чем вообще веб-кодинг на других языках(питон, руби, node.js, asp.net, возможно еще что) отличается от пхп? Почему сторонники этих языков смотрят на пхп как на говно? Почему именно пхп самый популярный в веб-программировании? Правда ли что он сильно устаревает и скоро станет нинужен как перл?
>>806208 По идее ты должен в абстрактном классе задать какие-то функции, которые обязательно надо реализовать в наследниках. Вроде как это и есть суть абстрактных классов.
>>806208 Если у всех наследников Worker'а есть какой-то метод с одним и тем же названием, но реализовывать его нужно по-разному для разных наследников, то делай этот метод абстрактным и переопределяй в наследниках. PHP не обязывает тебя добавлять в абстрактные классы абстрактные методы, хотя по моему диванному мнению так было бы наглядней. Есть абстрактные методы - делаем класс абстрактным, нет - делаем просто базовым, от которого наследуемся.
>>806216 Мне кажется, таким как мы с тобой пока лучше не ебать себе мозги всякими абстракциями да интерфейсами, а лучше просто пытаться в ООП кодинг на практике. Авось потом само дойдет.
>>806238 Опять же я пишу в классе worker такие поля как salary, coffe хотя мог бы и не писать по идее, ведь они как бы все переопределяются в наследниках, но у меня в классе worker есть методы, которые как бы обращаются к этим полям, и если эти поля не писать в самом классе, то правильно ли тогда в классе иметь поля, которых нет в классе, но которые есть в наследниках???
Аноны, вы наверно видели много статей где критикуется MySQL и восхваляется PostgresQL. Мир IT - он такой, люди часто делают выводы не из сравнения преимуществ и недостатков, а из того что написал популярный блогер. Точно также вы можете услышать что один популярный язык программирования на самом деле плохой и всем надо писать на никому не известном языке с кучей математических абстракций.
А сегодня я прочел о том, что Uber переходит с postgres на mysql. Так-то!
Что касается PostgresQL, я считаю что это хороший проект, у него много интересных фич и конечно стоит его изучать. И для многих проектов это будет хороший выбор. Но когда дело доходит до сложных высоконагруженных проектов, приходится делать выбор, тщательно взвешивая все особенности продукта, а не доверяясь мнениям популярных блогеров.
> In CSS, identifiers (including element names, classes, and IDs in selectors) can contain only the characters [a-zA-Z0-9] and ISO 10646 characters U+00A0 and higher, plus the hyphen (-) and the underscore (_); they cannot start with a digit, two hyphens, or a hyphen followed by a digit. Identifiers can also contain escaped characters and any ISO 10646 character as a numeric code (see next item). For instance, the identifier "B&W?" may be written as "B\&W\?" or "B\26 W\3F".
Бутстрап и jquery - полезные и нужные библиотеки. Но перед ними надо научиться писать CSS и JS код руками без них. У тебя, на мой взгляд, код пока не очень.
У нас кстати в ОП-посте есть задачи и по CSS и по JS по которым ты можешь оценить свой уровень и которые ты бы мог решать параллельно с другими курсами. мы проверим решения и дадим подсказки если что-то непонятно.
>>806393 Вот у тех, кто говорит, и спроси. Если высокоуровневый инструмент попадает в руки неопытного, то некачественный код на выходе - не вина высокоуровнего инструмента. Что делать? Изучать низкоуровневые вещи, чтобы не было пикрилейтед.
У ОПа есть. jQuery полезная библиотека, которая содержит много нужных в повседневном использовании функций. Но у нее есть и недостатки:
- монолитность, нельзя взять то что нужно,надо тянуть всю библиотеку - любят свой подход вместо стандартов, например у них своя нестандартная реализация промисов - скрытие ошибок: если передавать в функции аргументы неправильного типа, они часто не выдают никакого сообщения об ошибке - не умеет искать поля формы по имени
Ну и многие из тех верстальщиков, кто пишет код на джейквери не знает толком ни яваскрипта ни самой джейквери, возможно отсюда и складывается такое впечатление.
Калькулятор. Стоит ли потом после прочтения ооп возвращаться и переписывать калькулятор(Как в учебнике с ооп и скобками) для того чтоб получше въехать(Или это будет невыполнимо для новичка?)
Аноны, кто подскажет? учу сейчас yii2, и хочу создать свой собственный контроллер, но хоть убей ничего не выходит, даже если скопировать дефолтный и поменять название файли и класса все равно выдает китайские иероглифы. знаю что где-то проебался и что-то не учел вот только не пойму где? может в controllerMap или типа того?
>>806537 в документации нашел, что нужно задавать в пространство имен контроллеров, нашел переменную в документации , но где мне искать ее в своих файлах, или мне добавлять динамически?
> Мне на самом деле эта строка нужна была, чтобы указать в какой папке вью. Если заменю "view": "status/register_ok" на "folder": "status" - будет норм?
Это по идее неправильно. Роутер отвечает за разбор УРЛ, а вид логично задавать в контроллере. Тут конечно можно при желании извернуться и разрешить в роуте указывать кроме имени действия дополнительные опции и уже в них - имя шаблона. Но мне конечно не очень нравится сама идея указывать имена шаблонов в роутере. Это конечно дложно быть в контроллере.
И зачем тебе эти шаблоны? Почему бы при успешной регистрации не редиректить например на список студентов и выводить там уведомление над списком?
> - В чём заключается непонятность структуры? Ты предлагаешь делать методы типа getDBLogin(), getDBPass() и т.д. или как? Я имел в виду, раз у тебя есть класс для чтения конфига, можно было бы возвращать объект этого класса. И например получать значения через $config->get('db.login')
Можно и массив конечно.
> проверь контроллер В общем, стало лучше.
> $isAuthorized=$this->c['isAuthorized']; Вот это мне кажется странным, по идее контейнер для хранения каких-то не привязанных к текущему запросу вещей. У тебя есть сервис авторизации - это надо у него выяснять, залогинен пользователь или нет.
Ну например , что если мы хотим обработать несколько запросов, ты обновишь значения isAuthorised перед каждым? А если это значение уже успел получить и сохранить какой-то сервис? В контейнере должны быть значения, не привязанные к текущему запросы. Потому что их может быть несколько, или вооьще не быть (например в командной строке).
В Симфони кстати тоже раньше хранили объект request в контейнере, потом поняли что это плохая идея, извернулись и добавили scope. Мне конечно не нравится, я за то чтобы его там вообще не было.
Текущий пользователь, город IP адрес и прочее - это не для контейнера сервисов, если рассуждать об идеальном коде.
> $find=isset($_GET['find']) ? $_GET['find'] : NULL; Надежнее писать strval($GET[...]) на случай если передадут массив например
Еще мне у тебя не нравится неймспейс Project\Classes - тут целых 2 слова которые не несут никакого смысла. По идее должно быть что-то вроде StudentList\???. ЧТо написать вместо Classes - трудно сказать, может просто класть тогда классы на 1 папку выше чтобы было app/Validator.php ?
> foreach ($_POST as $post) {$post=trim(strval($post));} > Он делает trim и strval, разве нет? $post это не элемент массива, а копия его значения. Ты меняешь переменную, а не исходный массив.
И менять $_POST тоже плохо. Это ведь пришедшие данные - вдруг они где-то еще нужны. Относись к нему как к массиву только для чтения.
> floatval($char); правильнее все же intval так как одна цифра дать дробное число никак не может. А так, в общем верно.
Стоит ли делать - ну а ты попробуй изучи ООП сначала. Я думаю, после изучения у тебя хватит энтузиазма и на калькулятор. Тем более что там в основном надо использовать готовые алгоритмы.
А лучше плагины для поиска символов разных алфавитов в одном слове (или шрифт где они разные). Спеллчекинг будет ругаться на всякие сокращения и названия функций.
Нельзя обращаться к полям, которых нет в текущем классе, так что ты делаешь правильно. Но подумай вот о чем. Вот допустим кто-то хочет унаследовать твой класс и создать новую профессию. Как он догадается что надо переопределить поля?
В некоторых случаях лучше использовать абстрактне методы вместо полей. Их нельзя забыть переопределить. Поля можно использовать когда в них по умолчанию разумные значения и переопределять их не обязательно.
Инкапсуляция нужна для лучшей читаемости кода и для упрощения внесения изменений в код. Пасты:
------
Инкапсуляция. У этого слова есть разные определения, в том числе такие что ничего не понять, потому объясню простыми словами.
Суть инкапсуляции в том, что класс скрывает (инкапслирует) в себе логику работы с данными и сами данные, а наружу выставляет методы. Пользователю этих методов не важно, как класс устроен внутри, как он хранит данные, ему достаточно вызвать нужный метод чтобы получить результат.
Это упрощает понимание кода: тебе не надо читать и разбирать код класса, достаточно прочитать название метода (и может быть комментарий к нему). Также, это упрощает изменение кода: если какое-то свойство имеет уровень private то доступ к нему возможен только из того же класса и тебе не надо бегать по всему коду и смотреть что там с этим свойством делается, тебе достаточно просмотреть один файл с этим классом.
Инкапсуляция это хорошо. Так как весь код, который занимается одной задачей, оказывается заключен внутри одного класса. Противоположный случай это когда код (или знание о его внутреннем устройстве) вылезает из класса и размазывается по всей программе.
Если проводить аналогии, то можно представить кофе-машину. Ты нажимаешь кнопку (=вызываешь публичный метод) и получаешь кофе (=результат вызова этого метода), при этом ты не видишь что происходит внутри нее и тебе не надо в этом разбираться.
------
Вот представь себе кофе-машину без инкапсуляции, то есть такую, у которой всякие внутренние части и кнопки выведены наружу. Чтобы ей пользоваться, тебе надо сначала разобраться как она работает, где что засыпается, где подогревается и ты должен сам догадаться сколько минут его греть и перемешивать. Фактически знание о процессе приготовления кофе не заключено в машине, а размазано по машине и голове пользователя. если мы хотим поменять рецепт приготовления, мы меняем не только конструкцию машины но и переобучаем всех пользователей этой машины. А что если кому-то мы забыли рассказать о том, что конструкция поменялась?
Так же и код. Каждый класс должен выполнять какую-то свою задачу. Если ты не делаешь инкапсуляцию, то код относящийся к задаче, не заперт внутри класса, а размазан по классу и другим частям приложения. Это усложняет его понимание и изменение.
Обычно интерфейсы исплоьзуются библиотеках. Благодаря им автор задает ограничения, которые должны соблюдать пользователи, желающие использовать свой класс вместе с библиотекой.
Ну и конечно использовать их можно и при одиночной работе - задавать определенные требования к классам которые куда-то передаются.
-----------
Интерфейс это набор требований к классу. «требование» здесь значит требование чтобы в классе был определенный метод.
Если класс реализует интерфейс, в нем обязаны быть эти методы.Обычно интерфйес представляет собой какое-то умение: классы, реализующие этот интерфейс, умеют что-то делать.
Допустим мы делаем сайт где можно ставить лайки постам и комментам. Допустим у нас есть классы User, Post и Comment.
Вот у нас есть пост и коммент, мы можем увеличить число лайков, допустим методом increaseLikeCount и узнавать сколько у них лайков методом getLikeCount, то есть у них есть что-то общее, но как описать это в коде? Как сказать что эти 2 класса в отличие от других умеют работать с лайками?
Второй пример, мы хотим сделать функцию, которая допустим ставит лайк от определенного пользователя определенному посту или комментарию:
function addLike(User $user, $object) ...
Мы сказали что $user должен быть объектом класса User, а как сказать что $object должен быть классом, умеющим работать с лайками?
Обе проблемы решают интерфейсы. Объявим интерфейс Likeable, который представляет собой умение получать лайки. Опишем какие методы обязаны реализовать такие классы:
interface Likeable { public function increaseLikeCount( ); public function getLikeCount( ); }
Теперь укажем в коде что посты и комменты можно лайкать:
class Post implements Likeable { ... } class Comment implements Likeable { ... }
на этом этапе php проверит, не забыли ли мы реализовать в классах упомянутые методы. Если забыли — выдаст ошибку. Как удобно!
Ну и теперь мы можем использовать интерфейс чтобы указать какие аргументы принимает функция addLike:
function addLike(User $user, Likeable $object) { ... }
заметь что благодаря интферйесам наш код стал расширяем. Допустим завтра мы добавим класс Photo который тоже можно лайкать. Если он будет реализовывать интерфейс Likeable то функция вроде addLike сможет работать и с ним без переписывания кода.
В общем интерфейс представляет какую-то способность класса и требует от него реализовать определенные методы.
Плюс благодаря инкапсуляции ты можешь гарантировать корректность работы классы. Ну допустим у тебя нет инкапсуляции и есть публичное свойство обозначающее возраст пользователя . Где гарантия что в него не запишут строку или ноль?
При использовании инкапсуляции поле недоступно и менять возраст можно только через метод который может проверить данные и гарантировать что неправильное значение не будет принято и сохранено.
> то куда его положить этот класс? В хелперы? Обычно для вспомогательных скриптов делают папку bin, util, scripts. Но если ты хочешь подключать его из композера через статический метод то он должен быть автозагружаемый.
> mkdir($path, 0700, true); Обычно веб-сервер имеет права "другой" а в твоем случае файл доступен только владельцу.
Сегодня у тебя в классе нет свойств, а завтра появятся. Да и я не вижу проблемы, одна строка на все приложение по моему ничего не решает. Ведь все остальные классы у тебя в DI контейнере. Более того, твой Engine в тот же DI контейнер не засунуть будет.
А что у тебя будет в этом классе?
> Но неужели нельзя просто использовать абстрактный класс для целей просто инициализации чего-то. Это нелогично так как будет сбивать люде с толку. Абстрактный класс не предназначен для исплоьзования.
> Например нужен нам класс управляющий, который будет наводить движуху в нашем приложении. Вот это уже странно. Ты там случайно не собрался полприложения в этом класс не написать? зачем это тебе такой класс?
Господа, нужна консультация с задачкой про айфон. Что-то я туплю. Мой школьник, собака, не доплачивает банку два платежа. Дурачок никак не поймет, что банк заберет его айфон вместе с новым модным ланч-боксом со спайдерменом и последними трусами.
>Напишите программу конвертирующую набор чисел и других символов в телефонный номер, состоящий из блоков размером в 3 числа. Последние 1-2 блока могут быть размером 2 числа. > >Пример: "9 - 33 2176--856" >>> "933-217-68-56"
>>806594 Здравствуй, это ты всем тут подробно отвечаешь на вопросы? Я в тред только вкатился, как и в похапе, но у меня есть пара серьезных хоть и дебиловатых вопросов которые я бы хотел очень обсудить лично, возможно ли с тобой связаться по фейкомыльцу?
И можно еще подсказку как сделать <figcaption> внизу картинки? Очевидно, сначала нужно использовать position: absolute, но как сделать чтобы элемент был внизу? Неужели задавать координаты с помощью top, left, ...?
У меня не получилось сделать точь в точь как у тебя. Как на глаз определить тень и шрифт? Еще у меня наверно рамка не такая как у тебя...
>я смог решить задание, используя 3 тега на кнопку (label, input, i) А почему ты выбрал именно наклонный текст? Лучше же span взять - он не меняет стиля текста.
>это задание рассчитано на современные браузеры. Но если ты сделаешь, чтобы код работал и в старых (за счет яваскрипта), это будет плюсом. Или если в старых браузерах будет выводиться просто набор чекбоксов, это тоже лучше, чем ничего Я пока не знаю javascript, можно я доделаю это позже? Можно пока подсказку как сделать чтобы в старых браузерах просто выводился набор чекбоксов?
>твои CSS стили должны применяться только к элементам внутри переключателя. Недопустимо писать стили вроде label {... } меняющие вид всех label на странице. Я забыл про этот пункт пока делал задание, можем мы это опустить? В "боевых" задачах я естественно так не буду делать.
>чтобы определить состояние «кнопка вжата», можно использовать селектор label:active (на самом деле input:active) Я сначала подумал, что ты ошибся насчет :active, что надо было :checked за место этого. Нужно еще и :active делать? Какой у неё должен стиль? Как у :checked?
>дополнительный пункт: если ты посмотришь на обычные, не стилизованные радиокнопки и чекбоксы, то увидишь что по ним можно перемещать фокус с клавиатуры кнопками Tab, Shift + Tab, стрелками и переключать пробелом. Попробуй сделать поддержку клавиатурной навигации и в стилизованных кнопках. Подсказка: для этого надо отказаться от display: none на input, так как перемещать фокус по скрытым элементам нельзя. А можно еще подсказку как и это сделать?
>старайся не использовать id в верстке так как с ними не получится вывести на странице несколько блоков вкладок. Разрешается использовать классы или data-атрибуты для связи вкладок и заголовков. Это касается даже при использовании for у лейблов? Как тогда реализовать переключение вкладок, если вкладывать элементы уже во внутрь лейбла? Не получиться обращаться к соседним или родственным элементам, потому что сначала нужно проверить на :checked у input.
>сверстай блок так, чтобы блок с вкладками можно было вложить в страницу блока вкладок Нужно чтобы можно было скопировать вкладки в контентную страницу? Может лучше чтобы в контентной странице был свой элемент со вкладками? Так для это следует задать ему собственные атрибуты и стили. Зачем делать по два раза одно и тоже? Я что-то недопонял?
Как валидировать телефонные номера? В основном нужно Российские, желательно но необязательно международные. Не хочется изобретать свою регулярку которая все все равно будет неправильно срабатывать для каких-то регионов. Ессть же FILTER_VALIDATE_EMAIL, неужели для телефонов ничего похожего?
>>806393 Надо было страничку промотать вверх, написал: >window.scrollTo(0, 0); Но так как на сайте куча мобильных юзеров, решил не рисковать юзнуть жиквери с его перделками: >$("body").animate({ scrollTop: 0 }, "slow");
В итоге на виндоус фонах страничка не проматывалась и клиент очень обидно отхуесосил за это. Больше жикверям не доверяю в плане кроссбраузерности.
>>807343 Я начал с Symfony2. Мне нравится. До симфони совсем чуть-чуть ковырял Silex, но это не щитаеца.
Думаю, что можно начинать с симфони. Только не пытайся проглотить всё разом - у нее много возможностей. А освоить работу с основным функционалом, содержащимся в каждом фреймворке, особого труда составить не должно. Советую прочесть доку. Если засомневаешься, можешь поиграть с микрофреймворком вроде Slim, Silex.
>>793705 (OP) Кокой из тредов теперь легитимный? Посоны, мне нужна жс галерейка типа такой: http://www.family.su/woman.html + в идеале, подписи запилить к каждой увеличиваемой пикче. + очень опционально - форма заказа. Сам вряд ли справлюсь. Подскажете какую-нибудь готовую и максимум лаконичную и понятную реализацию, просто готовый скрипт "встрой в страницу и забудь" или русскоязычный гайд по самостоятельному запилу подобного на жс? Попова не предлагать, там не то и еще большие азы.
>> `cookie_token` varchar(100) NOT NULL, >Я бы тут добавил уникальный ключ для защиты от глупых ошибок, например когда туда вставляется пустая строка или что-то такое. Гугл говорит, что в MySQL для запрета вставки пустой строки нужно писать триггер. CHECK молча игнорирует проверку. Не думал, что уникальный ключ можно использовать для этого. Правда, таки один студент с пустым токеном в таблице для этого нужен, но его можно и самому создать.
> Эта штука мне напоминает тест. Это не тест? Тебе определенно стоит почитать урок про тесты Я читал ещё твои посты по тестированию, адресованные другим анонам, мне очень нравится идея автотестов. Попробую начать с простого - написать тесты к калькулятору. Если разберусь, потом посмотрю в сторону функциональных и опробую их на студентах.
> В реализации роутов у тебя есть подвох. Параметры роута определяются по порядковым номерам, а не по названиям. То есть можно легко написать в роуте плейсхолдеры /:a/:b/:c, а в контроллере function doSomething($c, $b, $a) и не заметить ошибки. Сделал проверку на соответствие плейсхолдеров с именами аргументов экшна. То есть теперь имена аргументов экшна должны идеально совпадать с плейсхолдерами. Это не так плохо, как если бы ошибки просто умалчивались, но и никакого автоматического связывания аргументов нет. Вот коммит, отвечающий за изменения в роутинге: https://github.com/applejacky/students/commit/f996fe2fcf3bb978047e4135e427a7bd4abc9a73
>> protected static $table; > Лучше делать это через абстрактный метод. А то где гарантия что переопределят имя таблицы? >> public static $table = 'students'; > Непонятно почему тут public. В общем, все эти проблемы были из-за AbstractMapper, который использовал позднее статическое связывание. Идея такая: у всех мапперов методы findById, findAll, и т.д. одинаковые, меняется только название таблицы в SQL-запросе. Позднее статическое связывание позволяет наследнику вызывать метод родителя, подставляя туда свои статические значения. Но, поле должно быть публичным. Делать абстрактную функцию (чтобы гарантировать возвращение $table), а потом использовать $table в контексте статического связывания кажется бредовейшей идеей, поэтому я просто удалил AbstractMapper.
>>807645 кто-то создавал тред что не нашел пхп, этот я еле отрыл где-то очень далеко внизу, увидел что уже 600+ постов, запилил перекат, но если нет так нет
>>807931 Нашел такое объяснение: TIMESTAMP Дата и время в формате timestamp. Однако при получении значения поля оно отображается не в формате timestamp, а в виде ГГГГММДДЧЧММСС, что сильно умаляет преимущества его использования в PHP
>>806657 Внимательно прочитай подсказки к задаче. Сам этого не сделал и долго мучался (в конце поста скинул) Возьми свою 1000 рублей и вставь в функции. кредитный баланс получается минусовое значение. Общий платеж тоже минус, потому что ежемесячный платеж больше. Это минусовое значение подставляется в ежемесячный платеж и выплат тоже минус. Банк должен ). Подумай, как сделать так , чтобы избавится от минуса и чтобы он рассчитывал реальное значение долга.
"Исправь и переделай программу, чтобы она работала нормально. Например, эта версия позволяет школьнику переплатить за кредит и уйти в минус, так, что банк ему становится должен — это плохо! Подсказка: перед тем, как платить, надо проверять, сколько осталось долга, и если он меньше 5000, то платить только остаток и завершать цикл через break"
>>806589 >В некоторых случаях лучше использовать абстрактне методы вместо полей. Их нельзя забыть переопределить. Поля можно использовать когда в них по умолчанию разумные значения и переопределять их не обязательно.
Эм, простите я не понял. То есть именно абстрактные методы в абстрактном родителе, вместо пустых полей?
Вместо private $coffe; public function getCoffe() { return $this->coffe; } в родителе и private $coffe = 20; в наследнике
нужно писать что-то типа: abstract private function getBasicCoffe();
public function getCoffe() { $result = $this->getBasicCoffe() * .... return $result; }
в предке, и соответственно
private function getBasicCoffe() { return 20; }
в наследниках?
Я понимаю вроде как идею, тип у нас такая вот напоминалка получается. Но для такого нуба как я это только лишнее запутывание :(
>>807732 Как думаете. Можно ли это использовать в ответе на один из самых УЕБАНСКИХ вопросов на собеседовании, а именно: ПОЧЕМУ PHP? Просто ебальник бы бил за него нахуй. А так отвечаешь что мол у нас всё збс, топовый язык же.
>>808094 Норм вопрос, если ты писал на нескольких языках и можешь провести параллели и обосновать почему PHP для тебя подходит лучше. Здесь в ход идёт твой кругозор программиста.
Во вторых у меня в резюме нет ни строчки о других языках, то есть вообще. Я как бы начинал вкатываться в програмирование именно с php, на его основе учил все примитивы и всё в таком духе.
И тут те такой вопрос: А ПОЧЕМУ ПХП? А ОПИШИТЕ ПЛЮСЫ И МИНУСЫ?
>>808101 > Я на джуниора претендую Странная отговорка.
> И тут те такой вопрос: А ПОЧЕМУ ПХП? А ОПИШИТЕ ПЛЮСЫ И МИНУСЫ? Ну вот а действительно, почему ты из языков именно PHP выбрал? А что если другие лучше, а ты жрёшь говно, даже сам этого не осознавая? Увидел много вакансий - так и скажи, ничего зазорного, все кушать хотят. Повторяю, нормальный вопрос, тем более для джуна. Позволяет набрать дополнительные плюсики.
>>808106 Ладно кароче, на следующем собеседовании говорю, что начала учить пхп, потому что увидел тред на дваче, с простым и понятным учебником, дружелюбным обсуждением ну и кароче не надо было ебать мозги, прост сел и через час ты уже что-то умеешь, ну а дальше понеслось.
Если кароче меня не берут после такого откровения, то ты пидор.
spl_autoload_register() предоставляет более гибкую альтернативу для автоматической загрузки классов. По этой причине использовать __autoload() не рекомендуется, а сама функция в будущем может перестать поддерживаться или быть удалена.
>>808117 В Java тоже нет абстрактных свойств. Меня, надеюсь, поправят, если ошибаюсь: "Абстрактный" обозначает, что у нас есть декларация, но нет определения (definition), поэтому интерпретатор выбрасывает ошибку, если метод не переопределить (точнее, не выставить ему тело в наследниках). В PHP нет понятия декларации функции и её определения (В C/C++ есть). Декларация функции - имя функции, количество и тип принимаемых параметров. Тело функции (определение), думаю, знаешь, что такое. Когда ты делаешь метод абстрактным, ты используешь только декларацию функции, без тела. Так вот переменную мы не можем задекларировать, она уже существует, когда мы только написали $foo.
>>808168 Опыт? Я бы не называл Битрикс опытом. Это так же как с вордпрессом блядь. Ковыряние в битриксе и прочей подобной хуйне делает тебя чисто знакомым с Битриксом. То есть если ты учил php, потом шел на битрикс, то ты можешь стать неплохим Битрикс-специалистом, но если захочешь слинять, то придется возвращаться туда, откуда ты начал своё знакомство с битриксом, а то и раньше, что бы освежать свои знания. Инфа 99.734656%
>>808175 Анон, ты не понял. Если тебе сформулировали задание, а ты ничего не понял, но не подал виду, а молча кивнул, не задавая никаких вопросов, то это плохо. Ты либо учишься спрашивать у начальства что непонятно, либо тебя выпнут, так как ты сидишь без толку, ничего не понимая, боясь лишний раз уточнить что-то.
>>808179 А вот за этот совет спасибо втройне. Часто ловлю себя на мысли, что боюсь переспросить. Хотя последнее время научился перебарывать себя: меня за вопрос не побьют, денег с меня за вопрос не возьмут, мать не откажется. Спасибо за то, что подбодрил.
Такой вопрос, пишу миграцию с одной структуры базы на другую, делаю вывод через ob_implicit_flush(true) и ob_flush() + echo. Можно ли как то очищать экран в процессе ?
Прочитал уроки из оп-поста. Все, конечно, охуенно, но очень не хватает урока, как это все собрать в одну кучу и сделать что-то полноценное. Хотя бы на примере той же задачки про студентов. Может кто знает где такое найти в сети? Гугл не помог.
>>806587 > $isAuthorized=$this->c['isAuthorized']; > Ну например , что если мы хотим обработать несколько запросов
А это как? Как пользователь может передать несколько запросов? Типа изменить данные, а потом выйти из системы одним нажатием url'а? Тут я не очень догоняю.
Просто я понимаю, что это происходит так: в начале выполнения моего мега-кода происходит проверка на авторизацию и в течение выполнения программы статус авторизации не меняется вплоть до отсылания представления пользователю. Если он сделает logOut, то при следующем запуске программы статус будет отрицательным так же от начала до конца выполнения программы.
В стандартной схеме работы пхп интерпретатор на каждый запрос запускает отдельную копию скрипта и скрипт обрабатывает только один запрос.
Однако есть и другие подходы. Например, мы самостоятельно можем открыть порт, принимать HTTP запросы, вызвать нужны контроллер и отдавать ответ (HTML страницу) обратно. В такой схеме наш код будет запускаться од н раз и обрабатывать запросы в цикле. И тут недостатки твоего подхода станут хорошо заметны.
ОП, а ты не против, если свои решения начнут тут выкладывать не совсем начинающие аноны? Скажем, те, у кого есть где-то полгода опыта реальной работы. Хочу сделать TestHub на Symfony2.
Кому интересно, как преподаётся программирование в ведущих мировых вузах - на русский язык перевели лекции гарвардского курса CS50. Курс рассчитан на абсолютных новичков. Но довольно интенсивен. http://javarush.ru/cs50.html
- можно передавать их в функцию и иметь гарантию что она не поменяет объект - если ты отслеживаешь изменения (например в ORM), то если объект остался тот же, то можно не проверять его на изменения
У них есть еще другие особенности, которые важны например в многопоточной среде, но для php это неактуально. В пхп они вообще особо не используются.
Некоторые используют это для оптимизации, чтобы приложение не надо было инициализировать на каждый запрос. В любом случае, суть контейнера в том, что бы хранить сервисы, а не что-то что относится к текущему запросу.
> В коде он несколько раз вызывается и каждый раз проверяет куки и в базу заходит Это исправляется тем, что можно кешировать текущий объект пользователя внутри сервиса авторизации и возвращать его при повторном обращении. Не забывай сбрасывать кеш при разлогинировании/залогинивании.
> public function makeReport() { //хз куда если не сюда сложить подобный метод Ну посмотри внимтельно, он же даже по стилю не соответствет другим методам. Это надо вынести куда-то наружу, в отдельную функцию например.
> if (is_subclass_of($worker, 'Worker')) { Используй лучше instanceof . Также, вопрос, а что если передано что-то неправильное? Молча проигнорируем? Это не выход. Лучше выбросить исключение.
> public function getTotalDepStuff ($something) { //Salary, Coffe, Papers В процессе написания оказались 3 одинаковых функции, объединил их Это плохая идея так делать. Вот смотри, у тебя имя функции формируется по кускам и явно целиком нигде не вписано: $something = 'getWorker' . mb_convert_case($something, MB_CASE_TITLE);
Что если я хочу например проверить поиском, где используется функция getWorkerSalary? Поиск не найдет эту строчку. Потому надо стараться не формировать имена функций динамически, а если без этого никак, то делать это хотя бы в том же классе что и сами методы.
Более того, нет даже никаких проверок, правильно
В твоем случае можно либо передавать имя функции целиком, либо (что лучше) передавать анонимную функцию как аргумент. Этой функции передается очередной департамент, и она возвращает интересующую характеристику. И конечно от пользователя все это стоит скрыть, сделав 3 метода с названиями вроде getTotalSalary(). А не заставлять пользователя угадывать как ему получить то или иное значение и разбирать кривой код.
> как почитаю про исключения, то заменю > return "N/A"; почитай и замени
> //private $salary; //и без них всё работает, но если их разкоментить, то будут в наследниках мусорные пустые поля от родителя Это неправильно. Не должно быть в классе обращений к полям которых в этом классе нет. Есть такой принцип "класс не должен знать ничего о своих наследниках". Вот я сейчас напишу наследника к классу Worker и где гарантия что я сделаю это поле? Это неправильно.
Вообще использовать тут поля плохая идея. Как ты гарантируешь что тот кто наследует класс, их переопределит? Тут должны быть абстрактные методы. Они специально для этого предназначены. А у тебя все на честном слове держится.
Скорее всего нет. Есть какие-то ANSI коды для управления терминалом, но они могут быть разные в разных системах. Есть консольная команда. Но зачем очищать экран? Суть терминала вообще-то в том что на нем остается лог введенных команд и ответов на них. Какая выгода от того что твоя команда его очистит? Это вообще не задача скрипта миграции очищать терминал.
> делаю вывод через ob_implicit_flush(true) и ob_flush() Ты делаешь что-то странное. Ты в браузере что ли скрипт запускаешь? Бросай эту дурь, скрипты миграции надо запускать в командной строке а не через костыли. Что если на середине процесса соединения разорвется или вкладка в браузере упадет? Специально для таких вещей придумана консоль а ты какие-то костыли лепишь.
Это не мусорные поля. Приватное поле принадлежит только одному классу и потому в объекте может быть несколько одноименных приватных полей от разных классов.
Это можно сказать как "много доступной и понятной документации на русском языке, хороший мануал". Правда на это можно получить ответный вопрос, а почему ты не хочешь учить английский и читать оригинальную документацию?
Давай я еще раз напишу. Если у тебя есть значения полей по умолчанию и их не обязательно переопределять в наследнике, то можно использовать поля. Если же каждый наследник имеет свои значения зарплаты, кофе (или свою уникальную логику их расчета), то надо использовать абстрактные методы.
Абстрактные методы очень даже хороши:
- видно, какие методы надо переопредедить при наследовании - php напомнит если забыть их переопределить
Вообще, это неправда. TIMESTAMP отображается также как и DATETIME, в виде '2016-01-01 12:00:00'. И соответственно передавать его в базу надо в таком же виде. Отличие TIMESTAMP от DATETIME в том, что TS - это конкретный момент времени (с учетом часового пояса), а DATETIME - это просто день и время, без указания часового пояса.
> Гугл говорит, что в MySQL для запрета вставки пустой строки нужно писать триггер. CHECK молча игнорирует проверку. Не думал, что уникальный ключ можно использовать для этого. Правда, таки один студент с пустым токеном в таблице для этого нужен, но его можно и самому создать.
Ну уникальный индекс хорошо бы добавить так как значения здесь должны быть уникальные. CHECK да, в mysql не работает, если будешь Postgres изучать, он там работает.
> Я читал ещё твои посты по тестированию, адресованные другим анонам, мне очень нравится идея автотестов. Попробую начать с простого - написать тесты к калькулятору. Если разберусь, потом посмотрю в сторону функциональных и опробую их на студентах.
Не лучше ли вынести часть этого кода в какие-то функции, методы? Хотя бы в каком-нибудь хелпере.
> AbstractMapper, который использовал позднее статическое связывание. Это в общем плохая идея, лучше использовать обычный абстрактный метод. То есть в базовом классе мы пишем:
abstract protected function getTableName(); ...
$table = $this->getTableName();
абстрактные методы для таких случаев и предназнаечны. Это намного лучше чем надеяться на то, что не забудут переопределить публичное статическое поле.
Вообще, я считаю что вот это вот "позднее статическое связывание" - это плохая штука и плохо ложится на концепции ООП. В ООП статический метод/поле - это такое поле, которое принадлежит классу. Так как оно принадлежит классу, ты всегда можешь написать Class::$field. А вот это вот "позднее статическое связывание" - это какая-то пародия на наследование, только хуже, без абстрактных методов например. Мне оно не нравится. Тут одназначно можно было бы использовать обычное наследование.
> Думаешь, стоит реализовать смену email? Думаю, стоит. И пароля тоже. А то ты упрощаешь себе задачу такими ограничениями, подгоняя требования под твою архитектуру. В задаче есть возможность редактировать email.
Считает верно, но вот если посомтреть на алгоритм, то там какие-то "костыли". Вот после цикла стоит строчка " $total += $credit;". Зачем ты после выплаты кредита прибавляешь остаток баланса назад к общей сумме? Как-то нелогично ведь? Нельзя ли не уходить в минус?
А как они будут использоваться? Можно сделать какие-то минимальные проверки, вроде "не меньше N цифр", но в общм номера могут быть самые разные и если их будт читать человек то лучше не ограничивать формат.
Как в бутстрапе сделать отступ снизу? Есть для col- класс в котором будет указана высота (напр, 2 строки, 3 строки). Или может как-то создать невидимый col- под ссылками?
Аноны, делаю файлообменник, написал немного логики для сайта и все заебись, но вот дошел до верстки и это просто пиздец. Это ж такие дебри ебанутые, просто пиздец как лень учить. Вообще в голову не лезет. Шо делать?
>>808729 1. не используй регулярки без крайней необходимости. 2. Заменяй +7 на 8 через str_replace 3. Не используй ключ в конструкции foreach если не собираешься использовать в цикле.
>>808644 >Симфони хороший фреймворк, только готовься читать докмуентацию и ковыряться в исходниках, а не скачи по верхам. Да, на работе его и используют. Собственно, я и хочу что-то своё написать с целью изучить уже известные вещи более глубоко.
>>808659 Ну а можно пример замены свойства в абстрактном классе на абстрактный метод?
Я просто не понимаю в итоге, что делать то нужно, вот как тут >>808051 делаем? И вместо public $coffe = 20;
везде пишем public returnCoffe () { return 20; } ?
Это же не просто так тип взял по фанчику заменил в родителе свойства методами, это потом в наследниках с этим работать, и в других классах возможно тоже.
Практикуюсь тут с бд, и вот какая хуйня http://ideone.com/BvcuDO Я уже не знаю, перебробовал несколько вариантов синтаксиса, но ничего не работает. Может у меня как-то mysql не так настроен?
>>809726 Ох, там я еще просто mysqli_prepare и mysqli_stmt_bind_param($stmt, "ssii", $title, $author, $pubyear, $price) делал раньше. Не суть, все равно не работет.
>>809745 Забыл ошибку показать: Warning: mysqli_prepare() expects parameter 1 to be mysqli, null given in C:\OpenServer\domains\eshop.com\inc\lib.inc.php on line 5
>>809747 > mysqli_prepare() expects parameter 1 to be mysqli, null given Т.е. он почему-то считает, что я ему передаю не линк на бд, а какое-то левый параметр я так понял. Но что я делают не так понять не могу.
>>809756 Я понял в чем у меня ошибка была. Я пытался из функции общараться к внешней переменной, т.е. $link у меня там не было, зато смог через $GLOBAL["link]. Это нормальный подход, или лучше так не делать?
Ребзики, помогите с задачкой из учебника ОПа. Уженесколько часов ищу ошибку, никак не могу найти, вроде бы написал все правильно, а запускаться не хочет (регулярное выражение сначала проверил на regex - все проходит) http://ideone.com/zqAqXA
Ну очень спорно же, с конкатенацией мне проще на новую строку код переносит и я сразу вижу, что есть текст, а что переменная. К тому же, элемент массива или свойство объекта удобнее вставлять.
Ребзяки, посмотрите как я решил задачу с регулярными выражениями, работает, но почему то мне не нравится написанный код. Опытные программисты меня забьют камнями? http://ideone.com/e6GYFK
>>810845 Окай. Какую ты преследуешь цель? Для души? Учи что хочешь. Для работы? Найди вакансии в своём городе на должность руби, питона. Сделай выводы.
>>810846 Хочу зарабатывать бапки на фрилансе, а потом, поднабравшись опыта, может быть вкатиться в офис. Просто как только я наткнусь на php в каких-либо форумах, то сразу же начинают пиздеть, что язык говно и говорят про Python и Ruby. Я не хочу тратить время... Вдруг правда, через несколько годиков php станет никому не нужен и придется вкатываться в другие языки. Уже скачал дохуище курсов по php, но меня одолевает гора сомнений, поэтому никак не могу приняться за изучение. Знаю C++ на среднем уровне, но на нем ничего стоящего не писал, только решал олимпиадные задачки и баловался со всякими графическими библиотеками, ну и Qt. Сначала я занялся программированием для души, мне просто это понравилось и прочитав пару гуидов про создание игр, начал учить C++. Потом, покончив с играми, мне наконец захотелось зарабатывать деньги на своем любимом деле, но как только я начал гуглить, понял, что я полный ноль и мне нужно поднабраться знаниями. Позже нашел инфу, что чтобы зарабатывать бапки на программировании, лучше вкатиться в веб. Короче блять, я не знаю зачем это написал, но пусть будет.
>>810856 >сразу же начинают пиздеть, что язык говно и говорят про Python и Ruby. Не надо так. Присмотрись внимательнее и увидишь что каждый язык так или иначе смешивают с грязью. >Позже нашел инфу, что чтобы зарабатывать бапки на программировании, лучше вкатиться в веб. Короче блять, я не знаю зачем это написал, но пусть будет. Ну PHP никому не нужен чистым. Все хотят PHP + HTML5+CSS+Javascripts+%Framevorkname% готов ли ты потратить года 2 на изучение этого всего?
>>810856 Ну зайди на фриланс биржи и посмотри для какого из языков больше заказов, что ты как маленький. Кратко: вакансии есть на всех трёх языках, учи какой хочешь. На PHP вакансий больше, потому как много обезьяньей работы вроде пикрилейтед.
> Просто как только я наткнусь на php в каких-либо форумах, то сразу же начинают пиздеть, что язык говно и говорят про Python и Ruby.
Говнокодить можно на любом языке, руби же своими магией и фривольностью тебя к этому будет ещё и подталкивать.
Твой код ищет любые латинские буквы в любых словах. А в здадче надо искать слова содержащие буквы разных алфавитов. Если слово полностью английское то ошибки быть не должно.
>>810859 >каждый язык так или иначе смешивают с грязью. Ну мне все таки кажется что php обсирают больше. Хотя это мода наверное такая просто. >Ну PHP никому не нужен чистым. Да, конечно я в курсе, что одного php не хватит. Я просто пытаюсь выбрать бэкенд язык.
Никак. Лучше всего возвращать результат через ретурн, в крайнем случае можно передать объект и менять его свойства, но скорее всего ты что-то делаешь неправильно.
> Она же в вендоре/автолоад.пхп, я ж не могу ее редактировать. А этот файл на основе чего генерируется? На основе правил в composer.json, в ключе autoload. Допиши туда нужное правило.
>>810919 Есть несколько способов: 1) На сайте JetBrains выбираешь студенческую лицензию, высылаешь им туда фотку студбилета, дают на год лицензию на все их программы. Я так сделал. 2) Пользуешься триал версией в 30 дней, потом удаляешь PHPStorm (конфиги не удаляешь), ставишь опять эту IDE, она говорит тебе мол у вас есть конфиги, применить ли их, тыкаешь да. И так каждый месяц, но ничего заново настраивать не нужно. На винде геморно при каждой установке 10 раз нажимать next, а вот на линуксе это всё легко автоматизируется, так как софт ставится через пакетный менеджер. 3) Брать бесплатную IDE, например NetBeans. Сомневаюсь, что ты почувствуешь разницу между PHPStorm.
>>810864 По-моему, нужно лесом обходить компании, которые требуют от меня сертификаты, а не знания или гитхаб.
Когда лучше начинать учить фреймворки? Я вот скоро начну студентов делать, может с фреймворки будет уже легче? Алсо, с какого начинать? Вроде вай2 самый популярный, но вот у меня в городе чато в вакансиях laravel указывают.
>>811767 > Cisco Certified Network Associate (CCNA) > Сisco Значение знаешь? И чего ты вакансию не указал, там поди инженер Cisco какой-нибудь, логично, что от него будут требовать сертификаты Cisco, а не гитхаб, он же не кодер, к нему другие требования. И 180k это помидор с многолетним опытом, который знает сам что ему нужно. Переформулирую: я бы лесом обходил компании, требующие для должности PHP-джуна какие-то сертификаты, а не знания и гитхаб.
>> Она не умеет считать русские буквы, имей в виду. > Я так понял, это справедливо для всех str_* функций без префикса mb? А как тогда выравнивать? Сделал sprintf'ом. Да, почти для всех, кроме нескольких, для которых работа с байтами или буквами ничего не меняет (str_replace, strtr - их можно использовать). sprintf кстати тоже не умеет считать правильно. Приходится для таких случаев писать что-то свое на основе mb_ функций.
> https://github.com/applejacky/arithmetic_expression_calculator/blob/master/test.php#L24 > '2^(1/2)' => SimpleFraction::SIGN_INACCURATE . pow(2, 1 / 2), Вот здесь конечно тест получился плохой, так как содержит в себе по сути копию кода, который тестирует. Более того, он жестко определяет число знаков после запятой - если твой код вернет чуть более точный результат, тест провалится.
В такой ситуации лучше бы как-то задать рамки или погрешность - например "1.41 +- 0.02". Разумеется, можно использовать не 2, а например 6 знаков после запятой. Но главное что мы не пытаемся сравнивать посимвольно неточные числа.
Насчет поточности - нет, парсер не поточный, так как он разом делит строку на массив токенов и возвращает на выходе массив. Для выражений это вполне нормально, но парсеры текстов программ обычно пишутся немного по-другому. Обычно они пишутся как некий итератор, который при каждом вызове возвращает следующий токен. При этом входной файл они тоже могут читать побайтово или построчно:
$lexer = new Lexer($inputStream); while ($token = $lexer->next()) { ... }
Или, если объект поддерживает интерфейс Iterator, можно писать так:
$lexer = new Lexer($inputStream); foreach ($lexer as $token) { .... }
Для математических выражений это не требуется, но в PHP есть интересная штука, которая упрощает поточную обработку данных - она назвается генераторы. С ней можно писать так:
$lexer = new Lexer($inputStream); foreach ($lexer->tokenize() as $token) { ... }
Это напоминает итератор, но реализация на основе генераторов получается более простой и красивой. Наверно для математических выражений это не нужно, но если бы тебе надо было обрабатвать какие-то большие наборы сущностей (например гигантские XML файлы), такой подход мог бы помочь. Советую почитать про итераторы и генераторы.
> https://github.com/applejacky/arithmetic_expression_calculator/blob/master/src/InfixParsing/Parser.php#L50 > if ($operandsCount !== $binaryOperatorsCount + 1) { > throw new InvalidInfixException('Количество бинарных операторов должно быть на один меньше, чем количество чисел'); > if ($parenthesisDeep !== 0) { > throw new InvalidInfixException('Неправильно расставлены скобки'); Эти ошибки наверно должен отлавливать алгоритм сортировочной станции?
Вот здесь нет ли ошибки? Если присмотреться к коду то видно что если на стеке не скобка, то мы снимаем оператор со стека и добавляем в выходну очередь, а затем снимаем еще один оператор - а есть ли гарантия что это 100% скобка? Я бы как минимум if или assert туда поставил.
Что касается возведения в дробную степень, я бы разбил ее на 2 части: возведение в степень и извлечение корня. Ну наример возведение в 2/3 лучше делать как возведение в квадрат, затем взятие корня. Иначе мы округляем 2/3 и можем что-то потерять по дороге. Плюс, проверку на точность ты делаешь только для степени 1/3 в этом случае.
> public function __toString() Насчет этой функции - я не люблю ее использлвать так как из-за нее можно например использовать объект как-то неправильно и не получить при этом ошибки.
Ну и мне по прежнему кажется, что удобно было бы иметь возможность складывать и умножать дроби не создавая для этого объекты токенов.
>> Надо ставить фигурные скобки. Вместо копипастоы ифов лучше сделать массив с цифрами и словами и циклом искать совпадения в нем. > Я ничегошеньки не понял как это делать, кто-нибудь может подсказать? я имею в виду делаешь массив вида
>>812284 > stderr > PHP Parse error: syntax error, unexpected '<' in /home/dxAupK/prog.php on line 3 > PHP Parse error: syntax error, unexpected '<' in /home/dxAupK/prog.php on line 3 > PHP Parse error: syntax error, unexpected '<' in /home/dxAupK/prog.php on line 3 > PHP Parse error: syntax error, unexpected '<' in /home/dxAupK/prog.php on line 3
>>812294 http://ideone.com/riyP25 Вот весь мой код грубо говоря. Никаких ошибок с подключение он не показывает. Но Warning: mysqli_stmt_bind_param() expects parameter 1 to be mysqli_stmt, boolean given in C:\OpenServer\domains\testWork1\dbraste.php on line 17
>>812299 1) Читал этот пост. Никаких ошибок соединение не показывает, проблема в $stmt = mysqli_prepare($connection, $sql); который у меня всегда фолс. 2) Пока пдо я не осиливаю.
>>812306 Проверь, что сервер MySQL запущен. Понапихай везде var_dump'ов, чтобы проверить, до какой строки код выполняется, а начиная с какой уже нет. Обмажь код функциями mysqli_connect_error(), mysqli_error(), mysqli_stmt_error() где нужно.
Потому и советуют использовать PDO вместо MySQLi, так как первый может выбрасывать исключения, а второй молчит при ошибках, отдавая false и попробуй разберись с этим. Проще в PDO разобраться. Я читал phptherightway, погугли, там написано как с PDO работать.
>>812314 http://ideone.com/riyP25 А вот так все заработало. Да, походу я как-то неправильно создал таблицу, хотя как - вот убей не пойму что там можно не так сделать. И вообще ты прав, надо пдо учить, а то ебанешься каждый раз писать эти проверки.
Решаю файлообменник. Оп, ты вот здесь пишешь https://github.com/codedokode/pasta/blob/master/db/trees.md следующее: > materialized path > При этом способе path хранится в поле вроде TEXT или BINARY, по нему делается индекс. Выбрать всех потомков можно запросом SELECT WHERE path LIKE '001.001.%' ORDER BY path, который использует индекс.
Что за индекс такой? Это как-то связано со сфинксом? Т.е. анон в этот момент должен быть знаком со сфинксом?
Анончики, помогите Есть у меня гигансткий масив вида http://ideone.com/ArpBjk Естественно его надо выводить в удобочитаемый вид, нужны только названия городов. Как я понимаю, его надо выводить через foreeach. Но никак не могу правильно это дело написать. Объясните идиоту как это правильно делается.
Если ты арендуешь shared hosting то там Апач уже установлен и настроен Если ты арендуещь сервер то ставить и настраивать надо тебе самому, для этого надо изучать командную строку линукса, в ОП посте есть паста для начала.
Всю работу с таблицей студентов (выборку студентов) надо бы собрать в одном классе, и использовать твой класс работы с БД а не писать функцию.
> $validator=new StudentValidator($student,$container,$student->getId()); Тут мне не нравится то, что студент передается в конструтор, отдельно зачем-то его id. Контейнер передавать в валидатор неправильно, это же нарущение DI. Студента логичнее передавать не в конструктор, а в функицю валидации. задача конструктора - инициализировать объект. Лучше сделать многоразовый валидатор.
> > перечитай урок про DI. Это service locator и это плохая вещь. > Убрал где можно. Но как я понимаю в контроллеры всё равно контейнер придётся передавать целиком, так? да, есть те, кто считает что контроллер тоже надо делать как сервис, но это получается сложнее, и не очень понятно, а нужно ли оно. Проще в контроллер передавать контейнер. Контроллер это все равно не повторно используемый код и его вызвать откуда-то нельзя.
>> Сам класс авторизации странный, половины функций связанных с авторизацией, в нем нет, они в контроллере. > Добавил setHash(). Еще что-то нужно? У меня нет идей
> Я подразумеваю, что всё что нельзя редактировать пользователю, то protected. А get_object_vars возвращает только public свойства. Разве не элегантно? нет, это плохо так как не очевидно. Легко добавить публичное поле и внезапно оно становится доступно для редактирвоания пользователем. Это неправильно, надо чтобы все было безопасно по умолчанию, а не превращать код в минное поле.
> потому что этот класс используется только так и никак иначе. Создать, проверить на ошибки, вернуть ошибки. Верно так делать? Это сокращает работу с классом до одной строки: $validErrors=new StudentValidator($student,$this->c['table'],$id); Нет, лучше чтобы валидация делалась в методе validate. Логично ведь что валидация это функция, которая принимает на вход модель и возвращает список ошибок. Это позволяет например проверить нескольких студентов одним валидатором. мне кажется так будет удобнее. Хотя конечно твой подход тоже имеет право на жизнь, но мне кажется что лучше для валидации иметь отдельный метод, а не нагружать этим конструктор.
> $allEngineers = array_filter($dep->workers, $askEngineer); правильнее было бы в департаменте закрыть достпу к полю workers и вместо этого предлагать метод поиска работников.
Также, не хватает сортировки работников чтобы увольнять в первую очередь работников определенного ранга.
> foreach ($this->workers as $num => $worker) { > if ($employee === $worker) { Можно использовать array_search с флагом точного сравнения
> public function fireEmployee($employee) тут стоит поставить тайп-хинт
>if (is_array($employee)) { > $this->workers = array_merge($this->workers, $employee); > } else { Это плохая идея, принимать значения разных типов. Это оставляет незамеченными ошибки в коде, не позволяет исопльзовать тайп хинты, усложняет код. Лучше сделать 2 отдельных метода.
> class Employee Надо пометить его абстрактным. Также, стоит использовать абстрактные методы для переопределения базовой ставки, а не надеяться, что поля не забудут переопределить.
Ну и не хватает одного из антикризисных методов. И применяется только один метод, а надо применить все 3 независимо.
Надо добавить папку с PHP в PATH. В ОП посте есть паста по командной строке и там вроде это объясняется. И конечно лушче бы установить PHP самому - в ОП посте тоже есть статья по теме.
Абстрактные классы позоляют тебе задать правила для тех кто наследуется от твоего класса. ты как бы делаешь заготовку, которую они дополняют.
Интерфейсы позволяют отнести класс к какой-то группе или опсиать опредленное умение. Ты можешь их использовать, чтобы твои функции могли работать не с одним классом, а с любым. поддерживающим интерфейс. Урок по теме: https://github.com/codedokode/pasta/blob/master/php/interfaces.md
>>813270 Я бы посоветовал начать не с чтения всей документации, а с туториала как писать хелоу ворлд на фреймворке и как на нем реализовать простейший mvc сервис, что бы понять куда какие строчки перегонять и как примерно всё устроено на нем. Вот же есть в офф документации всё, нагуглил за 5 сек http://www.slimframework.com/docs/tutorial/first-app.html А далее как начинаешь писать свой сервис, то просто гуглишь возможности фреймворка которые тебе нужны и могут быть в нем реализованы, например: slim db connection slim query builder slim post get
Хотя опять же по документации там пробежаться дело пары часов судя по всему, так как возможностями фреймворк не перегружен.
>>812005 > Сisco И чё? >Переформулирую: я бы лесом обходил компании, требующие для должности PHP-джуна какие-то сертификаты, а не знания и гитхаб. А где я спрашивал про ТРЕБОВАНИЯ? Вот есть Ерохин с сертификатом уровня CCNA только от PHP. Ему же это будет плюсом? Или например висит у меня на стене RHCSA, я могу из-за него затребовать на собеседовании болшую зарплату. Я повторюсь, знания, опыт и гитхаб у меня есть!
>>812005 Обьясню тебе и таким как ты. Существуют некодерские конторы, которым нужен просто макак на галеру, чтобы сайтик модерировать. Естественно сайтик не простой, а сайтик болльшой и преуспевающей компании, которая широко известна в своей области. Сидит в такой конторке тётенька мэнэджэр, которая в IT не понимает ничего, зато диплом мэнэджэра есть, и поэтому она там сидит. Вот в такие конторы берут по сертификату. Просто потому-что в один прекрасный момент кто-то начнёт догадываться что сайт немного накрылся нахрен, логины не работаю, новсти отьехали, а стартовая страница - это всё что осталосьот сайта. И вот тогда начинают разбираться кто нанял этого криворукого дауна? А манагер тут как тут со словами "А я хитро прикрою свою жопу фактом наличия у него сертификата!". На этом моменте тень подозрения спадает с манагера и её странной политики найма, и они снова ищут прогроммиста.
>>813530 Да, добавлю ещё, что платят там таки хорошо. И карьерный рост по фактуотсутствующий, но всё-же есть. Тоесть ты можешь стать из junior даже тим лидом. И зп тебе повысят хоть до 4килобаксов, вот только ты в команда программистов будешь один. Такие дела.
Стоит ли читать Зандстру, не зная про базы данных(В учебнике с оп поста в теме про ооп перед задачами рекомендуют прочитать 2 книги)? Когда в 4 главе начали что-то говорить за PDO и базы данных потерял связь.
>>814582 Ну при ошибке самое первое что я сделал это попытался добавить в другую таблицу и везде получил такой результат. Чего я ожидаю? Чтобы этой ошибки в пхпмайадмине не было (очевидный ответ #2). Извини, но вопросы у тебя напрашиваются на такие ответы.
>>814585 Могу еще добавить что ошибка 1 получилась при клике на пик1, а вторая на пик2 (выделил куда жал). Может я чего-то не понимаю, третий день как поставил пхпадмин.
>>814593 Массив информации о файле вырезанный getID3 либой. Так ошибка происходит до добавления чего либо, наверное ее надо решить до этого момента, верно?
>>814605 Спасибо, анончик. Алсо вопрос опу, какого вида комментарии делать на файлообменник? Как пикрелейтед? Или как вконтакте? В случае пикрелейтеда комментарий "матери" должен пропасть в случае удаления комментария брата?
> В случае пикрелейтеда комментарий "матери" должен пропасть Можно сделать что пропадает, можно заморочиться и вместо родительского писать "комментарий удален", а дочерний оставить. Так будет интереснее.
> Тут я думаю проще всего просто в модели и таблице файла предусмотреть поля для информации о картинке и видео. Поскольку видео бывает разных типов с разыми параметрами, то проще всего хранить эти параметры в базе как JSON массив. В коде конечно работать с массивом неизвестной структуры работать неудобно, потому хорошо бы завернуть это в класс, например, с названием FileInfo, с методами для получения списка свойств, значений свойств, конкретного свойства и тд.
>>814706 >проще всего хранить эти параметры в базе как JSON массив. Ты уверен что правильно его понял? Потому-что >В коде конечно работать с массивом неизвестной структуры работать неудобно, потому хорошо бы завернуть это в класс Это не неудобно, это работа через такие анусы, что тебе и не снилось.
>>814708 Ну вот я в эти анусы и попал. Поэтому вопрос. Вот получаю я через FETCH_CLASS из базы свой объект со свойствами, допустим name, size, id и тот самый fileInfo формата json. Как мне его обернуть теперь? Это статический класс должен быть принимающий в свойства целый массив и возвращающий конкретное значение (например длину видео). Или же это класс со свойством fileInfo которое представлено в json формате, а методы делают тоже самое, что и в статическом варианте. В последнем случае желательно чтобы я сразу в объект файла запихивал свойство-класс работы с этим json, т.е. это должно делаться через FETCH_FUNC?
>>814727 Перекати тредис пожалуйста. Я делал это с 60 по 69 треды. Теперь мне лень, а оп пропал. Только закати 4 оп поста и оп пикчи. Тебе в новом тредеответят сразу.
>>814810 У меня есть. Ты в курсе, что вся статика принадлежит классу, а не объекту? $this и self это не одно и то же. Первое указывает на текущий объект, self указывает на статическое поле класса. Такое поле будет общим для всех классов.
>>814867 >в /pr будет 4 живых PHP-треда. Никогда такого не было, и вот опять произошло. Раньше как всё было медленно - за два года тредов двадцать всего.
Не знаю, можно ли меня считать "шарящим", но я тут подумал, что надо будет написать урок по MVC. А то действительно, много непонимания.
Там главная суть в отделении модели, хранящей и управляющей данными, от их отображения и от обработчиков действий пользователя. Кроме организации кода, мы получаем возможность например использовать одну модель с разными вью или разными контроллерами.
> Но тогда всё равно же придётся искать метод который предоставляем наружу. Если мы поменяем внутреннюю логику метода так, что он будет возвращать свершено другой результат, например заместо строки массив, то метод который мы предоставляем наружу, тоже нужно будет поменять, и для этого нужно так же искать где он вызывается.
Это верно. Потому что тут ты меняешь тип метода, и соответственно придется менять места его использования. А вот если тип остается прежним, но например, меняется алгоритм хеширования (или исправляется ошибка в нем) - остальной код трогать не придется.
> Я перечитал твой мануал по инкапсуляции и могу сказать, что она нужно скорее чтобы скрывать внутреннюю логику, а не облегчение её редактирования. Да, это помогает например понять как использовать класс - тебе достаточно лишь посмотреть на публичные методы, а не изучать весь код класса.
> Так же, мне теперь кажется, что я зря в некоторых сущностях делал свойства закрытыми, ведь при работе с ними нет никакой внутренней логики, мы просто их меняем. И чтобы их не поменяли на неверное значение есть класс валидации.
Ну это пока. На практике логика может появиться в любой момент. Например, при задании одного поля надо менять значение другого поля. И здесь отсутствие инкапсуляции может помешать. В большом и сложном проекте переделать поля на методы будет непросто (если только не использовать магические методы), потому некоторые советуют с самого начала делать все через сеттеры и геттеры. Но так конечно код получается объемнее.
Что касается валидации, то это не совсем то, что нужно. Ведь неверное значение может ставиться в одном месте кода, а валидация - делаться в совсем другом (или вообще не делаться). Валидация - она обычно используется для проверки данных от пользователя.
> Я не могу вспомнить как я научился такому методу. У тебя случайно не было так написано в уроке по DI? Так вообще делают?
Ты вот про это? > public function setProperty($property, $value) { Это вообще не очень хорошая вещь. Во-первых, она не проверяет имя поля и позволяет создать поле с любым именем. Во-вторых, она по большому счету нарушает инкапсуляцию. Потому что, если ты добавишь в сеттер setName() какую-то проверку, то она не будет вызвана в setProperty().
Зачем этот метод? Не думаю, что он нужен.
> У них там всё равно всё сделано через роутер, а я даже не знаю откуда они берут эту задачу чтобы делать через него, Если погуглить по habr mvc php то там есть статья с роутером в ней. наверно оттуда.
> Еще у этого анона есть такие классы как от Request, Response - мне это тоже не понятно зачем они нужны. Чтобы можно было представить запрос и ответ в виде объектов. Ну например, мы теперь можем сделать функцию, и указать что она принимает аргумент типа Request. Также, мы можем писать например $request->getQuery('x') вместо конструкции isset($_GET)...
Объект ответа Response может использоваться, чтобы получить результат обработки запроса (страницу со всеми заголовками) и что-то с ней сделать.
Это может использоваться например для тестирования (можно создать произвольный объект запроса, можно проанализировать получившийся ответ), а также какими-то промежуточными слоями, которые например берут ответ или запрос и что-то в нем заменяют до/после обработки приложением. Если ты будешь изучать фреймворк Slim , то там есть так назваемые middleware которые могут выполняться до/после обработки запроса.
> Раньше я думал, что контроллер отвечает за логику того или иного действия, а модель это, исходя из названий содержащихся в ней классов, всего лишь вспомогательные методы для него. Не, не так. Модель отвечает за логику работы приложения, хранение и обработку данных. Вид отображает эти данные. Контроллер принимает запросы от пользователя, меняет данные (через Модель) и отображает результаты (с помощью Вида). Поэтому например мы можем сделать несколько Видов, которые работают с одной моделью и отображают одни и те же данные в разном виде. Или несколько Контроллеров, работающих с одной Моделью.
Ну например: пользователь заходит на страницу редактирования профиля. Контроллер определяет, залогинен ли он, запрашивает у модели информацию о нем и просит Вид отобразить форму с введенными данными.
Условно говоря, модель - это "ядро" приложения, без интерфейса, но со всей нужной внутренней логикой. То есть имея модель, ты всегда можешь в пару строчек получить или изменить какие-то данные в базе. Или проверить данные.
> Ведь как может отвечать за всю логику лишь Помощник? Ну иногда такие классы называют Сервис, иногда Хелпер.
> Валидатор тоже не может отвечать за всю логику. Валидатор это как раз часть модели. Он знает как проверять данные.
> Класс с работой с БД - тоже. Это тоже часть модели, отвечающая за загрузку данных из БД и сохранение в БД.
> Это сбивает с толку. Так почему в Модели, которая отвечает за логику, за внутреннее состояние программы, мы не содержим классы как AuthModel или просто Auth(orization)? Потому что авторизация реализована полностью в интерфейсе. У нас ведь авторизация делается установкой кук, которые хранятся в браузере пользователя. Модель о браузере и HTTP-запросах (а куки это часть HTTP) ничего не знает.
Вот если бы у тебя хранился например где-то в базе список залогиненных в данный момент пользователей - тогда Модель бы отвечала за него. Но установкой и проверкой кук она не должна заниматься. Это часть интерфейса между приложением и пользователем, а модель не отвечает за интерфейс пользователя. Ну например, когда мы запускаем консольную программу, никаких кук в консоли нет.
Хотя.... при желании тут конечно можно как-то извернуться и объявить Модель ответственной за залогинивание/разлогинивание ... но мне кажется, это будет искажение идеи MVC.
>>Но третья-то зачем? > Так токен же, для csrf протекции. > Я тоже сомневался стоит ли её создавать и при регистрации. Я бы не привязывал защиту CSRF к авторизации. По идее они никак не связаны, ведь формы могут быть доступны и для неавторизованных пользователей. И я не вижу никакой выгоды тут, зачем привязывать генерацию CSRF токена к регистрации, если можно это не делать?
> $spl[$place] вернет NULL. Ты наверно хотел написать $spl[$student] вместо этого? Да, ошибся.
>>Это значит, что в SplOS можно заносить объекты, не привязывая к ним данные. > О каких данных здесь может быть речь? Имеется в виду, что можно писать так:
$s = new SplObjectStorage(); $s[$object] =1; // добавляем элемент с ключом и значением
А можно и так, добавляя только ключ без значения (если нам нужен просто список объектов и не надо к ним привязывать никакие данные):
Интересная статья. Но надо помнить, что объекты-сущности (состоящие на 90% из геттеров-сеттеров) и сервисы для работы с ними появлились не просто так. Если перенести логику в модели доменной области, то мы получим кучу проблем, например:
- нам придется использовать DI и передавать в конструктор модели другие классы, что часто не совместимо с ORM библиотеками (они обычно требуют пустой конструктор у модели) - мы може получить что-то напоминающее Active Record, если перенесем операции работы с БД в модель - мы можем нарушить принцип "единой отвественности" и назначить классу модели много задач
Статья Фаулера, к сожалению, не приводит каких-то примеров c толстыми моделями и тонкими простыми сервисами, координирующими их работу. Может ты, раз тебе так нравится эта статья, можешь придумать пример?
Ну вот возьмем такую простую вещь, как валидацию. Должны ли мы внести код валидации в модели? Должны ли мы сделать Валидатор и инъектировать его в модель через конструктор? Или более сложный процесс регистрации, который например включает в себя валидацию, вставку нескольких сущностей в БД, обновление статистики, отправку письма?
В composer.json указывается имя класса и метод. Ты можешь либо сделать класс в общей папке (например с именем Composer\PostInstallHandler) либо сделать отдельную папку scripts и добавить ее в автозагрузку в composer.json. Там ведь можно несколько папок и префиксов указать. И даже отдельные файлы перечислить (хотя это уже не PSR-4 будет).
- не пиши по 2 команды в одной строке и освой стандарт оформления кода PSR - давай переменным более понятные имена ($k) - отучайся от исплоьзования str-функций, не поддерживающих кирилицу - $i <= strlen($phone)-1; тут лучше использовать знак "меньше" без "равно" - if (($k > 2) && ($k % 3) == 0) -> if ($k == 3) - правила форматирования конечно странные. Красивее было бы, если остается 4 цифры, делать 2 блока по 2.
> 1) https://ideone.com/4gty5H Приведение номера к единому формату. Лучше было бы сделать массив номеров и проверять все номера, которые даны в учебнике. На вид, вроде правильно.
> 4) https://ideone.com/qKlxkQ «Grammar Nazi» с автоматическим исправлением. По этой задаче я вроде где-то выше уже писал, что там "а/но" обрабатываются неточно и дают ошибку в предложении вроде "Хорошо. Но не очень". Также пытается добавлять пробел в самый конец текста.
> 5) https://ideone.com/LoFKwm «Опечаточники» Не все латинские буквы указаны, и программа считает полностью латинские слова ошибкой, а это не так. Надо искать слова со смешанными алфавитом.
> 1) https://ideone.com/0HTZhW Задачка "Клавиша shift" слишком сокращаешь названия переменных, $arr - ничего не значит, лучше $sentences. Тут https://ideone.com/6PX5Mp не удаляются лишние пробелы после знаков препинания (или это и не требуется? вроде требуется).
> 2) https://ideone.com/P8euld "Yoda Speak" > $reverseSent = implode(" ", array_reverse(preg_split("/[ ]/u" , $sent, 0, PREG_SPLIT_NO_EMPTY))); Длинновато, лучше на 2 команды такое разбивать.
В остальном, верно.
> 3) https://ideone.com/AO9sGB "Калькулятор" > $number = 0; Можно наверно не повторять это несколько раз?
> //Удаляем купюры количество которых равно 0 Это наверно лишнее - алгоритм и с нулями должен по идее нормально работать. Проверку на отутствие денег можно сделать и через array_sum.
> $count = ($preCount < $quantity) ? $preCount : $quantity; Это лучше записать через min()/max()
> .container { > padding: 10px; > font-size: 0px; > display:table; не понял, зачем это? Зачм таблица без table-row или table-cell? Также не понял, зачем ты таблице ставишь паддинг, который есть только у ее ячеек. Это какой-то хак для решения проблемы пробелов? Стоило тогда добавить комментарий, а то совсем неочевидно. Ну и конечно изучи и другие методы борьбы.
- li { margin: 5px 0px; } меняет стиль всех элементов списков, а на странице могут быть и другие списки. Надо ставить стили точечно, чтобы это применялось только к меню. То же относится к ul, nav - ты жестко прописал размеры body. Это не годится. Верстка должна растягиваться под ширину страницы. - font-family: 'Trebuchet MS'; - надо указывать в конце списка один из встроенных шрифтов (вроде sans-serif) - h1 должен быть не жирным - article { width: 230px; } - статья должна занимать всю оставшуюся ширину, а не 230px - nav:after {} - он тут не нужен. Он применяется к не-float элементам, которые содержат внутри float элементы. А у тебя nav и так float и ему clearfix не нужен.
Высота кнопки и поля ввода не совпадают. Ты учел что кнопки и поля ввода по умолчанию имеют разный box-sizing, для одного задается внутреняя высота, для другого - внешняя. надо либо менять box-sizing либо пересчитывать высоту с учетом этого. Читай подсказки (хотя бы после того как решил).
Ну и на практике стили вроде input {...} будут конфликтовать с другими инпутами на странице - лучше применять стили более точечно.
> А можно подсказку как сделать чтобы примечание не растягивала контейнер в котором оно содержится? У меня пока получилось только так float не растягивает родительский контейнер (а также position: absolute) так как вырывается из потока.
- body { width: 330px; } - не годится, давай верстать резиново под любую ширину, а не прописывать жестко ширину страницы. - p { margin-left: auto; max-width: 200px; } - это применяется только к абзацам, а что если в тексте заголовоки, таблицы, списки, картинки? Читай подсказки - aside {vertical-align: bottom; } - свойство vertical-align работает только для элементов с display: inline-block, inline, table-cell. К блокам оно неприменимо.
Увы, эта задача решена совсем неправильно. Надо переделвать. Добавь в текст заголовки и списки и больше примечаний.
- Текст не должен затекать под желтый блок слева. - div {} - будет применяться ко всем дивам на странице, плохо, сломает верстку. Верстать надо так, чтобы твою верстку можно было вставить на любую страницу и не было никаких конфликтов.
> И можно еще подсказку как сделать <figcaption> внизу картинки? Очевидно, сначала нужно использовать position: absolute, но как сделать чтобы элемент был внизу? Неужели задавать координаты с помощью top, left, ...? Элементарно: абсолютно позиционировать подпись относительно блока с картинкой, которому назначить относ. позиц. Это как раз пример когда абс. поз. уместно. Почитай про свойства top, left, right, bottom - их можно использовать в разных сочетаниях.
Тут немного сложная часть - как сделать ограничение ширины картинки. Придется повозиться с width/max-width.
- между кнопками должна быть линия в 1px а не 2 пикселя - кнопки высоковаты - body { font-size: 0px; display: table; } - это не позволяет вставить твой блок на произвольную страницу. мы ведь не будем там сбрасывать шрифт на body. - "inputbox left" - это неудобно, подписывать каждый блок. И что если у нас не 3, а больше кнопок? переписывать CSS? Нужно более универсальное решение. Есть же :first-child например. Погугли "css псевдоклассы" - для анимации наверно лучше бы подошло более простое правило transition - изучи его. Или нет?
Ответы HTML задачиАноним07/08/16 Вск 09:31:05#843№815065
> Как на глаз определить тень и шрифт? Для начала, надо попробовать определить радиус тени (на котором она плавно переходит в прозрачность). Если присмотреться, то видно что на картинке тень несимметричная: она большая сверху, маленькая снизу и равная по сторонам. Значит, тень смещена вниз, а справа или слева ее ширина. По ней мы подбираем радиус (будет примерно пикселя 3 я думаю). подобрав радиус, подбираем прозрачность черного, чтобы с краев тень совпадала по прозрачности с картинкой.
Ну и напоследок подбираем вертикальное смещение тени, просто на глаз двигая тень вниз.
Если ты не понимаешь некоторые термины, то изучи какие есть параметры у теней. Заметь что для внутренних (inset) теней одним параметром меньше.
Шрифт -какой-то из стандартных. Погугли какие распространенные шрифты есть, по моему тут Arial.
Также, как насчет клавиатурной навигации?
> А почему ты выбрал именно наклонный текст? Лучше же span взять - он не меняет стиля текста. Короче пишется. Лучше конечно span.
> Я пока не знаю javascript, можно я доделаю это позже? Можно пока подсказку как сделать чтобы в старых браузерах просто выводился набор чекбоксов? Гм... тут надо использовать в селекторе CSS правила которые не понимают старые браузеры (напрмер какие-то псевдоклассы из CSS3). То есть условно говоря, если старый браузер не понимает n-th-child() то мы можем записать так:
.inputbox { правила для старых браузеров } .inputbox:n-th-child(...) { переопределяем правило для новых }
Насчет яваскрипта - проблема старых браузеров в том, что они не поддерживают :checked. И потому в них при клике не будет меняться подсветка кнопок. Для решения надо повесить на радиокнопки обработчик событий и при перекоючении добавлять какой-то CSS класс на нажатую кнопку.
> Я забыл про этот пункт пока делал задание, можем мы это опустить? В "боевых" задачах я естественно так не буду делать. Лучше бы конечно с самого начала учиться делать правильно. Да и вроде у тебя в этой задаче проблем с этим нет, все за классами скрыто.
> Я сначала подумал, что ты ошибся насчет :active, что надо было :checked за место этого. Нужно еще и :active делать? Какой у неё должен стиль? Как у :checked? :active вроде значит "вжатое" состояие чекбокса в момент нажатия. Это если ты хочешь чтобы в момент нажатия он как-то подсвечивался или был более темным например.
> А можно еще подсказку как и это сделать? Для начала сделай просто список радиокнопок с подписями но без стилизации и поэкспериментируй с клавиатурой. Потом изучи псевдокласс :focus
Скрыть чекбокс можно и не через display: none, а например: через visibility: hidden, через overflow:hidden c задвижением за край видимой области, через абс. поз. за край видимой области (left: -10000px) - но тут есть свои недостатки. Ты кстати должен знать эти варианты.
>>старайся не использовать id в верстке так как с ними не получится вывести на странице несколько блоков вкладок. Разрешается использовать классы или data-атрибуты для связи вкладок и заголовков. > Это касается даже при использовании for у лейблов? Тут надо смотреть, насколько это сложно реализовать. Если без id обойтись очень сложно и будут проблемы - значит, придется их использовать. Если же можно без особых проблем обойтись - то хорошо бы обойтись. То есть надо взвешивать плюсы и минусы.
В твоем случае эти id прописаны в css. Значит, если мы хотим на странице несколько блоков с вкладками, нам нужно каждому дать уникальный id и еще прописать его в css. Это непрактично если у нас страница генерируется динамически и мы не знаем сколько будет блоков на странице.
Хорошо бы хотя бы от id в CSS избавиться, хотя бы через data атрибуты
Вообще, без уникальных id видимо можно обойтись только если верстать в таком подрядке:
- заголовок - контент - заголовок - контент
Этот вариант еще интересен тем, что на старых браузерах (а также на устройствах с узким экраном! адаптивность!) его можно разверстать через теги вроде h3 как текст с подзаголовками. Но тогда мы не сможем переносить заголовки на новую строку если их слишком много (хотя... может флексбокс нам поможет? изучи-ка вопрос). Посмотри, в общем, какие есть варианты и какие у них недостатки.
> Как тогда реализовать переключение вкладок, если вкладывать элементы уже во внутрь лейбла? Не получиться обращаться к соседним или родственным элементам, потому что сначала нужно проверить на :checked у input. Можно кстати идентифицировать вкладки и не по id, а например по data-атрибутам: <input data-tab="tab1">. Это тоже требует униакльности, но только в рамкх одного блока вкладок.
> #first-tab:checked + .tab-label[for="first-tab"] + #second-tab + .tab-label[for="second-tab"] + #third-tab + .tab-label[for="third-tab"] + #fourth-tab + .tab-label[for="fourth-tab"] В новых браузерах есть селектор ~. Нагугли и прочитай про все новые псевдоклассы и селекторы из CSS3. В старых браузерах он правда не работает, для них можно наверно просто вкладки вертикально вывести как блоки.
Есть еще такая проблема: активная вкладка при наведении мыши становится серой - мне кажется это неправильно.
> Это касается даже при использовании for у лейблов? Как тогда реализовать переключение вкладок, если вкладывать элементы уже во внутрь лейбла? да, проблема. Но может мы хотя бы можем убрать жестко прописанные id из CSS?
>>сверстай блок так, чтобы блок с вкладками можно было вложить в страницу блока вкладок > Нужно чтобы можно было скопировать вкладки в контентную страницу? Может лучше чтобы в контентной странице был свой элемент со вкладками?
да, чтобы внутри мог быть свой блок с вкладками и он не конфликтовал с родительским.
Аноны, давайте перекатываться в новый тред >>807538 (OP) (OP) , тут будут только ответы на старые посты. Кого пропустил -напомните о себе в новом треде.
Опять, многовато дивов. Для этой задачи достаточно одного. Ну и надо все же делать ближе к тому, что изображено на картинке. От верстальщика обычно требуется сверстать так, как изображено на макете, а не как ему кажется лучше.
> html { > box-sizing:box-border; box-border - неправильное значение. И зачем тут это?
> min-height:200px; Это в задаче не требовалось
> p1 { Зачем придумывать свои теги? Как другим людям догадаться, что он значит? Не надо так.
Набор информации о файле содержит самые разные значения и выгоднее их засунуть как JSON чем пытаться уложить в сложную реляционную модель. Выборки и поиск по этим значениям все равно делать не требуется.
> Как мне его обернуть теперь? Это статический класс должен быть принимающий в свойства целый массив и возвращающий конкретное значение (например длину видео). Класс ничего не возвращает же. "Обернуть" это значит что-то врде такого:
$info = new MediaInfo($mediaInfoArray);
Либо
$info = new MediaInfo::fromArray($mediaInfoArray);
Если у тебя конструктор занят под что-то другое.
А уже в классе могут быть (а могут и не быть) например методы:
Ну то есть ты должен подумать, что ты хочешь получить от этого класса, какие данные, в каком виде, и как сделать его удобным в использовании и понятным. Очевидно что без класса нам пришлось бы копаться в массиве, в котором могут отстуствовать любые поля и надо вспоминать где что хранится.
> Или же это класс со свойством fileInfo которое представлено в json формате, а методы делают тоже самое, что и в статическом варианте. В последнем случае желательно чтобы я сразу в объект файла запихивал свойство-класс работы с этим json, т.е. это должно делаться через FETCH_FUNC? Вряд ли можно через PDO это сделать. Надо вручную выбрать нужное значение, раскодировать его и создать объект.
>>815058 >Это верно. Потому что тут ты меняешь тип метода, и соответственно придется менять места его использования. А вот если тип остается прежним, но например, меняется алгоритм хеширования (или исправляется ошибка в нем) - остальной код трогать не придется. Но если мы не меняем тип, то остальной код тоже не придётся трогать. Не могу понять как инкапсуляция тут помогает.
>>815058 >> public function setProperty($property, $value) { >Это вообще не очень хорошая вещь. Во-первых, она не проверяет имя поля и позволяет создать поле с любым именем. Во-вторых, она по большому счету нарушает инкапсуляцию. Потому что, если ты добавишь в сеттер setName() какую-то проверку, то она не будет вызвана в setProperty(). У меня есть похожие методы на этот которые обращаются к полям не через сеттеры. Их тоже следует исправить?
>>815058 >Ну иногда такие классы называют Сервис, иногда Хелпер. Тогда я бы предпочел иметь Сервисы (классы отвечающие за внутреннюю логику) и Хелперы (классы содержащие вспомогательные методы) в разных директориях. Это не критично если я буду пользоваться таким подходом? По хорошему, мне, наверно, следует перенести логику из контролеров в сервисы.
>$limit = 2147483647 В мануале по mysql сказано о том что если нужно получить все записи, то нужно указать какое-то большое число
https://dev.mysql.com/doc/refman/5.7/en/select.html >To retrieve all rows from a certain offset up to the end of the result set, you can use some large number for the second parameter. This statement retrieves all rows from the 96th row to the last: >SELECT * FROM tbl LIMIT 95,18446744073709551615; Это действительно так? Бывают ли на практике такие ситуации что нужно получить количество записей большее чем позволяет максимальное значение int?
Это не чат! Пожалуйста старайтесь постить только вопросы, решения и ответы по теме. Сколько лет вы не можете найти работу никому не интересно. Высказывайтесь одним большим постом, а не цепочкой мелких
Это тред для начинающих. Не написал за свою жизнь ни одной программы? Ты наш человек.
Устанавливать пока что ничего не требуется, разве что редактор кода вроде Sublime Text 3, Notepad++, Netbeans PHP или PhpStorm (с ним будет удобнее).
Предыдущий тред был тут:
Что самое главное для программиста? Умение аккуратно оформлять код (читай второй пост прежде чем писать код).
Почему PHP? Потому что фейсбук и википедия на нем написаны, и вакансий море, и учить легко.
Правила: ведем себя воспитанно, помогаем новичкам, постим ссылки на решения задачек, ОП их проверяет и дает советы и замечания. ОП заходит редко, где-то раз в 2-3 дня, у него мало времени, не жди его, решай задачки дальше. ОП отвечает на все вопросы по его задачкам и учебнику, а вот насчет каких-то других вещей - только если останется время. Но в треде немало анонимных экспертов разного уровня, так что вряд ли вопрос останется без ответа.
У нас есть уроки по основам PHP, они собраны и выложены по адресу http://archive-ipq-co.narod.ru/ Это учебник для изучающих с нуля, то есть если ты вообще ничего не знаешь, то надо начать с него. Он простой и понятный (по крайней мере в начале). Там есть задачи, их надо решать обязательно (чтобы стать программистом, надо писать код — иначе никак). Пости ссылки на решения в тред, мы их проверим, напишем замечания и дадим советы по улучшению.
Если не знаешь как решать, запости код, напиши в каком месте остановился и попроси подсказку.
Ты прошел весь учебник? Молодец, но это были лишь основы языка 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/Yii2: https://gist.github.com/codedokode/8733007
- После нее можно изучать автоматизированное тестирование
- Если ты все решил, переходи к Symfony 2/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
Решения задач лучше показать мне, особенно на ООП,так как сам ты вряд ли увидишь все ошибки. Пости свой код на гитхаб и вкидывай ссылку в тред по мере решения. Я прокомментирую и укажу на ошибки.
Также, у нас есть задачи которые позволят тебе изучить или подтянуть до нормального уровня знания 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://gist.github.com/codedokode/10539213
Что почитать
- Мануал по 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
Нужен ли ООП, фреймворки, MVC, git, composer? — Да, однозначно. Посмотри любую вакансию.
Сайт опять упал!!!!! — Не паникуй, а открой http://rghost.ru/6bfCY9lfl и получи личную немного устаревшую оффлайновую копию сайта (можно читать хоть на андроиде без интернета)
Оформляй код аккуратно!!! — например пропусти через phpformatter.com . Также, если ты пользуешься IDE вроде PhpStorm, Netbeans, Eclipse, то в них эта опция встроена, подробнее: https://gist.github.com/codedokode/8759492
ОП, сделай за меня мою работу или домашнее задание? — Это конечно, хорошая идея, но нет.
Подскажи сайты для поиска работы, я не умею гуглить? — hh.ru, geekjob.ru, moikrug.ru (склеен с brainstorage.me), fl.ru, upwork.com (бывший одеск). Имей в виду, что кроме фриланса есть еще постоянная удаленная работа (remote job) когда тебе не надо тратить время на поиск заказов и переговоры с неадекватными заказчиками.