24 декабря Архивач восстановлен после серьёзной аварии. К сожалению, значительная часть сохранённых изображений и видео была потеряна. Подробности случившегося. Мы призываем всех неравнодушных помочь нам с восстановлением утраченного контента!
Добро пожаловать в наш уютный тред. Тут мы изучаем язык PHP (а также JS/CSS/HTML/SQL), решаем задачки и даже делаем простые сайты! Зачем? Кто-то хочет научиться программировать, кто-то - делать сайты, кто-то - просто размять мозги и заняться чем-то полезным.
Пожалуйста, пишите один большой пост вместо нескольких маленьких и не флудите не по теме. ОПу ведь все это читать придется.
Это тред для начинающих. Не написал за свою жизнь ни одной программы и имеешь тройку по математике? Ты наш человек.
Устанавливать пока что ничего не требуется, разве что редактор кода вроде Sublime Text 3, Notepad++, Visual Studio Code, Netbeans PHP или PhpStorm (с ним будет удобнее).
Что самое главное для программиста? Умение аккуратно оформлять код (читай второй пост, прежде чем писать код).
Правила: ведем себя воспитанно, помогаем новичкам, постим ссылки на решения задачек, ОП их проверяет и дает советы и замечания. ОП заходит редко, где-то раз в 2-3 дня, у него мало времени, не жди его, решай задачки дальше. ОП отвечает на все вопросы по его задачкам и учебнику, а вот насчет каких-то других вещей - только если останется время. Но в треде немало анонимных экспертов разного уровня, так что вряд ли вопрос останется без ответа.
У нас есть уроки по основам PHP, они собраны и выложены по адресу http://archive-ipq-co.narod.ru/ Это учебник для изучающих с нуля, то есть если ты вообще ничего не знаешь, то надо начать с него. Он простой и понятный (по крайней мере в начале). Там есть задачи, их надо решать обязательно (чтобы стать программистом, надо писать код — иначе никак). Пости ссылки на решения в тред, мы их проверим, напишем замечания и дадим советы по улучшению.
Если не знаешь как решать, запости код, напиши в каком месте остановился и попроси подсказку.
Ты прошел весь учебник? Молодец, но это были лишь основы языка PHP, этого недостаточно. Вот что в идеале надо изучить еще: ООП, как работает веб-сервер, HTML/CSS, SQL, PDO, работа с таблицами в БД, работа с формами, MVC, git, composer, JS, фреймворки, автоматизированное тестирование.
Надо переходить к более серьезным задачкам, которые научат тебя всему этому.
Решения задач лучше показать мне, особенно на ООП,так как сам ты вряд ли увидишь все ошибки. Пости свой код на гитхаб и вкидывай ссылку в тред по мере решения. Я прокомментирую и укажу на ошибки.
Также, у нас есть задачи которые позволят тебе изучить или подтянуть до нормального уровня знания JS/HTML/CSS/SQL. Решай их параллельно с задачами выше.
Оформляй код аккуратно!!! — например пропусти через phpformatter.com . Также, если ты пользуешься IDE вроде PhpStorm, Netbeans, Eclipse, то в них эта опция встроена, подробнее: https://gist.github.com/codedokode/8759492
У ОПа нет аккаунтов и групп вконтакте, в фейсбуке, в твиттере, все "пхп-треды" там поддельные.
Платиновые вопросы
- Почему PHP? Потому что фейсбук и википедия на нем написаны, и вакансий море, и учить легко. - Сайт опять упал!!!!! — Не паникуй, а открой http://rghost.ru/6bfCY9lfl и получи личную немного устаревшую оффлайновую копию сайта (можно читать хоть на андроиде без интернета) - Что надо знать чтобы найти работу - разработчику: PHP, SQL, HTML/CSS, JS, ООП, Git, композер, MVC, фреймворк. Верстальщику - HTML/CSS, JS, jQuery - Можно подробнее про поиск работы, собеседования - нет, ОП писать не будет, но может кто из анонов захочет рассказать. Поищите тред перезвонивших, а также раздел /wrk/. - Сколько времени надо изучать все это? - все зависит от тебя, но не меньше 6-8 месяцев - Посоветуйте редактор кода - Sublime Text 3, Notepad++, PhpStorm - Нужен ли ООП, фреймворки, MVC, git, composer? — Да, однозначно. Посмотри любую вакансию. - Что самое главное для программиста? Умение аккуратно оформлять код. - ОП, сделай за меня мою работу или домашнее задание? — Это конечно, хорошая идея, но нет. - Подскажи сайты для поиска работы, я не умею гуглить? — 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 пробела)
Вот ссылка на стандарты, где все это описано подробнее и даны примеры оформления:
Код нужно писать не как попало, а аккуратно и по правилам. Почему? Потому, что на неакуратно написанный код не хочется даже смотреть.
Если тебе лень выравнивать код руками, закачай его на 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, то рассказать об этом стоит в каком-нибудь другом треде.
Не придирайся к знанию английского языка, анон пишет как умеет.
Ах да. Если тебе кажется, что что-то в учебнике или задачах можно сделать лучше — пиши, обратная связь всегда очень полезна.
Возможно ли полюбить php? Вот питон как ламповая тяночка, с ней хорошо, но с ней нет будущего, она утянет на дно. А php - это не такая ламповая, но зато работящая тян. Я же смогу привыкнуть к php и полюбить его? Это же не язык уровня 1С - грязного вонючего бомжа?
>>945120 У тебя видимо загвоздка в том, что ты не очень понимаешь что сортируешь. Наверное ты хочешь отсортировать массив по значению, хотя пытаешься через ключи. http://php.net/manual/ru/array.sorting.php Попробуй что-то из этого. ИМХО, у тебя очень хромает теория.
>>945099 Мне после Питона все языки говном кажутся. До этого писал на пхп. Не представляю как бы снова пришлось писать на нём. Хотя ты мыслишь и делаешь правильно, на пыхе вакансий больше.
>>945130 > Наверное ты хочешь отсортировать массив по значению >>945131 > А потом еще сформулируй вопрос нормально. Что из твоего данного массива после сортировки должно получиться. Ничего не получается. Есть уникальный id, есть значение, которое присваивается этому id. Нужно вывести все id, отсортировав по значению, которому им присвоено. Что-то вроде ORDER BY id
>>945266 > >$peremennye_translitom Могу себе позволить. Я не кодер, которого ебет начальство за каждую орфографическую ошибку в доках, а управленец, который как раз ебет кодеров который ебет нижестоящее начальство, чтобы оно ебало вас
> По-моему тебе уже только живительная эвтаназия поможет. Программист - это, блядь, бледная моль, шестеренка №64. Кто-то скажет "кококо, а как же Джобс, Гейтсс, Цукерберг?". А вот хуй, эти люди прославились как организаторы-управленцы-бизнесмены, а собственно код писали безликие макаки, на которым всем похуй.
Так что под шконку. Сколько я таких ограниченных перевидала
Подскажите, существует готовый скрипт для попапа пикч прям как на дваче (с возможностью перетаскивания и масштабирования)? Или придется все делать самому? Смог найти только скрипты-галереи без масштабирования и перетаскивания.
>>945286 Укради с двача че ты как не пират? А вообще, 99% уже есть такой скрипт, нужно больше искать. Попробуй по-английски составить вопрос гуглу, либо например на stackoverflow создай тему на английском. >>945285 Добавил в коллекцию паст, это блять эпично.
Алсо, пацаны объясните, как это работает: >>945259 >if ($ballov -- 0) {} else { print... } ?
Ананасы, прочитал, что все ошибки теперь наследуются от Throwable. Однако, мой ExceptionHandler, который принимает Throwable, по-прежнему не перехватывает синтаксические ошибки, т. е. parseErrors. Что я не так делаю?
Если у меня некоторые свойства объекта устанавливаются в конструкторе, должен ли я проверять их существование в других методах? Т.е. я как бы подсказываю пользователю класса, что для работы с этим методом необходимы такие-то условия, но с другой стороны есть гарант в виде, что они существуют. Правда где-то их могут очистить... Т.е. наверное все-таки нужно проверять их на существование.
>>945392 Конструктор чекает на нулл и невалидные значения? Публичные сеттеры есть? Если нет, то могут ли затереться значения где-то в коде класса? Если с этим всем разобрался, то можешь не проверять нихуя. Однако, поскольку код имеет свойство внезапно подвергнуться правкам твоей же рукой и ты уже забудешь где чего, то для верности можешь чекать вообще всегда.
>>945485 Тогда я ушел с твоей обоссаной галеры вместе с половиной команды, спиздил сорцы проекта, написал обличающую статьюу на хабре-хуябре и доу, гуд лак искать макак за доширак.
>>945285 Чего раскудахтался-то, придурок? Я в код заглядываю раз в 10 лет, чтобы отправить разъеботчикам не только exception.log, но и кусок говно кода, который надо поправить. >перевидала Ой, иди нахуй, зелень.
>>945488 Вы, мамкины кодеры, никчемные пустые людишки. Посредственности, серая масса. Жизнь ваша убогая, никто вас не любит, никому вы не нужны. Ваши "умные, нестандартные мысли" про спиздить сорцы и написать обличающую статью за пределами интернета никому не интересны, рассуждения уровня пятиклассника о жизни никто слушать не будет, а за особо дерзкие выпады и по ебалу могут накидать. У вас нет чувства юмора и эрудиции, чтобы остроумно шутить, нет знаний и жизненного опыта, чтобы поведать что-нибудь интересное предложениями больше чем из 3-х слов. Детские максимы, псевдознания, почерпнутые из роликов на ютубе и передач по рен-тв, стереотипы, рожденные в среде клешированного офисного планктона и нитакихкакфсе - вот и весь ваш "интеллектуальный" арсенал. Разумеется, ни девушку, ни взрослого, думающего человека таким богатством духа не заинтересовать. Вам хочется денег, славы, признания, но в жизни никто вас даже не замечает, как никто не замечает вошь на бездомной собаке. Вот и приходится вам, бедненьким, привлекать к себе внимание на интернет-пространстве самыми идиотскими высказываниями, на которые сбегаются точно такие же обделенные жизнью, чтобы поспорить, давать советы, увещевать, хоть как-то почувствовать себя чем-то "значимым" для кого-то на другой стороне провода. В интернете вы все аналитики. философы и выдающиеся мыслители современности, а на деле неуверенные в себе, зажатые, зависимые от родителей и мнения окружающих человечишки, прячущиеся в своей комнате от мира и людей, как тараканы от включенного ночью на кухне света. Мне вас жаль.
Нытики из перезвоним-треда, выкатитесь обратно плиз. Тут тред про обучение программированию, а не для жалоб на жизнь от всяких неудачников, не способных найти себе хорошую работу. Вы своим нытьем мешаете тем, кто учится.
- название Student::GENDER_FEMALE намного больше говорит чем просто строка 'f'. - сразу видно, какие константы есть и какие варианты значений доступны - если ты опечатаешься в константе, будет фатальная ошибка, а в случае со строкой -это останется незамеченным - в IDE будет работать автодополнение при вводе названия константы
Еще хуже было бы, если бы ты например использовал для обозначения пола числа 1 и 2 вместо строк, тогда вообще понять в коде было бы ничего нельзя без констант.
> Если у меня некоторые свойства объекта устанавливаются в конструкторе, должен ли я проверять их существование в других методах?
А о каком языке идет речь? В PHP если ты в классе объявил свойство, то оно всегда существует и проверять ничего не надо. Или ты имеешь в виду, что в свойство могут записать неправильное значение?
Лучше всего конечно ставить проверку там, где свойство меняется. Если оно приватное и меняется через метод setSomething() то нужно там поставить проверку и при попытке передать неверное значение выбросить исключение, завершающее программу. Если свойство публичное то проверку не сделать.
Я бы советовал также подстраховаться и добавить проверку при чтении свойства, примерно такого вида:
если ($this->something неправильное) { выбросить исключение; }
Также, эту проверку можно сделать короче с помощью функции assert. Она правда не бросает исключение, а только дает warning:
assert($this->x > 0);
зато выглядит очень наглядно. Любому теперь ясно, что функция рассчитывается что в x будет положительное значение.
Throwable это интерфейс, потому не наследуются, а реализуют. Это было сделано специально, чтобы можно было делать свои классы исключений, не наследующие Exception.
Как освоить адаптивную вёрстку? какие есть хорошие уроки по этой теме, желательно чтобы с примерами реальных проектов, то есть чтобы показывался весь процесс адаптивной вёрстки из psd?
В каждой компании свои градации. Синьора из какой-нибудь провинциальной веб-студии в Гугле даже на собеседование на стажера не пустят.
Обычно эти градации соответствуют опыту:
- стажер - человек, как правило, студент, который пока не имеет нужных для полноценной работы навыков - джуниор - человек с минимальным опытом, которому нужен постоянный надзор и помощь, что-то вроде разнорабочего на стройке - миддл - человек с определенным опытом, способный сам решать более сложные задачи, оценивать их трудоемкость - сеньор - человек с значительным опытом, способный руководить другими разработчиками, принимать решения, понимать, что нужно бизнес-заказчику (не красивый код с кучей абстракций, а быстрое и эффективное решение задач)
Если ты ни дня ни работал, то выше джуниора должность ты в принципе получить не можешь в связи с отсутствием опыта.
Что должен делать претендент на пост джуниора с 0 опытом работы? Конечно, учиться. Зубрить вещи, которые пригодятся ему на работе:
- алгоритмы и структуры данных - объектно-ориентированное программирование - понятный и самодокументируемый код (есть книга "Совершенный код" на эту тему) - системы контроля версий (git) - если ты вебщик, то веб-технологии (HTML, CSS, JS) - базы данных, SQL, нормальные формы, транзакции - изучать популярные инструменты, библиотеки и технологии (фреймворки например)
Так как у такого кандидата нет опыта работы, то говорить на собеседовании с ним про предыдущие проекты смысла нет. Потому их гоняют по теории, то, что я перечислил выше, про ООП, про нормальные формы, как найти число в массиве, что нового появилось в последнем PHP.
Конечно, не везде это нужно. В провинциальной веб-студии, чтобы попасть на должность перекрашивателя меню и натягивателя верстки на CMS, это может не потребоваться. Но ты ведь вряд ли заинтересован в том, чтобы этим всю жизнь заниматься. Наверняка ты хочешь быть полноценным разработчиком в большой команде, разрабатывающей какой-нибудь серьезный продукт.
Прежде чем браться за адаптивную верстку, надо освоить резиновую, то есть такую, которая тянется по ширине, а не имеет фиксированную ширину. Адаптивность заключается в более тщательной адаптации верстки под разные устройства. На практике адаптивность реализуют подстройкой верстки под маленькие экраны - планшеты и смартфоны. Обычно выделяют так называемую линию перелома (break point), если экран имеет ширину меньше определенной, то мы меняем верстку так, чтобы страница отображалась на нем без необходимости прокручивать ее горизонтально (то есть выстраиваем все в столбик, вместо нескольких колонок делаем одну).
Также добавляется тег meta viewport, который заставляет браузер рендерить страницу под реальную ширину устройства, а не имитировать экран шириной 900px и заставлять пользователя приближать текст.
Я советую начать с изучения примеров адаптивных сайтов. Гугли статьи вроде "примеры адаптивных сайтов" и смотри примеры там, чтобы понять, как это обычно выглядит. Если у тебя нет смартфона, то ты можешь имитировать мобильный браузер, сделав окно узким либо открыв инструменты разработчика (Ctrl + SHift + I) и нажав там кнопочку со смартфоном.
Технически нужно изучить всего несколько вещей:
- медиа-запросы CSS @media - тег meta viewport, говорящий браузеру, что страница адаптирована под мобильные устройства
У нас в ОП-посте есть задачи на CSS и там есть макет, которй надо свестать в том числе с адаптивностью
Иногда еще добавляют адаптацию страницы под экраны с высокой плотностью пикселей (ретина), чтобы для них использовались картинки более высокого разрешения. Гугли HTML-атрибут srcset и теги picture, source.
Вообще, адаптивность не ограничивается мобильными устройствами. Есть и другие вещи, которые можно улучшить. Ну например, при печати страницы ссылки становятся недоступны (ты не можешь кликнуть пальцем на бумагу). Можно в таких случаях сделать правило, чтобы при печати выводились URL ссылок. Изучи медиа-запросы, там много разных опций.
Адаптивность значит способность отображаться на разных устройствах с учетом их особенностей. И это обычно не просто уменьшение шрифта. На мобильных устройствах (адроид/айфон) браузер по умолчанию рисует страницу на холсте шириной 800px точнее, 960px и отображает в уменьшенном виде. Пользователь кликает, чтобы ее увеличить, и если абзацы широкие, то ему приходится прокручивать экран вправо-влево чтобы читать текст (увидеть все это можно тут: http://www.youtube.com/watch?v=-1haU-WRMoA если ты с этим явлением не знаком).
Также, надо понимать, что на мобильных устройствах нет средней и правой кнопки мыши, возможности точно нажать маленький элемент, а также возможности навести мышь на элемент, только тап пальцем по экрану или жесты.
Смартфон также может быть повернут набок — тогда ширина экрана получается больше. Кроме смартфонов, есть планшеты, где ширина экрана большая, но используется палец вместо мыши.
Соответственно, адаптивные сайты на мобильных устройствах часто меняют расположение контента так, чтобы информация была в виде узкой вертикальной полосы и не требовала зума и прокрутки вбок. Элементы управления, кнопки, делают крупными. Для этого применяют такие вещи:
1) правило @media в CSS которое позволяет применять блок правил только при определенных условиях (ширина экрана меньше определенного значения — например меньше 640px). Информация:
(обрати внимание, сколько разных видов устройств поддерживается — можно отдельно задавать стили для телевизоров, а отдельно для печати)
Заметь что @media не поддерживается в старом ИЕ, потому логично верстать страницу по умолчанию под обычные браузеры, а правила для маленьких экранов заключить внутрь @media, который ИЕ наверно проигнорирует (если нет — выносим в отдельный файл и подключаем через условные комментарии).
Кстати, насчет vw, ты можешь делать так:
font-size: 14px; // правило для старых браузеров font-size: 5vw; // правило для CSS3 браузеров
Это будет работать, если писать в таком порядке так как браузеры игнорируют свойства которые они не поняли.
2) тег meta viewport который говорит мобильному устройству что страница учитывает его особенности, и указывает что ее надо рисовать на холсте, равном реальной ширине экрана, чтобы отображалась в 100% масштабе. Часто (подозреваю по незнанию) запрещают зум, хотя мне это не нравится — может у человека маленький экран и плохое зрение и он хочет увеличить текст. Я против таких штук, но среднестатистический верстальщик делает такие вещи методом «скопипастил из интернета» и сам часто не понимает что он делает.
Для отладки адаптивного дизайна лучше всего конечно использовать реальные устройства, но в Хроме в инспекторе есть неплохой режим имитации маленьких экранов, и в фаерфоксе что-то для этого есть.
Для типов вроде INT это просто рекомендуемая ширина колонки при выводе чисел Для DECIMAL задает точность в знаках Для FLOAT - точность, но не в знаках, а в битах, выделяемых под хранение мантиссы (влияет на то, будет ли использоваться для хранения числа 4 или 8 байт). Если указать 2 числа, то точность в знаках, до которой числа принудительно округляются.
>>945813 Может. Так как значения для номеров в скобках это не размер(он всегда фиксирован для инт типов), а количество цифр для отображения при запросе, например, mysql консольным клиентом.
Задачка про лайкиАноним04/03/17 Суб 09:35:55#50№945839
На всякий случай напишу, что на sqlfiddle результат SELECT'ов по умолчанию выводится в виде HTML-таблицы, что выглядит громоздко, как по мне. Но можно выбрать plaintext (пик).
Вот у меня такая структура проекта (пикрил). Как мне получать адрес папки src из любого места? Ну, я пишу контроллер, в нем метод render, который должен в соответствии с запросом отображать файл из папки views.
>>945877 мои глаза. просто возьми фреймворк и не парься. >>945887 дебильные задачки для тупых олимпиадников. даже текст задачи нормально составить не могут. какие-то склеенные банкноты, натуральные числа, вообще ахуеть.
>>945940 У тебя в шаблонах код контроллера. Шаблоны только отображают переданные сверху данные, а не обращаются к HTTP/выполняют SQL-запросы, как в твоём случае. Формирование ссылки на CSS в контроллере выглядит странным (HTML это код шаблона, а не контроллера). Контроллер у тебя создаёт PDO, лучше бы передавать в контроллер сразу AbiturientGateway. Контроллеры в студентах необязательно делать классами, хватит двух скриптов list.php и form.php, которые будут разбирать HTTP-запрос, обращаться к модели и в конце подключать шаблон. Валидировать студента - не ответственность Gateway, нужно вынести валидатор оттуда. Мне кажется, что ты не читал пасту про MVC: https://github.com/codedokode/pasta/blob/master/arch/mvc.md Исполняемый файл композера, папки vendor и .idea в системе контроля версий нет смысла хранить, добавь их в .gitignore
>>945940 foreach ($this->css as $css){ $list .= "<link rel = 'stylesheet' href = '". $css ."'>\n"; } бляяя, такого ахуенного подключения стилей прямо в контроллере я еще не видел. просто 10 из 10 говнокод.
Какие-то аноны учат по книгам, кто-то по другим сайтам. Заходите, рассказывайте о том, как учите, к чему стремитесь, и, самое главное, просите помощи, если есть трудности.
Что я могу предложить от себя? На данный момент имеется два с половиной наставника, конференция вконтакте и группа там же. Бесплатно.
Если у вас возникнут вопросы - можете задать их в группе или же в конференции.
Метод POST у тебя тоже должен быть в контроллере отдельно от html, а не во вьюхах. Во вьюхи выводится только хтмл код и переменные, которые ты передаешь во вью через контроллер. Весь код лежит в контроллерах или моделях. Во вью только циклом по массиву, который лежит в переменной, переданной через контроллер, можешь пройтись.
Ты глупости пишешь. Начинающим надо сначала разобраться вообще с тем, как веб-страницы делаются, а браться за фреймворк, не изучив предыдущие темы. По твоей логике и массивы с регулярками изучать не надо, а сразу брать фреймворк и повторять то, что делают в видеокурсе. Так ты научишься только повторять за другими, а не писать сам.
Вообще, твой комментарий тут довольно бесполезный. Лучше бы и не писал.
Он не сеньор с 20 годами опыта чтобы с первого раза все идеально написать. Не понимаю, в чем твоя претензия.
Вы прежде чем комментировать, не пробовали понять, что тут происходит, что это за тред и зачем люди здесь код постят? В ОП посте написано, прочитайте сначала.
>>945997 >Вы прежде чем комментировать, не пробовали понять, что тут происходит, что это за тред и зачем люди здесь код постят? В ОП посте написано, прочитайте сначала. Да я не придираюсь, просто мне было бы реально интересно понять ход мыслей - зачем в объекте хранить подключение таблицы стилей. А так у него типичная проблема неофита -понимание MVC.
>>946005 На пхп очень много всего написано. Куча ORM, фреймворков и т.п. А на питоне? Собственно питон же и не заточен чисто на веб, а вот пхп полностью, того он в нем и доминирует, ничего странного.
>>946011 Но на пистоне можно писать все то же самое, что и на пхп, только в разы изящнее. Еще руби есть, он например тоже заточен только под веб. Все дело в говноедстве пидорах, эти тупые уебаны без чувства прекрасного будут еще сто лет форсить убеанскую хуйню, типа 1С или хостинга всего и вся на шинде и аспе. Эта тяга к безвкусице и некрасивым решениям, костылям и говну уже в крови.
>>946013 >Но на пистоне можно писать все то же самое, что и на пхп, только в разы изящнее. Так бери и пиши, в чем проблема? Вот когда будут полноценные альтернативы симфони, доктрины, зенда и прочего - тогда посмотрим, может пхп и зафейлится. Понимаешь, "изящность" это ну очень мутное преимущество. Я например не перевариваю snake-case и табуляцию как часть синтаксиса. >Еще руби есть, он например тоже заточен только под веб. Руби ВСЁ, официально.
>>945987 джанго говно каждый школьник в своем тех.пту учит, а потом эти толпы после выпуска со знаниями одной джанги валят на рынок труда и переполняют его.
>>945997 Я сам учился кодить в этом треде и сейчас уже джуном работаю, но даже я на начальных этапах начинал с верстки и таких ошибок в мвц не делал. он даже мвц толком не написал, а создал какого-то монстра, мог просто погуглить статьи о мвц и ПОВТОРИТЬ простенький апп-бутсрап.
Что надо использовать на яваскрипте, чтобы при наведении мышки на ссылку показывалась одна из картинок, которая находится по этому адресу?
1. Если это ссылка на другую страницу этого же сайта, но адрес на картинку недоступен на этой страницы из запроса к базе данных. 2. Если это ссылка на другой сайт.
Я так понял тут нужны какие-то парсеры чтоли, но как их делать на яваскрипте?
у нас на работе кстати работает джунша с вышкой тех.вуза, которая не знает, как делать мвц и не может во фреймворки. до сих пор все ручками пишет и ведь ее говноподелия с уродской админкой впариваются заказчикам. у меня просто глаза вытекли, когда она данные в форме на пустоту не проверила, даже элементарный required в инпуты не поставила. И такой-то шок у меня был после пхп треда, где учили делать самостоятельно мвц и дрочили за отсутствие валидации форм. Зато любит матан и создает рандомные многоугольники через синусы всякие. Еще один пруф, что матанобляди не могут в кодинг
>>946048 на всем, чему учат в вузах, нет работы, потому что там программа устарела лет на 50. еще спроси, почему нет работы для паяльщиков микроконтроллеров, хотя этому учат в вузах.
ОП, может лучше на Доброчане тред создавать? Или создавать 2 PHP-треда, в одном - задачки и ответы, во втором пусть люди обсуждают важность ВО, а управленцы будут унижать кодеров. До 500-го поста в треде один трём ни о чём.
>>946070 >кодинг последний вагон уходящего поезда возможностей Щито? У тебя какой-то неправильный манямирок. Кодинг это сознательный выбор, никакого хайпа. Короче, не вижу смысла дальше общаться с тобой, укатывайся на софтач траллировать.
Сириусли единственная причина проебать 5 лет в вузе - это если у тебя родоки богатые, они готовы тебя кормить пять лет и еще и за вуз доплачивать. А также ты хочешь 5 лет пропинать хуи, поебывая однокурсниц и ходя на общажные вписки. Все. Т.е. это просто такая дыра, куда ты должен убить 5 лет своей жизни только потому, что работодатели не любят нанимать малолеток до 23 лет ибо они нестабильны из-за гормонов и амбиции через край.
>>946110 Но ведь работодатели любят нанимать малолеток. Сейчас придешь в контору 22+ - сразу начнутся подозрительные взгляды - а где вы до этого хуи пинали?
>>946178 Если тебе тяжело понять это, советую потратить денек на http://nnmclub.to/forum/viewtopic.php?t=1046622 второй курс, 1-4 уроки. Только я например так и не понял зачем он там синглтоны пихает, но MVC поясняет очень хорошо. Да, я знаю что смотреть курсы - тупиковый путь, но там просто лектор реално хороший.
1) Весь код содержится в контроллере. 2) В view содержится только html с выводом необходимых переменных. 3) Вызывать view через include(файл) в контроллере - это нормально.
>>946184 В моделях содержится вся работа с данными. Вьюхи, понятно, чисто для рендера. Контроллер как связующее звено между всем этим выступает. Вьюха дергает контроллер - контроллер дергает модели (а может и не дергать) - контроллер дергает вьюху какую-то, чтоб та отрендарилась и так до усеру. Стоит заметить, что это вебовское mvc, каноничное вообще не так работает, а тут это скорее mvp напоминает.
> контроллер дергает модели (а может и не дергать)
Это понял.
>контроллер дергает вьюху какую-то, чтоб та отрендарилась Тоже понял.
>Вьюха дергает контроллер А вот это - не совсем. Вью же отвечает только за отображение информации, райт? Она не должна трогать контроллер, разве что в плане получения из него каких-то данных для рендера.
>>946184 Ты совсем не понял. MVC не значит, что у тебя должен быть определенный набор файлов, скриптов, это логическое разделение кода. Контроллер - это часть кода, куда попадает запрос пользователя. Он обрабатывает запрос и передает необходимые данные модели. Модель - это код отвечающий за всю логику приложения считай. Вычисления, сущности, операция с БД - это все модели. Сама по себе данные для работы она получает только из контроллера(запомни, это важно). Получив необходимые данные модель отправляет их контроллеру, тот уже подключает шаблон(через include например). Как-то так. >>946187 Котнроллеры должны дергать всякие методы. Модель и вьюха живут отдельно и не знают о существовании друг друга.
>>946187 Ну это я образно, типа жизненный цикл запроса описал с учетом, что страница в браузере это уже отданная клиенту вьюха. Ну да, технически это не вью, я выразился так просто. Давай по новому, клиент делает запрос откуда то, твое приложение его роутит и он приходит на контроллер, контроллепр работает с моделями и сам чет делает, что считает нужным (логику работу с данными, однако, ты инкапсулируешь в модели), в конце концов контроллер отдает какие-то данные вьюхе, та их использует для рендера статики, ну а статика уже выплевывается обратно клиенту.
Есть альтернативы мануалу по YII2 на русском языке? На рутркере в топе Сафронов М. - Разработка веб-приложений в Yii 2, но ее не очень хвалят в комментариях.
Я с довольно дурацкой проблемой пришел, прямо затупил в этот раз. Есть уже большое приложение с рест апи, все как всегда. Но один из маршрутов возвращает кириллицу в виде "????". Весь проект на utf-8, вся база в utf8-general-ci. Откуда по совершенно такому же гет запросу, как и остальные, вдруг меняется кодировка ума не приложу. (жизненный цикл абсолютно одинаков для каждого гет запроса) Во время выполнения самого приложения вплоть до отдачи из контроллера данные в нужной кодировке находятся. Вот такие дела. С учетом этого можно все это обойти просто сделав эхо прямо из контроллера, но хотелось бы все же понять в чем дело то может быть.
Не, контроллер нужен для того, чтобы принять запрос от браузера, вызвать нужные методы модели и затем вызвать вью чтобы отобразить результат. Ну например, запросить у модели список студентов,а затем вызвать вью, чтобы отобразить его.
> Вызывать view через include(файл) в контроллере - это нормально. В общем, да.
>Вьюха дергает контроллер - контроллер дергает модели (а может и не дергать)
Не, такого нет. Бывают архитектуры, когда вью вызывает методы модели, чтобы получить у нее какие-то данные, но в вебе обычно это делает контроллер и передает полученные данные во вью, а оно только их отображает.
Нельзя вызывать контроллер, это не модель, чтобы кому-то какие-то данные предоставлять.
Контроллер просто принимает данные от браузера (например, анализирует GET/POST) и затем вызывает модель и вью.
> Сама по себе данные для работы она получает только из контроллера(запомни, это важно). Получив необходимые данные модель отправляет их контроллеру Не совсем так. Правильнее сказать, что контроллер вызывает методы модели, чтобы получить какие-то данные или изменить их.
Условно говоря, модель содержит всю логику приложения, кроме вывода данных (это задача вью) и приема HTTP запросов от браузера (это работа контроллера). То есть любое действие в приложении можно сделать программно, вызывая методы модели. Хочешь получить список студентов? есть такой метод. Хочешь найти студентов по ключевому слову? Есть такой метод. Хочешь добавить нового студента? Есть и такой метод. То есть имея только модель, ты можешь программно (вызывая функции) делать все действия, которые доступны в приложении. Или, если перефразировать, для любых действий, которые доступны в приложении (просмотр, поиск, регистрация), есть методы модели, которые их выполняют.
>>946246 А ты про что именно? Если про переменные с постами, то они для шаблонизатора, который их потом раскидывает по виду. Сами посты я получаю из модели, контроллер только отправляет их шаблонизатору.
>>946249 Я про вот это. >public function __construct(Post $posts, Tag $tags, Attitude $attitude) Я конечно не знаю что ты хочешь там вообще сделать, но по идее ты должен внутри контроллера получать из модели посты, не? А так ты выходит получаешь где-то посты, потом передаешь их в контроллер. Со стороны выглядит как грубое нарушение принципов MVC.
>>946270 Не, это какая-то ларавелевская хуйня, так уже было из коробки Я так понял, она получает класс модели, чтобы создать из него объект, который присваивается свойству внутри контроллера, чтобы потом получать доступ к методам модели через это приватное свойства конструктора. Можно в конструктор ничего не передавать, тогда в модели методы должны быть статичными, чтобы обращаться к ним без создания нового объекта из класса модели.
Это кривой код, он толком сам не понимает что представляет собой объект Post и что надо передавать в контроллер. Просто где-то что-то похожее видел и бездумно написал по аналогии.
У тебя вообще код странный и такое ощущение что ты сам толком не понимаешь что пишешь.
В Eloquent объект Post представляет собой один пост, а для работы с таблицей постов в целом используются статические методы. Найти пост - статический метод. Изменить заголовок поста, проверить пост - обычный.
> return $this::where
Так не пишут. для вызова статических методов используют self::
Ну вот давай посмотрим на этот метод поиска поста по id:
> public function getPost($id)
Это не статический метод. Чтобы его вызвать, нам надо иметь объект класса Post, который соответствует одному посту в БД. То есть чтобы вызвать getPost (и найти пост в БД), мы должны сначала загрузить из БД объект поста. Ну бред же, как ни смотри.
Та же проблема с нестатическим методом forUser. Получается чтобы найти все посты пользователя, мы должны сначала загрузить какой-нибудь другой пост. Ну и вообще, этот метод наверно логичнее бы смотрелся в классе User. $user->findPosts(...)
> public static function getPageCount(User $user) Неправильное название функции, она считает не число страниц, а число постов. Опять же, возможно ее логичнее в класс юзера поместить. Я не знаю, как в ларавел принято это делать.
> public function setPost($request, $post) Почему у тебя модель работает с запросом? Это задача контроллера.
> public function countPages($request, $posts_on_page, $this_page) Эта функция вообще непонятно, что делает в этом классе. Вот смотри, простой пример: допустим ты захочешь сделать пагинацию для еще каких-то сущностей, тебе придется скопировать в тот класс весь этот код. Очевидно, что его надо вынести в отдельный универсальный класс, а не копировать в каждую модель.
Далее, про класс Attitude. Во-первых, у него неправильное название, не Attitude, а Relation. Во-вторых, Relation тоже неправильное название, так как не говорит, связь чего с чем представляет это класс, правильно PostToTag или PostTagRelation, как-то так.
В общем, впечатление пока плачевное. Пока ты своим кодом показываешь что ты даже не пытался разобраться в фреймворке, который используешь, на каких принципах он построен. Ты просто пишешь код по аналогии с где-то увиденным (в видеоуроке?) не читая документацию и не понимая, что он значит. Ну и статические методы с обычными путаешь. Я бы такого кандидата отправил домой читать документацию.
Вот там был выше анон, который написал глупый комментарий вроде "зачем тратить время на написание задачи про студентов с нуля, бери фреймворк". Вот когда сразу берут фреймворк, получается такой результат.
Потому, что для проверки уникальности email надо обращение к БД (через объект StudentDataGateway). В модели такого объекта нет. Также может потребоваться обращение к каким-то другим сервисам. Поэтому валидатор логично сделать внешним по отношению к модели сервисом.
>>946192 Я не ОП, но вот основные, на мой взгляд, проблемы:
Вызывает вопросы сама архитектура приложения, код очень плохо разделен, у тебя в одном файле смешана верстка, SQL запросы, валидация и сама логика приложения. Ты видимо не совсем понимаешь как должен выглядеть нормальный MVC проект, попробуй поискать примеров и перечитать уроки ОПа.
По стилю кода тоже возникли вопросы, у тебя имена методов и переменных написаны снейк кейсом, код оформлен не по стандартам, почитай второй пост в треде, у нас есть стандарты PSR-1 и PSR-2.
Обработка ошибок сделана неправильно, ты поставил PDO в режим исключений, но потом при запросе ты все равно почему-то делаешь проверку https://github.com/grigoryMovchan/auth/blob/master/php/module.php#L18 Если у тебя PDO стоит в режиме исключений, этого делать не нужно, при любой ошибке БД PDO выбросит исключение, которое ты потом сможешь обработать как хочешь.
>TODO: вынести валидацию формы на фронт с помощью AJAX Это сделано очень неудачно. Мало того что у тебя в коде две разные валидации (одна обычная, другая для аякса), так ты еще хочешь оставить только аякс, чтобы у пользователей без JS совсем ничего не работало. На мой взгляд это неправильный подход. Я бы сделал отдельный класс или метод для валидации данных которые пришли, этот метод возвращал бы массив с ошибками типа ['имяПоля' => 'текст ошибки'] (или пустой массив если все хорошо). Затем использовать один и тот же метод при аяксе и при обычной отправке формы сабмитом. В случае если запрос пришел аяксом, отдаешь JSON с массивом ошибок, если при обычном сабмите формы - показываешь пользователю ту же форму с ошибками.
Но правильнее передавать в вью не склеенную строку, а коллекцию тегов, а оно пусть делает с ней что хочет.
Дальше, редактирование у тебя сделано в виде 2 методов:
> public function edit(Request $request, Post $post) > public function save(Request $request, Post $post)
При таком подходе, как ты сделаешь обработку ошибок? Вот пользователь заполнил форму неправильно, мы должны показать ему эту форму и сообщение об ошибке. Но в твоем варианте с редиректами введенные в форму данные просто потеряются. Тебе надо почитать про алгоритм обработки форм: https://github.com/codedokode/pasta/blob/master/forms.md
У тебя даже валидации нет. У тебя можно отправить форму с пустыми полями.
Поиск отсутствующих/новых тегов надо было делать в модели. ты похоже не понимаешь идею MVC и кто за что отвечает. С твоим кодом, если мы захотим где-то в другом месте поменять теги поста, нам придется копипастить код из контроллера так как повторно его вызывать из другого места нельзя.
Вообще, тебе надо сделать задачу про студентов и почитать комментарии к ней (в ОП посте). Ты взялся за фреймворк, не изучив много более базовых вещей вроде валидации или работы с формами.
Насчет валидации, в Юи можно прописывать правила валидации в модели и там один и тот же код обеспечивает валидацию и обычного POST-запроса и аякс-валидацию для отдельных полей. Я подозреваю, в Laravel тоже есть какое-то готовое решение для работы с формами и валидацией и надо использовать его.
>>945059 (OP) Первый раз вижу чтобы фреймворк из коробки не работал по гайду, это я об Slim v3, всегда 404 ошибка, /hello/lorem не отрабатывает вообще, об htaccess вообще речи не идет в их официальном installation guide. Полазив в инете единственное, что понял - популярность этого фреймворка довольно низкая, так как нет абсолютно ничего, ни рабочего примера нигде, ни гайдов нормальных, комьюнити нет совсем. Зачем на нем писать fileshare ?
>>946318 https://github.com/slimphp/Slim#usage Вот же есть раздел про использование, там пример с встроенным в PHP веб-сервером (на котором URL Rewrite работает из коробки), а про другие веб сервера написано >For more information on how to configure your web server, see the Documentation. С ссылкой на нужный тебе раздел в документации.
на зло всем троллям приятно, что пхп не тонет и не умирает как язык. За год я овладел пхп, нодой, питоном и сейчас учу руби, но пыха всегда будет в моем сердце как что-то простое, понятное, но от этого ничуть не менее эффективное.
>>946308 Спасибо, очень отрезвляет, много ценных замечаний. Понял, что работу мне еще рано искать, буду дальше учиться.
>Пока ты своим кодом показываешь что ты даже не пытался разобраться в фреймворке, который используешь, на каких принципах он построен.
Вот тут я не верю что есть человек который может сесть и не разбираясь что-то написать на нем. Там же свой уровень абстракции. Я месяц делал эту поделку, до нее сделал похожую на чистом MVC https://github.com/grigoryMovchan/blog_mvc Старался внимательно читать официальную документацию, видео уроки обхожу стороной. Да, месяца мало, но вот чтоб говорить что я не пытался разобраться и не читал документацию, тут у меня бомбит.
>>946312 Спасибо. Да, это не MVC, скорее просто поделка в процедурном стиле с использованием классов, чтобы потом использовать в другой поделке, которая уже будет в MVC. Поэтому сори что запутал. Про PDO ценные замечания.
>Это сделано очень неудачно. Мало того что у тебя в коде две разные валидации (одна обычная, другая для аякса), так ты еще хочешь оставить только аякс, чтобы у пользователей без JS совсем ничего не работало. Стандарты PSR-1 и PSR-2 почитаю.
Тут я косноязычно выразился. Я хотел не вместо, а дополнительно ее сделать. Про один класс для валидации ценное замечание.
Куки использую чтобы снова не проходить аутентификацию, когда время сессии выйдет, а вот зачем тогда сессии использовать я не знаю, часть кода взял из урока. Возможно, и правда не нужны.
>Поиск отсутствующих/новых тегов надо было делать в модели. ты похоже не понимаешь идею MVC и кто за что отвечает. С твоим кодом, если мы захотим где-то в другом месте поменять теги поста, нам придется копипастить код из контроллера так как повторно его вызывать из другого места нельзя.
Тут не понял, ведь все методы для работы с тегами в моделях Attitude и Tag.
> Ты взялся за фреймворк, не изучив много более базовых вещей вроде валидации или работы с формами. Опять я ничего не знаю. Не представляю чтобы кто-то без этих базовых представлений сходу мог написать что-то на ларавел без опыта в других фреймворках.
P.S. Еще раз спасибо, господа. Все замечания взял на заметку. Впереди предстоит объемная работа. Исправлять эту поделку на ларавел я уже не буду, но в будущем, постараюсь сделать лучше.
>>946377 >Вот тут я не верю что есть человек который может сесть и не разбираясь что-то написать на нем. Там же свой уровень абстракции. Я месяц делал эту поделку, пиздец, я уже и забыл, как сложно первое время вкатываться. код плох на уровне смешения хтмл и кода. посмешила папочка с названием пхп.
няши, а почему у меня, например, по ссылке localhost/admin/blabla грузит блабла.пхп в потом снизу нее еще догружает после футера, типа две страницы на одной и индекс для адреса localhost/admin? в роутах: 'admin/blabla'=> 'admin/blabla', 'admin'=> 'admin/index'
>>946077 Предлагаю топить тред сразу сажей на дно. Заметили, что активность долбоёбов критически возрастает в начале каждого треда, а далее идет на спад, после бамплимита? Если бы у нас был доступ к модератору, то можно прикрепить для новичков тред в шапку и обновлять ссылку с каждым перекатом.
А то сидит завсегдатай такой, ковыряет в носу, рефрешит - "о бля! свеженький анимешный пэхэпэ тред, зайду ка посру..."
Аноны, нужна помощь. Делаю свой первый сайт, вот встал вопрос насчёт корзины, можете, пожалуйста, подкинуть линк на годный гайд/видео как мне это реализовать и с помощью чего(PHP или JS, или то и то), не могу определиться, спасибо.
>>946495 Не подкинешь инфы, если не тяжело? В PHP я полный 0, JS хоть как-то понимаю и то начал относительно недавно изучать его. Если всё это дело лучше написать будет на PHP, то буду значит разбираться. Спасибо за ответ.
Скорее всего наивный вопрос, но, где можно посмотреть исходник больших проектов(коммерческих желательно), чтоб узнать как там у них работают всякие функции и прочее
>>946567 Php, в нем ООП стандартный и нет callback hellа. В JS без опыта в нормальном ООП языке ты увязнешь и не будет понимания в голове, что и как работает, не будет понимания паттернов, наследования, разделения ответственности. JS лучше учи после, будут отличия от нормальных языков понятны.
Но она вроде относительно популярна и даже продается.
Ты бы мог обратить проблему ("тормозит") себе на пользу - учиться на примере этой CMS оптимизации и профайлингу, выяснить источник тормозов, понять, это принципиально неустранимая вещь или просто где-то кеширование не настроено.
> в языках вроде Ява эта проверка делается одним тайп-хинтом вроде Map<int, DepreciationInterface>. Ещё классы DiscountCollection и DiscountResult служат только ради тайп-хинтов.
>>946697 Трейт это инструмент для реализации множественного наследования. Чтобы ты мог два класса унаследовать от разных классов, но при этом в обеих классах реюзать один и тот же код.
Интерфейсы и трейты - абсолютно разные вещи. Первое - это контракт, не содержащий никакой реализации. Трейты (миксины) удобны когда нужно добавить классу какое-то поведение. Например, поведение объекта, который может генерировать события и оповещать слушателей: https://learn.javascript.ru/mixins
ИМХО, по возможности стоит предпочитать внедрение зависимости трейтам, так как зависимости можно подменить, а вот трейты вбиты в класс намертво.
ОП или аноны, выручайте. Скачал книгу по PHP 7 Дмитрия Котерова (2016 год). И в учебнике выводят на этот сайт http://windows.php.net/download Это так называемая "установка" Php определенной версии скачал седьмую. Что она дает вообще? и нужна ли она мне на этапе изучения? так как там вообще не особо об этом расписывают Как редактор скачал sublime text 3. Этого достаточно или еще что-то нужно?
>>945059 (OP) Посаны, а в фильтрах для uBlock пхп или нет? Мне, короче, надо знать как в них поставить вместо символа переменнную, чтобы там был диапазон значений. То есть вот есть у меня 10 строк, которые отличаются только одной циферкой - хочу вместо 10 сделать одну. Звёздочка почему-то не работает. Может её в какие-нибудь сраные скобки надо заключить или типа того? Причём в строках, когда меняется целое... слово (наверное, хуй знает как это называется) она работает, например - ||yastatic.net/morda-logo/i/cards/8march2017/enter/.png$image А когда надо поменять только его часть yandex.ru##.b-cards__enter_bg_*.b-cards__enter_8march2017.b-cards__enter уже нет.
год работал на чистом пхп люблю содомию задумался об изучении фреймворков и смене рабочего места. На русском рынке сейчас самый популярный - симфони? просто мне больше нравится йи.
>>946765 Блять, ебучая макаба, посчитала звёздочки элементами разметки. Первая строка должна выглядеть так - ||yastatic.net/morda-logo/i/cards/8march2017/enter/*.png$image
>>946768 На русском как раз самый популярный ЙИ. Если смотреть глобально, то наверное топ 1 по популярности - ларавел. Симфони вряд-ли где-то в топе, слишком навороченный фреймворк.
>>946496 "Столько инфы" усваивают только бородачи-профессор. А на уровень тутошних знатоков можно выйти за пару лет. Просто у нас кодеры получают сравнительно дохуя, вот они себя илитой и считают. Смотрел на западных кодеров - там разница в зарплатах не такая значительная, от того эти ребята в среднем менее упоротые, и комунити там гораздо более добродушное, серьезно. Просто если почитать наши ресурсы типа хабры и доу - складывается впечатление, будто погромисты все поголовно озлобленные, чсвшные мудаки, еще и делают все возможное что бы затопить новичков потому, т.к. боятся что наплодится конкурентов и начнется демпинг зарплат, а кроме как кодить они нихуя не умеют. Даже тот же стековерфлоу как ресурс для неофитов гораздо более дружелюбный, чем бОльшая часть ру-комунити. А проблема этого ИТТ треда скорее в мочерации, точнее ее отсутствие. >>946764 >Скачал книгу по PHP 7 Дмитрия Котерова (2016 год). Выбрось это, лол. Котеров и Костарев это просто легенды говнокодинга. Лучше по учебнику ОПа занимайся.
>>946792 Что значит чистый пхп? Фреймворки не на чистом пхп написаны? Фишка в том, что для того, чтобы решить более-менее определенную задачу, то тебе надо либо использовать либо фреймворк, либо cms, либо писать свой велосипед, который по сути будет таким же фреймворком. Естественно, пилить свой велосипед, когда все уже давно сделано до тебя очень глупо. Поэтому использовать фреймворк это умное решение - вопрос лишь только в том какой тебе подходит для твоей задачи. Если под чистым пхп ты подразумеваешь работу вообще без какого-либо паттерна, архитектуры и прочего, то максимум для чего такой "чистый пхп" подходит - это написать файлик-скриптик для генерации капчи или гостевой книги. В 2017 это нафиг никому не нужно.
>>946792 >Нужно ли сразу вкатываться на фреймворки? Лол. Это просто такой платиновый вопрос, что ОПу давно пора его жирный курсивом в ОП-посте добавить. Даже в этом треде уже было это. Поясню по хардкору - нив коем случае блять. Да, на чистом пхп чаще всего не пишут. Однако если ты хочешь именно стать разработчиком, тебе надо знать и уметь применять все принципы, которые лежат в основе пхп-фреймворков. А именно, помимо синтаксиса пхп тебе надо хорошо, именно что хорошо понимать ООП - зачем оно надо, основные фишки и плюсы которые оно дает. А так же MVC, ORM, и PSR желательно - а то увидишь, допустим, в документации фреймворка что такой-то класс реализует интерфейс из PSR-7, и начнется тупняк у тебя, пока не полезешь в гугл и не узнаешь что за PSR-7 такой. Вот когда хорошо разберешься в этом, напигешь пару MVC-бложиков, тогда уже можно и за фреймворки браться.
>>946787 Так что все-таки дает этот сайт http://windows.php.net/download Вроде как на пхп.нет что-то важное должно быть Я распаковал архивы и ничего полезного там не вижу как новичок
>>946810 какая у тебя задача-то? если установить локальный сервер на винде, то есть либо openserver, либо xampp.com, либо если хочется установить самому, есть урок от ОПа в шапке.
учебник Котерова определенно надо сжечь, намного лучше учиться хотя бы по тем же урокам в шапке.
>>946830 >учебник Котерова определенно надо сжечь, намного лучше учиться хотя бы по тем же урокам в шапке. Двачую. Там в предисловии указано на то, что учебник не для самых новичков, а для тех кто хотя бы поверхностно знаком с алгоритмизацией. Хотя я паскаль изучал давно и основы помню, но ничего не понимаю по его учебнику
Если я хочу сделать на сайте авторизацию через соц сети через API, функцию авторизации лучше закинуть в класс пользователя, или выделить отдельный класс, который управляет пользователями?
Есть абстрактный класс Controller, в нем метод render() (ну понятно, что там шаблон включается с переданными параметрами). Есть унаследованный от него контроллер страницы, где я вывожу <?=Student::GENDER_MALE?>. Так вот, интерпретатор говорит, не видит класса Student, хотя я использовал use для него в дочернем контроллере. Думал, так как метод родительский, то и импортированные пространства имен тоже от родителя – там прописал use ...\Student; все равно не работает, а если в шаблоне абсолютный путь (имя с неймспейсом) до класса, то все прекрасно. В чем проблема? я так понимаю, require_once просто включает содержание файла шаблона, как будто он там и был, и следовательно у шаблона должен быть доступ к импортированным пространствам дочернего контроллера и все должно быть ОК. Где я не прав?
>>946853 У меня кстати похожий вопрос. Есть у меня класс View(), который зависимость для контроллера. Однако там только метод display который просто передает параметры и инклюдит шаблон. Что бы еще такого в эту вьюху добавить? Что обычно в фреймворках там есть? Просто не хочется пока фреймворки вообще трогать.
У меня в линуксе нет пхп. Как его установить? apt-get install php? А модули как подключать, как подключить фреймворки, как запустить чтобы это всё работало на внешнем айпи или локалохосте?
Анон, как работает preg_replace? В некоторых случаях он вычленяет что-то из третьего аргумента и вставляет во второй, а в некоторых вычленяет что-то в третьем и заменяет это вторым аргументом. Когда что он делает?
>>946768 как можно работать на чистом (!) пхп еще и год. откуда вы такие беретесь? тут с тремя яп и 10 фреймворками хуй устроишься, а они ни чистом пхп работают. ахуеть
Просто сделал на фл.сру заказ лендинг для небольшой компании, потом разговорились, подружились, вышло, что они из города, в который я поступил учиться, и я с ними остался. За год сделал какое-то подобие фреймворка своего, за теми отличиями, что у меня это хуево реализованная мешанина того, чтотя использую чаще всего. Короче, мне норм.
>>946982 На больших фирмах как раз выкидывают эти твои фреймворки и пишут на чистом php. Фреймворк - зависимость от разрабов фреймворка и тормоза, большим фирмам не нравится. А вот мелким как раз.
Понимаю, что не там пишу, но все же есть вероятность, что кто-то из вас юзает Linux. С чего начать изучение Linux?если я его никогда не юзал, все жизнь пользовался виндой,
>>947203 по счастливой случайности я скроллил /pr и заметил твой пост. Ну, вообще в идеале, попробуй запилить виртуалбокс и в нём эмулировать Убунту. Самая хорошая для изучения линукса. Плюс, неплохо бы комбинировать с знаием Си. Хотя там и неплохая поддержка Питона есть. Вообще-то я не помню, что именно можно спокойно компилировать из терминала в Убунте. Но вот потом с помощью "help" изучай утилиты терминала. Поиграйся с файлами. Почитай пару гайдов по Bash. Ну и пиком будет установка стороннего приложения, например шиндосовского. Особенно с помощтю Wine.
>>947216 >никогда не юзай десктопный линупс Это почему? Я с 2010 юзаю генту, все ок. Оче легко создать среду для погромирования, будь то пыха, руби, да что угодно. Кресты вообще по умолчанию встроены, благодаря особенностям генты.
так я летом заработал тогда, а на что тратить деньги долбоебу-домосиду? Купил книг и это. Игрулечки в печенках уже тогда засели, хавчик я тогда ограничивал, чтоб похудеть.
А зачем? В смысле, нормальный фреймворк писать. Я сделал то, что помогло мне сократить время разработки без лишних танцев с бубном вокруг компа, чтоб было лишнее время на изучение английского языка. Теперь вот.
>>947203 Ставишь эмулятор vmware или virtual box, накатываешь mint linux или другой популярный дистриб, проходишь всю инсталляцию. Потом гуглишь как ставить там php, apache, виртуальные хосты, все настраивать. Гуглишь руководство по основным командам bash. Запускаешь апачу с пыхой, делаешь так чтоб сервак из винды видно было по ip. SSH еще с FTP осваиваешь до линукса из винды, cron для запуска скриптов. Можно еще какой-нибудь Docker попробовать. В принципе все, больше тебе обычно ничего не требуются при типичной разработке. Усилий не так много, за пару недель легко осваивается.
>>947292 >А зачем? В смысле, нормальный фреймворк писать. Нормальный не значит, что там фич овердохуя, просто что нормально написан - все разделено на отвечающие за свои роли классы, везде зависимости через dependency injection, юзается наследование и соблаюдаются SOLID принципы. Зачем надо? Просто потом ты этот фреймворк уже понимать будешь и в любом новом проекте просто его заюзывать. А если нормально написан, то и код сразу везде чистый станет без проблем с расширением и поддержкой. Сейчас это тебе неочевидно, но время действительно экономится будет, особенно когда требования заказчика на ходу меняются. Если у тебя кривой плохо расширяемый фреймворк с говнокодом, то ты и дальше в нем будешь не пойми что городить, проблем будет только прибавляться с увеличением сложности проектов, а с ними и временных затрат на любые изменения.
>>945059 (OP) Хочу быстро вкатится в погромирование, до этого писал хелло ворлды с циклами на крестах всего-лишь, и немного долбился в ассемблер с флагами там и регистрами. Хочу на галерку, грести, хоть за копейки и погонщика за спиной, чтоб мотировал. Я в тот тред зашел?
>>945059 (OP) У Godaddy толи цены сменились, толи меркетинговый ход с ценами. Сегодня посмотрел выставленный счёт на оплату. И получилось овер 16к рублей. Это за продление 1 домена на 12 месяцев и эконом хостинг на линуксе. Учитывая что за весь прошлый год я заплатил тыщь 6, то тут прямо таки странная картина. Если в треде есть кто может подсказать по вопросам буду рад. Можно ли домен перенести на нового хостера и как это сделать? Будут ли с этим проблемы? Как поступать с оплатой? Тоесть сейчас я плачу за продление Godaddy и не парюсь, а дальше платить новому хостеру? Как платить если у меня ещё пол года осталось и я боюсь что после того как домен закончится, его перехватят сквоттеры?
>>947412 Да все тоже самое. Може попробовать фриланс за еду и опыт? Но как-то совсем страшно, тем более я так понял там везде надо CMS-ки, а я ни одной не знаю. >>947414 Меня больше порадает набор технологий. Я раньше думал, что пхп-разработчик кодит только пхп, а судя по всему еще и жс надо знать хорошо, и верстать клево.
Или вот еще вакансия. Чисто интересно, кого они блять вообще ищут? приглашает кандидатов на должность ВЕБ — ПРОГРАММИСТ
Требования:
о/р от 3 лет; желательно высшее техническое образование; знание языков html, php, css; умение работать с Mysql, Apache; навыки работы с CMSWordpress, Joomla, OpenCart (создание сайтов, настройка); кроссбраузерная, адаптивная верстка; умение работать с графическими редакторами (Photoshop, CorelDRAW, Illustrator); понимание и навыки в SEO и SMM продвижении сайта; работас Google analytics, Google AdWords; предоставление портфолио. Преимуществом будет:
знаниеJava Script/JQuery/AJax, ASP.NET; навыки копирайтинга; опыт работы с облачными платформами (WIX, WEEBLYи др.); опыт работы с торговыми площадками (prom.uaи др.); работа с системой Moodle; системное мышление, опыт работы с системами мониторинга и сбора данных; умение пользоваться поисковыми системами для нахождения решений. Обязанности:
Обновление дизайна, верстка отдельных страниц сайта.
Разработка графических элементов, баннеров.
Использование рекламных каналов. Продвижение сайта в поисковых системах. Сопровождение сайтов на платформе WordPress.
Техническая поддержка и администрирование сайтов.
Разработка дополнительных модулей для сайтов.
Обеспечение интеграции сайтов с внешними системами (CRM, 1С, мобильные приложения).
Выполнение задач по модернизации и развитию сайтов своими силами и с помощью подрядчика.
Усовершенствовать и поддерживать ecommerce.
Просьба ВНИМАТЕЛЬНО читать требованияи присылать резюме только при соответствии ВАШИХ практических навыков указанным требованиям минимум на 80%.
>>947419 Верстать вообще не сложно. Вот как раз изучи вёрстку, хтмл сначала, может и понравится. Вкатиться во фреймворки и кмс тоже не сложно. Главное не лезть в жс с вебпаками. И обычно только в мухосрансках такие охуевшие, где нужно быть фулстеком. На фрилансе тебя никто не будет просить верстать или делать жс плюхи, для этого есть фронтотяночки
>>947421 Это охуевшие мрази, которые не шарят и хотят всё и сразу. Можешь прийти к ним на собеседование и прямо сказать - вы охуевшие мрази, идите нахуй.
>>947422 Да я то верстать кое-как умею, но без каких-либо хитростей вообще. >>947423 Меня вот интересует, а зачем они вообще столько всего пишут в требованиях? Даже моих скилов хватает, что бы понять - вакансия говно. При том что для мидлов-сеньоров вакансии нормально у меня выглядят.
>>947411 Короче, твой путь - учишь пхп, учишь хтмл, учишь парочку фреймворков -> пишешь пару своих сайтов с пользователями, борду, чатик, магазин, набиваешь первичный опыт -> идешь на фриланс, ищешь простые типовые задачи, типа сделать несложный магаз на всяких уиихах и ларавелях -> получаешь свою копеечку и радуешься жизни. Конечно, сразу это не придет, придется хотя бы полгода хорошо все изучить, и не лениться, тратить на это все не меньше пяти часов в день, а не полчасика на туториалы и дальше в дотку. Так не пойдет. Нужно работать. А когда ты дома и тебя никто не гонит, это совсем не сложно. Все получится, няша.
>>947431 Да я как-то так и думал. Щас где-то на середине студентов. Алсо поясните еще такую фишку - часто говорят, что не стоит начинать карьеру с CMSок, типа это тупиковый путь и все такое, надо искать работу на фреймворках. В чем суть? Неужели все цмс-ки дерьмо такое?
>>947444 Кмски это не программирование, это говно уровня админов на винде в шаражкиных конторах, ты этим заниматься не должен. В пидорахии вообще популярно делать сайты без программирования - берешь вордпресс, ебашишь плагины, натягиваешь на кмс.
>>947445 Я смотрел вакансии с опытом >3 лет, там много работы на ЦМСках. Правда там чаще не вордпресс, а всякие мадженты. И я так понял, там они скорее занимаются разработкой плагинов.
> PageObject Пока гуглил, заметил, что многие понимают PageObject по-разному: кто-то предлагает просто выносить селекторы в объекты со статическими свойствами, кто-то считает, что PageObject должен предоставлять интерфейс страницы, пользователи которого не знают ничего о селекторах и взаимном расположении DOM-элементов. Мне второй вариант понравился больше.
Насчёт теста функции экранирования: > - передаем строку с тегом и проверяем, что на выходе тега нет > - вызываем html_entity_decode на результате и проверяем, что получилась исходная строка > - аналогично можно проверить кавычки, а также отдельные угловые скобки, что их нет в результирующей строке Если правильно понимаю, то второй пункт работает, только если искомая строка не будет найдена. В противном случае результат будет содержать тег b или mark, и исходную строку от такого результата не получим. В общем, сам тест: https://github.com/kubk/students/blob/master/tests/StudentTwigExtensionTest.php#L71
> Насчет авторизации по паролю - лучше в куке (и в БД) хранить не пароль, а его соленый хеш. Чуть безопасней, а так у тебя пароль в открытом виде на каждый запрос шлется. И в базе лежит. Украли базу/куки - и можно идти проверять, подойдет ли этот пароль к почте, к соцсетям итд. В базе был только хеш, а насчёт кук - да, сглупил.
> я бы назвал класс не UniqueEmail, а StudentEmailUnique, так как это ограничение работает только для одного класса - студента. Насчёт универсального решения понятно, но вряд ли оно мне где-либо ещё пригодится, раз доктрина в симфони почти что стандарт и там уже есть UniqueEntity.
Впредь постараюсь быть внимательнее и лучше тестировать то, что отдаю на проверку.
Можно ли как-нибудь в PHP интегрировать ffmpeg? Жутко заёбывает писать там руками в cmd консоли всё, одна опечаточка и радуйся если скажет "ошибка", а не закораптит исходный файл к хуям (такое было, да да я криворук ещё тот).
Вот я специально потратил вчера вечер целый, поставил себе Apache с официального сайта, PHP тоже скачал, добавил как модуль чё-то там, в общем всё работает, хелловорлд все дела (прикольно кстати, я так понял это как настоящий интернет-сервер, по IP зашел к себе с телефона, офигеть).
Так вот допустим я смогу нарисовать формы, там для выбора файлов, всякие опции, которые часто использую, кодеки, тайминг, трим, склейка, ну в общем всё в виде удобных менюшек-переключателей-слайдеров (для домашней коллекции вырезаю из сериалов опенинги, титры, рекламу, лишние озвучки, меняю местами серии и т.п., и так сложилось что с каждым файлом приходится вручную работать, что очень утомительно)
Так вот, получится ли как-то динамически из маленьких таких кусочков составлять привычную команду для консоли и запускать ее из PHP?
ИНБИФО: еще одна макак — НЕТ, "ПРОГРАММИРОВАНИЕМ" ЗАРАБАТЫВАТЬ НЕ СОБИРАЮСЬ, так что если хотите, можете гнать.
Я тут замечаю, что все поголовно ставят апач. Мой вопрос - зачем, когда есть божественный nginx? Его даже развернуть проще намного, чем монструозный апач.
Реально сделать за две недели? Задание на пхп-стажера, 15к. Мимо-вкатывальщик из фронт-енд тредов, до этого верстал и учил JS. За вчера сделал вроде бы на Zend вывод и хранение альбомов, но как делать 4-5 пункт пока неебу совершенно.
>>947458 На вскидку выглядит очень сложно. (Ну то есть из примера Basic usage я не понял ничего). >>947455 >$cmd = "ffmpeg -codecs 2>&1"; >print shell_exec($cmd);
выводит ошибку: >'ffmpeg' is not recognized as an internal or external command, operable program or batch file.
хотя уже давно добавил ffmpeg в PATH и запускаю из любой локации, очевидно для PHP другие правила, нужно где-то зарегистрировать путь к экзешнику? Винда 7 если что.
>>947460 Не знаю, с этим апачем довольно быстро разобрался. А чем именно отличается для тебя nginx? Советуешь на него поменяться?
>>947466 Купи инстанс с центосью и накати энжинкс, в чем проблема? Деплоить не могешь штоле? Обычные линуксы же. Правда не ебу, что такое php-fpm, но гугл подсказывает что это кэширующий сервер, так что поебешься с часок и настроишь из мануалов, ничего сверхъестественного.
>>947466 Это задание нихуя не на стажера. В зависимости от качества реализации на джуна/мидла. Стажеры поидее вообще беспомощные и нихуя сделать не могут. В любом случае не на 15к уж точно. >>947468 >Правда не ебу, что такое php-fpm, но гугл подсказывает что это кэширующий сервер Это менеджер процессов пхп.
>>947470 А что с графической частью? HTML и CSS каждый школьник уже знает, и любую информацию найти легко. Да и нет у меня цели учить какой-то ёба язык. Мне нужно с нуля за пару вечеров то что я хочу получить, и с PHP это симс риал.
>>947478 Так ты делаешь свой локальный сайтек или что? На питоне можно в пару строк поднять фласк-сайтик и тыкать через него биндинги в ffmpeg-консоль. Или тебе нужна консольная приблуда без гуев? Тогда на питоне еще проще и любой школьник сможет написать.
>>947466 Достаточно простенькое. В зенде ебашишь контроллер, вьюхи и редирект на урл, потом чтение из бд и вывод. Настройка nginx c php-fpm в гугле везде описана, тоже ничего сложного. За 2 недели управишься.
>>947483 Поясню окончательно: >тебе нужна консольная приблуда без гуев? я сам заебался в cmd писать все руками, от консоли тошнит уже >На питоне можно в пару строк поднять фласк-сайтик и тыкать через него биндинги Если эти биндинги можно динамически составлять, и весь процесс вкатывания и написания подобного займет не более двух вечеров, и есть хоть одна причина почему это будет лучше PHP, то я хочу быть твоим падаваном, мастер. (а то я вчера задумался, а сегодня уже реализую на PHP первые фичи, и если мне придется начинать заново и ебать очко змеей еще неделю... а нахуя оно мне вообще?) >ты делаешь свой локальный сайтек или что? хочу так: приду я на работу, и в свободное время прямо с телефона зайду, щелкну пару кнопочек, найду нужные фреймы в видео, обрежу, склею, оно сохранится у меня на компе там где я хочу! Быстро. Дешево. Охуенно.
>>947499 > >>947454 по IP зашел к себе с телефона, офигеть утром включил, посмотрел IP, у меня не меняется до конца сессии, так что пока всё нормально с этим.
>>947497 >найду нужные фреймы Вот тут не знаю. Ты собрался вываливать все видео на сайт или как ты вообще представляешь находить нужные кадры? Ну вообще задачи похоже можно даже через телеграм-бота забиндить.
Архитектура же простая - парсить человеческие команды и преобразовывать их в понятную ffmpeg-командную строку.
Вот, например, мой говноскрипт, который отправляет скриншоты с вебки по запросу. Точно также можно намутить что угодно, сделать более сложный парсер предложений.
>Ты собрался вываливать все видео на сайт ну наверное 2 пути: 1) выбираю файл 2) конвертирую в webm с низким качеством 3) через HTML5 <video> смотрю, отмечаю (на бумажке) нужные секунды или: 1) выбираю файл 2) тут придется подшаманить, сделать виджет который позволит конкретный фрейм в виде картинки рипать, то есть как бы все в браузере просчитывается, а потом одна команда отправляется которая покажет где ты сейчас, на каком фрейме. А дальше режу по этим координатам.
>>947512 >Поясни, как это всё работает у тебя? Говноскрипт? Подключаю либы, телеграм-бота. Функция Camera() - делает скриншот, посылая прямую команду в ос через os.system(), на всякий случай обрабатываю возможные ошибки, т.к. если попытаться сохранить через ffmpeg c этим же именем, вылезет бесконечный цикл ффмпега, поэтому предыдущий файл нужно удалить. def echo(bot, update): - стандартная функция обработки сообщений телеграма. if update.message.text == "screenshot' - проверяю текст, если сообщение содержит в себе нужный текст то далее выполняется функция Camera, которая сохраняет скриншот на диске, затем bot.sendPhoto - отправляю скриншот в телеграм. Можно также отправить видео, документы, что угодно. def main():- тут думать не надо, стандартный обработчик бота, который будет крутиться в фоне и обрабатывать входящие сообщения.
Первый путь легко реализовать через sendVideo, отправляешь видео, смотришь, затем пишешь боту что тебе нужно и он выполняет любую команду. Насчет второго пути и быстродействия ffmpeg не знаю, по сути разбить на картинки и выбирать из них удаленно может быть даже медленней чем залить и смотреть тупо видеофайл на странице.
>>947519 Вот статья: https://habrahabr.ru/sandbox/80371/ >Литература >Курсы обучения за деньги >Бесплатные курсы >Через месяц, я смогу написать первое приложение Ну ты понял.
>Насчет второго пути и быстродействия ffmpeg не знаю, по сути разбить на картинки и выбирать из них удаленно может быть даже медленней чем залить и смотреть тупо видеофайл на странице.
Нет, ты не понял, я уже знаю какой фрейм мне нужен (например начинаем с ss 00:00:00.000), поэтому только его присылаю в виде "картинка + тайминг", а дальше средствами PHP делаю определенный шаг назад или вперед, получаю другой фрейм. Так пока не подберется идеальный. В принципе я и сейчас так примерно делаю, только в Free Video Editor, только он сук работает не так как надо, я там смотрю только тайминги и потом руками через консоль вырезаю и т.п.
>>947528 >Вот статья: К чему это? > я уже знаю какой фрейм мне нужен Ну ок, отправляешь картинки определенного тайминга боту. Для более сложной обработки сообщений тебе нужно будет выучить только строки и регулярочки, чтобы вычленять оттуда логические цепочки типа "обрежь от и до", "сделай главной вторую дорожку" и т.д. Это совсем не сложно и будет быстрее, чем писать целый сайт на пхп и в итоге заниматься тем же самым биндингом команд.
Просто бери, разбирайся, делай, в чем проблема вообще. Все предельно ясно.
Это троллинг? Или вы поехавшие? Писать телеграм-бота и гонять данные через полмира только чтобы получить скриншот? Во многих видеоплеерах скриншот делается нажатием кнопки.
Питон не то что бы сложнее, но вся информация по Питону в основном на английском, а по PHP например в ОП посте и в интернете куча информации на русском.
Можно, но это в общем не очень праивльный подход, по нескольким причинам.
Во-первых, уже есть куча видеоредакторов, в которые вложено множество труда. Вряд ли ты в краткие сроки сможешь сделать что-то сопоставимое. Эффективнее будет сделать поискать разные варианты.
Даже если тебе надо просто перекодировать файл - есть куча оберток над ffmpeg, в том числе open source и бесплатные.
Наконец, если делать самому, то на мой взгляд архитектура получается неэффективная. Ты предлагаешь ради GUI поднять веб-сервер и гонять запросы из браузера, чтобы этот сервер что-то делал с видеофайлом. Это очень неэффективно, тут явно нужно десктопное приложение, без всяких серверов. Но его написание это конечно намного более сложная задача чем вызвать ffmpeg. Если под винду то удобнее всего писать на C# и .NET. Есть еще варинант писать HTML/CSS/JS приложение и упаковать его в десктопное приложение с помощью Electron, но не уверен что это все эффективно и надежно будет работать.
Ну а телеграм приплетать сюда еще неэффективнее, он вообще тут никак не подходит.
В общем мой совет - найти нормальный готовый видеоредактор.
Вот живой пример: сайт, на котором размещена таблица. Каждую ячейку в ней можно редактировать прямо на странице. Нажимать кнопки, выбирать радиобаттоны и всё такое. При этом на странице (без перезагрузки) происходят какие-то изменения. Технически я сейчас это реализовал так: - На странице ловится событие (например, onclick или onchange) по которому срабатывает жабаскрипт. - Он собирает введённые данные (id элемента, value инпута и т.п.) и передаёт их через аякс в пхп-скрипт. - Этот скрипт - отдельный файл, например url:"refresh_cell.php", . В нём первым делом из $_POST извлекаются переменные и по ним что-то там обсчитывается. - Причём, большей частью в функциях, которые записаны где-то в другом файле (у меня они сведены в один function.php). - В итоге, пхп-скрипт выдаёт сгенерированную разметку через echo. - Он завершается, и в js через аякс возвращается эта выдача success: function (data) {. - Ну и дальше эта data куда-то встраивается на странице.
Это так и должно быть, или я набыдлокодил слишком много костылей? Как быть, если нужно извлечь не один кусок данных, а несколько? Например, при изменении одной из трёх ячеек, обновить в БД не только её саму, но и их сумму в четвёртой?
>>947541 В целом все правильно. Конкретно архитектура на фронте и беке вызывает много сомнений, типа почему у тебя там не мвс, а какойто дикий файлик с функциями, но это ты с опытом нагородишь. Сам процесс верно протекает. Ну а для того, чтобы решить твой вопрос просто дописывай и на фронт и на бек необходимый функционал.
Вообще, я бы конечно разделял это на компоненты. У тебя все перемешано в кучу и намертво связано. Я бы сделал отдельно на яваскрипте виджет таблицы, который генерирует события изменения. Отдельно бы код, который подписывается на эти события и отправляет данные на сервер. Отдельно на сервере код, который их принимает и сохраняет в БД. Там отдельно модели и контроллеры.
С сервера удобнее присылать не HTML, а JSON, а то непонятно как сообщать об ошибках например.
> Как быть, если нужно извлечь не один кусок данных, а несколько? Например, при изменении одной из трёх ячеек, обновить в БД не только её саму, но и их сумму в четвёртой? Реши, где будут делаться изменения. Если на сервере - то пусть тот присылает содержимое не одной, а всех изменившихся ячеек, если на клиенте - пусть см их пересчитывает.
>>947545 >почему у тебя там не мвс, а какойто дикий файлик с функциями Я пока не умею в паттерны. Почитал про MVC, офигел от того, что большинство объясняющих даже не могут внятно объяснить, что такое "модель" и в основном срутся по этому поводу друг с другом. А когда попробовал разобраться, получилось какое-то описание идеального программирования в стране эльфов. Типа вот волшебный идеальный пользователь, который волшебным идеальным способом контактирует через волшебного обозревателя с волшебными данными. А на деле получается что-то вроде "модель - это данные на сервере, но на самом деле в 2017 году это уже не совсем данные, а данные, плюс логика работы с ними, поэтому все серверные скрипты - это тоже данные, но только модель, правда собирать их в одну модель некорректно, потому что тогда контроллер размазывается между клиентом и сервером, а это а-та-та и ой-ёй-ёй, поэтому вот тут мы нарисуем стрелочку, этот блок на рисунке расположим чуть ближе - и теперь всё в порядке. Данные, которые не модель, видятся контроллером через вид, затрагиваемый моделью контроллера пользователя. Модель. Данные."
Пока что для себя я сделал вывод, что вид страницы настраивается только через css и рулится чере id и классы элементов, а активность пользователя отслеживается только через js. Данные лежат только в БД и все операции с ними проходят только на стороне сервера.
>просто дописывай и на фронт и на бек необходимый функционал >С сервера удобнее присылать не HTML, а JSON, а то непонятно как сообщать об ошибках например. Тоже о нём думал, не хотел с ним морочиться, но видно придётся.
>>947550 >Если на сервере - то пусть тот присылает содержимое не одной, а всех изменившихся ячеек Вот как раз этого и хочу избежать.
>Я бы сделал отдельно на яваскрипте виджет таблицы, который генерирует события изменения. А чем стандартные onchange и onclick не устраивают?
>>947593 Ты читал про классическое мвс, раз там обсервер фигурирует. В связи со спецификой бекенда обсервер между вьюхой и моделью быть в принципе не может. Тут значит схема такая. Модель - данные и логика работы с этими данными. Самый распространенный пример, который тебе в большинстве фреймворков встретистя - одна модель на одну сущность в бд. Вьюха - в данном конкретном контексте просто создает статичный хтмл. Контроллер - это в принципе центральная точка работы всего этого говна. Запрос с браузера маршрутизуется приложением так, что в конечном счете он приходит на какой-то контроллер. Контроллер его обрабатывает, вызывает методы моделей, какие требуется. В конечном счете контроллер какие-то данные отдает вьюхе, чтобы та отредерилась. И после этого статичный хтмл, полученный с вьюхи, отдается клиенту обратно. Ну вот такая сама стандартная схемка в двух словах.
>>Я бы сделал отдельно на яваскрипте виджет таблицы, который генерирует события изменения. > А чем стандартные onchange и onclick не устраивают? Может в твоей ситуации они и подойдут, так трудно сказать.
Переусложнено. Во-первых, это элементарно решается без генераторов, кода будет намного меньше. Во-вторых, тут: return function(start, step) - не должно быть аргументов. В третьих, вместо 2 yield можно использовать один.
То есть тебе стоит разобраться в теории, в каких именно ситуациях стоит использовать генераторы.
Ты замыкания знаешь? Если нет, изучи в learn.javascript.ru. Ты создаешь функцию, а переменную-счетчик располагаешь снаружи от нее, таким образом, что эта функция может увеличивать ее при каждом вызове.
Комментарии такого типа, как у тебя, тут не приветствуются. Ты ведь не помочь хочешь, а похвастаться что вчера прочел статью для чайников про настройку нгинкса? Это конечно большое достижение, но наш тред не для таких целей.
php-fpm это менеджер процессов PHP и FCGI сервер, с твоим гуглом какие-то проблемы.
Апач проще наверно. В случае нгинкса надо отдельно поднимать и настраивать php-fpm, а с апачем не нужно. Хотя конечно в плане конфигурации нгинкс современней, логичнее и удобнее. Но возни-то больше получается, особенно начинающему.
Ну и кстати у нгинкса полезных модулей меньше. Например, у него нет модуля, который умеет в отдаваемой странице заменять что-то по регулярке (тот модуль от китайцев, что есть, убогий и малопригодный).
Ты случайно не из тех, кто считает что новая модная технология X всегда лучше чем старая Y? Нгинкс ориентирован на производительность, а Апач на число фич и модулей.
>>947612 >То есть тебе стоит разобраться в теории, в каких именно ситуациях стоит использовать генераторы. Типа такого? А вообще я не жсер, увидел что там генераторы просят, полез юзать генераторы.
>>947612 >Апач проще наверно Мне он напротив перегруженным кажется. Кому как. А вот энжинкс прост и прозрачен для меня, работаю с ним и прямо душа радуется. С пхпфпм так же сложностей не имею. Все это даже на винде легко разворачивается (в несколько урезанном виде) для быстрой разработки. >Ты случайно не из тех, кто считает что новая модная технология X всегда лучше чем старая Y? Нет, дело не в новом. Да и о чем новом может идти речь, если для меня энжинкс и апач на первой же работе в связке попались >Нгинкс ориентирован на производительность, а Апач на число фич и модулей. Мне приятно осознавать, что он быстр, это тоже плюсом идет.
даже если Ip меняется, эта проблема решается с помощью Dynamic DNS - ты ставишь себе на компьютер программку и она автоматически обновляет DNS-запись. Есть бесплатные сервисы.
Проблема будет для тех, кто сидит за NAT (большинство пользователей интернета по кабелю). Там надо покупать белый IP у провайдера.
Правила у PHP такие же, просто после изменения PATH в панели управления надо перезагрузить компьютер чтобы службы получили новые переменные окружения. Это кстати не проблема винды, в линуксе наверно так же.
Откуда столько негатива? Не все готовы заказывать разработку с нуля, кто-то хочет взять готовое решение и сконфигурировать под свои цели, верстку натянуть. Что плохого?
Это во всем мире так делают.
Хотя конечно программистам лучше от этого подальше держаться.
CMS рассчитаны на создание сайта с минимумом программировния. То есть это не для программистов, а для верстальщиков, админов, контент-менеджеров и эникейщиков.
Зачем сомнительные задания с фриланса и конкуренция за еду? Это для тех, кто учиться не любит или не способен, а хочет поскорее зарабатывать. Я вижу другой вариант: в нашем треде всерьез изучить ООП, MVC, фреймворки вроде Симфони, тестирование, с таким набором знаний анон будет выглядеть лучше 90% вкатывальщиков, учившихся по видеокурсам, и его возьмут в любую нормальную компанию стажером.
> Кресты вообще по умолчанию встроены, благодаря особенностям генты. Анон оптимист, во всем видит хорошее (для тех, кто не понял шутки - компоненты генту распространяются в виде исходных кодов и их надо скомпилировать, чтобы установить).
Не все проекты такие нагруженные, чтобы нужна была кастомизация. На небольших проектах проще воткнуть кеширование.
Ну и тот же гитхаб, он вообще на Руби (и рельсах по моему: https://github.com/showcases/projects-that-power-github ) написан, не самый быстрый язык, но они просто наставили серверов побольше, где-то что-то подкрутили и проблема тормозов решилась. Хорошо, когда есть инвесторы и много денег!
относительно чего он считается? Ты думаешь, относительно текущего файла? Неверно. Если посмотреть документацию по require, правила там запутанные и в каких-то случаях это работает, в каких-то нет. А __DIR__ сожержит полный путь к текущему файлу и с ним все работает гарантированно.
"у меня работает" - это вообще ничего не значит. Сегодня работает, а завтра нет. Надо смотреть документацию.
preg_replace находит все фрагменты текста, соответствующие регулярке (первому аргументу) и заменяет их на второй аргумент. При этом при замене можно использовать подстановки из исходного текста вида $0, $1 и тд.
use работает только в пределах файла и не распространяется на файлы, которые ты вызываешь из него.
В use по моему нельзя использовать две точки, это не имя папки.
> я так понимаю, require_once просто включает содержание файла шаблона Где это написано? require это что-то вроде вызова функции, выполнить код из указанного файла. Только в отличие от вызова функции, вызванный файл видит те же переменные, что и родительский.
> как подключить фреймворки Как написано в документации к ним, скорее всего через composer, независимо от операционной системы.
> как запустить чтобы это всё работало на внешнем айпи или локалохосте? Если линукс твоя основная система, то тебе нужно еще Апач или нгинкс, в качестве веб-сервера, который будет принимать запросы от браузера. Ставится опять же через ept-get install, конфиги в /etc/ как всегда, логи в /var/log/
В браузере вводишь http://localhost/, если хочется использовать свое доменное имя вроде example.local, пропиши его в /etc/hosts
Надо делать отдельный класс, и может, не один. Потому что там довольно сложная схема с генерацией ссылок, обработкой ответов итд. Посмотри на сущестующие библиотеки для авторизации через соцсети и увидишь что там все не просто: https://packagist.org/search/?search_query%5Bquery%5D=auth
PHP выучить не очень сложно, но фрилансер ведь не будет писать абстрактные программы на чистом PHP. Тебе надо знать верстку, может CMS, может фреймворки, ООП, MVC, базы данных и при всем этом конкурировать с толпой людей. Зайди на фл.ру и сам почитай какие там задачи.
Есть, но плохая. Сразу не получится, надо сначала ООП, DI, MVC и некоторые паттерны изучить. В ОП посте есть задача на студентов, почитай комментарии к ней, а это ведь задача без фреймворков, а сколько всего надо учитывать.
Гайс, есть некая идея(но рассказывать офк не буду). В общем, суть заработка: 2 чела скидывают в общак, победитель забирает 80% от всей суммы, а 20% нам. Что вообще нужно знать и иметь для такого перевода?
Компьютер и ОС Windows не понимают язык PHP и не могут выполнить твою программу. Тебе надо скачать интерпретатор PHP и запускать его, чтобы он выполнил твою программу, которую ты написал.
То есть ты запускаешь этот интерпретатор, указываешь имя файла с программой, а он уже читает твой PHP код и выполняет (интепретирует) записанные в нем команды.
Еще с трейтами возможны конфликты имен полей и функций, как я понимаю, хотя там есть какие-то проверки на этот счет. Вообще, мало где они полезны и мне не очень нравятся.
>>947712 >Вообще, мало где они полезны Я их время от времени юзаю для реализации поведений. Конечно так, чтобы конфликтов не было. дешево и сердито, скажем так. Нормальные поведения заходят лучше, но не всегда стоят того, чтобы их пилить попросту.
>>947712 >Множественное наследование это странная и неоднозначная вещь. Если везде(вроде как) применяется принцип единственной обязанности, то зачем надо множественное наследование?
Ну может я ошибся насчет того что ты не читал документацию, но вот с моделями ты явно не разобрался. Прочти мой урок по паттернам работы с БД, прочти документацию ларавель по моделям и коллекциям, и я думаю, ты сам увидишь свои ошибки. А если что-то остается непонятным - спрашивай. Тут важно понять именно принципы, что куда надо добавлять, кто за что отвечает и тд.
> Да, это не MVC, скорее просто поделка в процедурном стиле А MVC не требует наличия ООП кстати. Это независимые вещи.
> Тут я косноязычно выразился. Я хотел не вместо, а дополнительно ее сделать. Про один класс для валидации ценное замечание. В ларавель есть своя валидация, тебе надо просто разобраться, как ее приспособить для твоей задачи.
> Куки использую чтобы снова не проходить аутентификацию, когда время сессии выйдет, а вот зачем тогда сессии использовать я не знаю Получается можно и без сессии обойтись. Можно и с ней конечно, но сложнее выходит.
>>Поиск отсутствующих/новых тегов надо было делать в модели. ты похоже не понимаешь идею MVC и кто за что отвечает. С твоим кодом, если мы захотим где-то в другом месте поменять теги поста, нам придется копипастить код из контроллера так как повторно его вызывать из другого места нельзя.
> Тут не понял, ведь все методы для работы с тегами в моделях Attitude и Tag.
Он анализирует список тегов, ищем те, что надо добавить, те, что удалить. Так как он в контроллере, то есть нельзя исплоьзовать повторно в другом месте.
> Весь функционал приложения содержится в модели....К примеру, если мы делаем сайт объявлений, с такими функциями, как "добавить объявление", "удалить объявление", "найти объявления по критериям", то для каждого действия где-то в модели должна быть функция, которую можно вызвать. Если выкинуть все контроллеры и вью, то мы все равно можем добавлять объявления, вызывая методы модели.
То есть это определение, какие теги новые, какие надо удалить, должно быть в модели. Должна быть функция вроде "обновить теги" и уже она ищет, что надо удалить, а что добавить.
>>947411 >>Как найти работу? Вон Ванечка Ерохин уже работает похрамистом, функционал на кассе тестирует, баги шваброй убирает. А все свои книжки читаешь.
>>947723 >В мануале есть страница, даже на русском: http://php.net/manual/ru/migration70.new-features.php >Оператор объединения с null >$username = $_GET['user'] ?? 'nobody'; Ух ты как удобно оказывается Даже так можно: >$username = $_GET['user'] ?? $_POST['user'] ?? 'nobody';
Ты на русскомискал информацию? В приципе, не обязательно именно этот, можно Silex, тем более что он на компонентах Симфони.Можно и большой фреймворк, вроде Yii.
Просто знакомиться с фреймворками проще с минималистичных фреймворков, да и вдруг потом пригодится.
ДА, нужно в фоновом режиме, например, по крону, собирать нужные картинки. Скрипт на странице может получать ссылку на нее либо из HTML атрибутов, либо аякс-запросом.
1) верно 2) верно (хотя ты не учел что бордер добавляет к ширине 2 px) 3) верно 4) цвета вырвиглазные. Почему-то у тебя стоит margin-right 5px, но в задаче требуется 10, почитай, как избавиться от пробелов и вызванных ими отступов 5) верно
Мне в питоне не нравится отстутвие тайп-хинтов и своеобразное ООП. Сам-то язык неплохой, его много где используют, но не уверен что он проще для изучения.
> Вывести информацию о пользователе, сколько лайков поставил/получил, сколько взаимных лайков
Решено пока неэффективно, с лишними подзапросами. Это можно сделать с 2 джойнами без подзапросов. Если непонятно, как, попроси подсказку.
Но вообще, надо приучаться мыслить так:
- джойним нужные нам таблицы - условиями ON/WHERE отсекаем ненужное - группируем, если надо - отсеиваем сгруппированные данные по условию HAVING - сортируем - отбираем нужные колонки из сгруппированных данных
В данном случае очевидно нам нужна группировка по пользователям, вопрос только что и как к ним приджойнить.
Джойны в данном случае сделают код читабельнее и дают оптимизатору больше свободы.
> Все пользователи, которые не поставили лайк юзеру 3 Опять же, решается без подзапросов одним джойном.
> Все пользователи, которые поставили лайк 1,2 но не поставили 3 И тут то же самое.
https://github.com/greenTea242/MinesweeperMVC/blob/master/src/views/PopupView.js#L33 > PopupView.prototype.addButton = function(option, title) { > if (!this._buttons) { > throw new PopupViewException("Необходимо создать контейнер кнопок."); > } Вот это по моему неудачное ограничение. Обычно сначала добавляют кнопки, а только потом отображают попап, а не наоборот.
> var template = document.querySelector(".template-popup"); Тут логичнее использовать id так как шаблон может быть только один. Но это так, мелочь незначительная.
>> 2: https://jsfiddle.net/Lq1fgjde/ > верно (хотя ты не учел что бордер добавляет к ширине 2 px) Насколько знаю, есть 2 пути: - вычесть эти 2 пикселя из ширины элемента. Получится width: 578px, выглядит как магическое число: https://jsfiddle.net/Lq1fgjde/1/ - выставить ширину с учётом паддингов и использовать box-sizing: border-box: https://jsfiddle.net/Lq1fgjde/2/ Оба подхода дали одинаковые результаты, какой лучше?
>>945059 (OP) В вебаче все тухло, поэтому спрошу здесь - когда верстаешь, то просто прикручиваешь ксс и хтмл, всякие жс-штуки не надо прикручивать? А если надо, то какие? Можно верстать просто так или все заказы обычно на верстку на какую-то платформу, типа бутстрапа?
>>947873 >А существуют заказы где просто собираешь хтмл+цсс? Да, но это уже лучше к дизайну отнести. Сейчас время такое, что верстал наплодилось пиздец. Фронтенд - это любая логика, вычисления, которая делается на стороне клиента. Если короче - вся жаваскрипт хуйня.
Вот по функциям вопрос. Если я в функции укажу переменные, вроде function fun(one, two, three), а после введу иные переменные, допустим oneThing, а после вызову функцию, но вставив новую переменную, вот some = fun (oneThing, ...), то будет ли сия функция работать? oneThing будет приниматься за one?
>>947949 Чего-то я не понимаю. Ведь функции выполнены действия с переменными, указанными уже. В эти переменные я после подставляю то, что нужно. А если я укажу любое выражение, которое не было указано, то как она будет выполняться, если в самой функции таковых нет?
Переменные, которые при описании функции указаны в скобках, называются аргументы.
Когда ты вызываешь функцию, то внутри нее эти переменные-аргументы создаются и им присваивается значение, указанное при вызове.
Допустим, мы создадим такую функцию: function something($x, $y) { ...
И позже ее вызовем так: something(1, 3);
тут внутри функции $x получит значение 1, а $y значение 3.
Функция не имеет доступа к глобальным переменным, созданным снаружи нее (и наоборот, снаружи не видны локальные переменные, созданные в функции), потому даже если у тебя снаружи есть переменные с такими же именами (x, y) то они не имеют никакого отношения к тем, что внутри функции.
Потому аргументы как раз и нужны, чтобы передать данные в функцию снаружи.
Пока нет роутера - доступ к страничкам по прямой ссылке на их контроллер, понятно что в продакшене это недопустимо. Еще не разбирался как составить htaccess, если скрипт делит домен с другим приложением
Знаю, что косяк, когда модель непосредственно работает с глобальными переменными. Пока думаю над этим
>>948041 Ну да, лярва выскоабстрактный кусок блевотины. Так сходу въехать во все происходящее именно в этом фреймворке и у опытного человека не сразу получится (например пришедшего с юи), попробуй доки почитать очень внимательно, хз че тут еще сказать.
>>948046 Да мне доки бесполезно просто так читать. Стал въезжать только когда начал пилить свою поделку, с этими уровнями абстракции как будто новый язык учу. Но это так, лирическое отступление
Поясните разницу между роутером, диспатчером и фронт контроллером? Чем отличаются, все сразу делать надо или какое-то одно выбирают, какая разница вообще что использовать?
Простите за глупый вопрос, но как вы учите, усваиваете пхп, я сначала читаю учебник и конспектирую в тетрадке, а потом смотрю видео уроки, вебинары по пхп и повторяю их в редакторе. Правильно ли я делаю?
>>948205 Нет, не совсем правильно. Нужно делать что-то своё, а не просто повторять. Напиши что-нибудь по аналогии, похожее, но не тупо переписывай с туториалов.
>>948205 Неправильно. Видео уроки и вебинары ничего не дают, бездумное повторение в основном тоже. Делать надо задачки как у ОПа, читать книги и документации. Прочел о какой-то новой фишке - пилишь под нее мини проектик. Когда достаточно много разных фишек освоил - пилишь проектик, где все их сразу используешь, тут-то сложности и возникают. Решаешь их, приходит понимание что и зачем, и в голове откладываются знания.
>>948322 А я не гнушаюсь видео уроками. Такой же источник инфы, как и остальные. Доки/статьи/книги могут быть перегружены либо некритичной инфой, либо попросту водой. Видеоуроки напротив кучу инфы не досказывают, но для беглого взгляда на какие-то вещи очень хорошо подходят иногда.
>>948322 Я так напили поделок в процедурном стиле, теперь хуй разгребешь, при этом некоторые используются в поле. Так что тоже не серебряная пуля. Необходимости в ООП и MVC может долго не появляться, пока не придется что-то поддерживать или расширять, а когда для себя пишешь может и не придется.
>>947203 О! Я как раз около недели назад решил, что пора переходить на линукс. До этого всю жизнь сидел на винде тоже. Делал вот что:
1. Сначала почитал какой дистр выбрать, так как они все кажутся одинаковыми, первым выбрал дебиан, поставил на виртуальную машину и не проперся, но подумал "по описанию Дебиан вроде заебись, буду привыкать".
2. По совету друга "не выебываться и ставить убунту" поставил убунту и понял, насколько она охуенная с т.з. использования. Насколько там все проще и лучше для пользователя. В дебиане прям с момента установки какая-то еботня начинается.
3. Понял, что работать в виртуальной машине невозможно, все тормозит и нет стимула глубоко лезть в настройки. От опыта системы воодушевился настолько, что подчистил место на диске и сделал логический диск для убунты, поставил ее туда вместе с виндой. Пару дней поебался, поставил виртуальный сервер и проч., уже чуок привык и теперь от винды блевать тянет, когда залезаю туда. А раньше сидел и думал, что все заебись.
Минусы, которые отмечаю в убунте по сравнению с виндой: жесткий диск греется сильнее на несколько градусов (я в этом параноик), хотя можно поебаться и выключить всякие индексации;
флеш тормозит, мультики в браузере не посмотришь, хотя на ютубе все норм работает;
многих программ нет, например пунто свитчера, для других какие-то ебаные версии (флукс), но для флукса хотя бы есть альтернативы;
драйвера для графических и звуковых карт тоже вроде какие-то ебаные, периодически все рывками двигается, хотя драйверов около 10 версий на выбор;
грузится раза в два дольше винды, хотя выключается в десять раз быстрее.
Но в целом по ощущениям от использования, количеству горячих клавиш, фич и общего ощущения некоей целостности убунту мне нравится намного больше винды, я теперь не вернусь туда ни за что. Винда стала казаться огромной кучей не связанных между собой и не доведенных до ума компонентов. Особенно я прозрел насколько в винде уебищно реализованы права и пользователи
Я короче ставил бы убунту и ставил ее не на виртуалку, а вместе с виндос, чтобы был стимул сидеть и копать. Не знаю позволяют ли другие дистры ставить их вместе с виндой без еботни, но убунту позволяет. Плюс там из коробки уже все работает, а в дебиане надо ебаться начиная с установки и потом после нее с добавлением репозиториев, судо, нормальых шрифтов. Подозреваю, что в других дистрах все еще сложнее (хотя могу ошибаться)
И еще, 90% всех вопросов-ответов в гугле связаны с убунтой, а не с другими дистрами.
>>948843 >Понял, что работать в виртуальной машине невозможно, все тормозит и нет стимула глубоко лезть в настройки. Ну как сказать... Стоит в виртуалке, не тормозит и в настройки лезть приходится. Причем убунта
Пару лет назад ставил убунту с GUI в виртуалку - на экране логина времяреакции на клик мышью было около минуты. Тогда Убунта что-то поменяла в интерфейсе так, что он должен был рассчитываться на GPU (использовался OpenGL, я так думаю), а в случае его недоступности GPU эмулировался на CPU и работало это сверхмедленно.
>>948843 >Понял, что работать в виртуальной машине невозможно, все тормозит и нет стимула глубоко лезть в настройки. От опыта системы воодушевился настолько, что подчистил место на диске и сделал логический диск для убунты, поставил ее туда вместе с виндой Виртуальную машину небось virtual box какой-нибудь юзал. Ставь Xen, он намного быстрее.
>>948843 >90% всех вопросов-ответов в гугле связаны с убунтой, а не с другими дистрами. А знаешь почему? Потому что убунта - днище. Есть 3 дистра, где ничего не надо спрашивать, ибо все описано в мануале либо в виках - гента, арч и дебиан.
В виртуалбоксе тоже есть проброс видеокарты, но там определенные условия. Как я понимаю, видеокарту надо отдать виртуальной машине целиком, а значит, надо иметь 2 видеокарты.
Вот, что пишут:
- нужно 2 видеокарты - You need a CPU that supports IOMMU which is VT-D (Intel) and AMD-Vi. This allows Virtual Machines to interface directly with peripheral devices.
Также, в виртуалбоксе есть какое-то экспериментальное ускорение, когда в гостевую машину ставится драйвер и она как-то через виртуалбокс может использовать аппаратное ускорение (OpenGL или DirectX как я понимаю). Как минимум винда начинает намного быстрее работать в таком случае и разрешение экрана в ней автоматически подстраивается под размер окна.
>>948843 Это pr или софтач? Если ты хотел научиться кодить на линуксах, достаточно было поставить серверную версию или купить нищевпску, десктоп для кодинга не нужен.
Истории успехаАноним08/03/17 Срд 10:27:36#397№948993
Настало время поделиться.
Где-то в апреле прошлого года понял, что хватит пинать хуи и пора таки становится нормальным программистом. Мой опыт - это работки в колледже, сами понимаете, не серьезно и не достаточно чтоб работу найти. Начал с нулевых задач этого треда, потом студенты, потом файлообменник. До конца они у меня так и не доделаны - функционал весь, но ОП еще присылал правки, то есть было, что улучшать. Параллельно работал курьером, то за 10к по полдня, потом за ~30к за месяц (да, очень хорошо платили). В ноябре заболел и пока сидел дома подумал, а дай-ка размещу резюме на hh, вдруг выйдет чего. В итоге на меня сами откликнулись. Больной бегал на собеседования. Их было целых три. Еще и тестовое дома делал. В итоге взяли на техподдержку. Современная веб-студия, пилящая на Битриксе (ба-дум-ц). Первые три месяца - 32к, потом 40. Вот жду-не дождусь повышения.
На собеседовании, кстати, оценили мои знания. То, что использую PDO прям плюсец жирный.
Теперь вот надо сдать 2 экзамена от Битрикса и потом у меня планы перевестись на разработку в этой же компании. (потому что, честно говоря, мне похуй почему у вас там сайт тормозит и почему слетает авторизация) Ну а так вообще я подумал, что не хочу свою карьеру связывать с Битриксом, поэтому как-нибудь начну изучать серьёзный фреймворк.
Не могу вот решить с чего начать, Laravel или Symphony, кто что думает? На hh у них доли примерно равные
>>948993 Время проебываешь не битриксе только. Мне за год зарплату до 120к повысили, при чем я пишу даже без фреймворков на чистом php. Ну я правда в ДС, в других городах думаю вряд ли столько дали бы. Учи паттерны, mysql, юнит тестинг, архитектуру и написание нормального кода, а не конкретные фреймворки. Фреймворки имеет смысл смотреть только, чтоб понять как они написаны, зубрить сам фреймворк тоже смысла мало, они на разных фирмах разные все.
>>949009 120 за год? Круто, вдохновляет? Ну а разве фреймворк не является хорошим примером и способом изучения хорошего кода, паттернов и прочего? Так-то да, понятно, что хороший уровень, это когда смена фреймворка - дело пары месяцев
>>949009 > при чем я пишу даже без фреймворков на чистом php Ты по отдельности компоненты ставишь или свои изобретаешь? Ведь не дано другого + ты пишешь про тесты и архитектуру, значит у тебя там просто свой фреймворк велосипедный? Можно глянуть твои компоненты?
>>948869 Тормознутость определяется не дистром, а окружением рабочего стола (Desktop Environment). Они все почти одинаково тормозят, за исключением LXDE/Xfce. Из убунты можно выкинуть Unity и поставить что-нибудь полегче или вообще изначально собирать всё самому из Ubuntu Minimal: https://help.ubuntu.com/community/Installation/MinimalCD
я без линукса теперь даже уии накатить не могу на винду. установка композера превращается в целую эпопею. и все это ради возможность юзать фотошоп в винде без всяких костылей.
Прогаю верстку под битрикс и чувствую что тупею, все задачи одинаковые, мест где надо применить изящные решения минимум, посоветуйте блогов или сайтов с снипетами по php/bitrix. Прогал на phalcon а бывало и на haskell хочется той же изящности
с домашнего компа ща запустил комозер экзешник на винду, а вот с рабочего там какой-то путь не прописывался. странно все это. я же просто хотел сделать проектик на уии, но так как он не установился на раб. компе, пришлось брать кодеигнитер.
>>949156 Всё сложное придумано для того, чтобы стало легче. А что сложного? Как раз просто в проектах: объявлен класс, пользуешься методами в любом файле, лишь указав namespace. Если судишь по задачам ОПа, то не надо. Они как олимпиадные задачки, такое тебе никогда в жизни не понадобится. В проектах и фреймворках такого не бывает, чтобы в одном файле столько всего было наверчено.
Все работает (проверял с разными суммами), но подозреваю что в плане элегантности это не самое лучшее решение. Есть какой-то образцовый вариант, на который можно равняться?
>>948993 Не иди туда. Битрикс это смерть. Если ты человек с позитивным уровнем icq то больше года не выдержишь, а потом еще и оказывается что за год ты приобрел бесполезный, и даже вредный опыт.
>>949264 Ubuntu 16.04, из репов ставил. Есть строка utf8 UTF-8 Unicode utf8_general_ci. Возможно ли ошибка из-за того, что при создании базы я указал uft8_unicode_ci?
С битриксом не связывайся, это полное дно, и в профессиональном плане, и в плане зарплат.
Учи Symfony и перекатывайся в какую нибудь серьёзную контору, пишущую что то сложное на нём (CMS-ки, какие нибудь внутренние корпоративные порталы для автоматизации бумагоперекладывания, или в подобную фигню - такие есть, сам в такой работаю). Через 3-4 года, если голова светлая, будешь получать не меньше, чем синьёр на какой нибудь джаве-хуяве.
>>949301 Не знаю на счёт питона, но думаю что примерно такие же. Там вся фишка в том, что подавляющее большинство современных пехапешных фреймворков (yii, laravel, zend) созданы под сильным влиянием ruby on rails и сильно на него похожи. Соответственно и друг на друга они очень похожи. Считай - если знаешь один - знаешь их все. В изучении довольно простые, особой магии нет.
Особняком только Symfony стоит. Он делался под влиянием java-вских spring mvc + hibernate, соответственно довольно сильно от них отличается. И область применения у него та же - всякая энтерпрайз фигня. Вот тут уже и магия присутствует (в виде кодогенерации и прочей фигни), и, самое главное, он предназначен для программистов, которые хорошо представляют себе, что такое ООП и как им пользоваться для того, чтобы не получилось такой ситуации, что на середине написания проекта код превращается в такие дикие макароны, что проще проект выкинуть, чем дальше развивать. но это всего лишь инструмент - сам посебе фреймворк качества кода воообще никак не гарантирует.
>>949445 > довольно сильно от них отличается довольно сильно отличается от других php-фреймворков, я хотел сказать. На spring mvc + hibernate он как раз сильно похож (по крайней мере на их раниие версии, пока те в монстров современных не разрослись)
Все тут сифони, ларавел и юи в целом обсуждают. А почему не фалкон? Да, он не популярен так, как вышеозвученные, но он быстр, как шайтан. В целом по возможностям он предоставляет все, что нужно для комфортной разработки, разве что возникает желание обертку другую нагородить поверх не самого привлекательного апи. Почему бы его не переместить в шапку? А то эта технология, очень даже привлекательная в плане потребления ресурсов сервера, остается практически неизвестной. Добавлю, что в нагрузку идет зефир, который позволит вынести в сишные расширения большую часть рутинной блевотины.
>>949448 Потому что идея, заложенная в основу phalcon - абсолютно бредовая.
ПХП выбирают из-за скриптовой природы и, как следствие, предельной простоты разработки на нём. Естественно, в ущерб быстродействию потом. ничего бесплатно не бывает.
Если тебе нужно быстродействие .... то нафига тогда вообще php брать?? Для этого есть java, c++, go наконец.
А проект на phalcon - это какая то дикая менашиша из кода на PHP и C - ну пиздец. В итоге ни удобства разработки на PHP, ни быстродействия полностью компилируемых языков.
>>949455 Ну вот есть у меня проект на фалкон. Я в сишный и зефирный код не залезал даже, все на пхп. Немного неудобное апи в сравнении с остальными обдроченными абстракциями фреймфорвками, но востальном все точно то же самое, только пашет намного быстрее. Фалкон не минифреймворк, он решает своим сраным сишным расширением 80% рутинных задач, я не вижу причин его не использовать и не развивать.
>>949455 На работе фалькон, никакой мешанины из Си там нет, обычный PHP. Не знаю откуда ты взял что там какая-то мешанина будет, фалькон в использовании ничем от других фреймворков не отличается.
Рыбята, я прошел курс молодого тельца и решил взяться за задачу про студентов. Начал читать и охуел, начал кричать "Слажнаааа", а где же работа с базой данных, создание страниц из данных вытянутых с базы? Тут циферки слаживали , а тут хуяк , посчитай остаточную массу электрона при распаде радия за 15 миллионов лет при условии что Маша и Миша не давали интервью в Лондоне.
>>949525 Посмотри в книжке из разряда пхп для даунов как работают с бд для начала, освоишь взаимодействие бд и пыхи, навертишь верстку и вот студенты и готовы. А потом ОП тебе разъяснит что ты лалка, пойдет процесс и ты все поймешь.
сегодня осознал, что можно делать вот так и подумал, что после того, как перешел с js, немного отупел в плане всяких фишек, укрощающих код, зато поумнел в качестве "хуяк хуяк и в продакшн"
>>949548 Лол, работаю по такому графику, зарплата 37$, 31 год. Когда в тредах ржут над фрилансерами которые зарабатывают по 100 баксов, я не смеюсь, я им завидую
>>949573 можно, если только тебе на свjих коллег насрать. И на себя тоже. 1) $status = '0'; echo $status == 1 ? 'yes' : 'no' выведет 'yes'. Это раз. 2) статус = 1. Ну заебись. Это что за статус такой? а если там 2 будет - это что значит? Правильно хотя бы так <?php echo CategoryStatusConverter::statusToString($category) ?> где: class CategoryStatusConverter { const STATUS_ENABLED = 1; const STATUS_DISABLED = 2; public static function statusToString(array $category) { if (array_key_exist('status', $category)) {
if ($category['status'] === self::STATUS_ENABLED) { return 'yes'; } elseif ($category['status'] === self::STATUS_DISABLED) { return 'no'; } } return 'unknown'; } } а ещё лучше djj,ot без статических методов обойтись.
Не всегда так надо усложнять. Если вывод нужен только в одном месте программы (а в других местах статус обозначается по-другому), то можно сделать и тернарным оператором.
Если вариантов больше, то можно сделать массив для перевода из статуса в текст.
>>949602 схрена ли? задача валидатора - проверить валидность и ответить, валидно ли значение или нет. Но ни в коем случае не редиректить. Задача контроллера - принять запрос, проверить с помошью валидатора и вернуть ответ. Или вернуть ошибку, если запрос невалиден. Так что редиректить тут вообще не нужно. Нужно юзеру ошибку вернуть и показать в браузере.
>>949607 Проверка на валидность более комплексное действие в общем случае, чем проверка одно айдишника. В целом моя позиция в том, что валидатор должен вернуть тру или фалс в зависимости от результата, + сообщение читаемое.Результат работы обрабатывается в коде, например, контроллера, и при фалсе редиректит куда-илбо. Но сама проверка должна осуществляться валидатором, контроллер, или кто там выше валидатора стоит, должны лишь отрегировать на валидацию.
ты совсем поехал? во первых, работает абсолютно корректно, во вторых, вариантов статуса всего 2. 1 и 0. Ты что, надграфу не можешь почитать? IS VISIBLE. Да и нет. Какие еще варианты? на пол шишечки?
в сложных вариантах - да, а тут почти человеческая речь. Статус равняется единице? напечатай да, или нет. Не знаю, все лучше, чем писать огромные if ($qwe == 1) echo '1'; else echo '2';
>>949612 Добавлю, что своим опытом выстраданные проекты привели меня к следующей схеме: любое несоответсвие отплевывается в виде жэксепшена, принимаего одни или несколькими обработчиками (чаще всего все же одним), и в связи с этим до контроллера вообще не доходит ничего в случае провала валидации.
>>949614 Это способ работатьб слесарем в чужой системе. Когда мы работаем на фреймворках мы и есть творцы системы в целом (бизнес логики). Когджа ты работаешь внутри какой-нибудь цмс ты лишь можешь рядом с этой системой (уже заранее заданной бизнес логкиой) возвести костыль, фиксящий то-то и то-то в самой системе. Но свобода твоя очень сильно ограничена. Вот в этом и разница.
>>949607 >любое несоответсвие Зачем вбрасывать исключение при проверке данных введенных пользователем? Исключения нужны только для программистов, чтобы в случае если вся программа по какой-то исключительной причине не может продолжать или выполнить работу.
>>949624 Зависит от того, как ты исключения обрабатываешь. У меня большая часть исключений выбрасывается клиенту в виде удобочитаемого сообщения че там и не так. Но я в основном апишник, мне этот момент очень важен.
>>949626 Ну, сорян, мои апи репы закрыты. Если на словах, то суть исключений апишных в том, чтобы в коцне сформировать короткой и понятное сообщение для клиента. притом для меня. Адово помогает в отладке. клиентов много ,апи одно, ты и сам знаешь наверно. Если его не сформировать, то я и сам не буду знать че там такое произошло прямо. Случаи подобного очень часты. Апи призвано отдавать либо ошибку подробную, либо валидные данные. Тут мимо идут сразу верстка и фронт, а потом эксепшены с моей стороны обязательны, иначе хуй отдебажишь вообще что-либо.
>>949636 Да я новичок вообще! Мне интересно как правильно должны писаться исключения. Я обычно пишу так:
if (something wrong) { throw new Exception("error"); }
Но мне хотелось бы знать как получить с помощью исключений максимально информации! Пока именно даже не знаю какой.
Думаю что нужно наследовать и писать своё исключение, и потом в конструкторе писать все нужные подробности. Но почему-то мне кажется что в конструкторе плохо писать логику исключения.
>>949644 Максимум информации ты получаешь уже в конструкторе исключения. Стак и прочее у тебя дступны силами разрабов самого языка, твое дело отдать наилучшее сообщение при new Exception, корторое ты только можешь, + определить форматирование в завимимости от способа отлдачи (я предпочитаю джейсон апи).
>>949591 На хуй присядь. ОП очень много объясняет того, чего ты нигде не прочтешь. Но для того, чтобы добраться до кладезя его знаний, гуглом нужно уметь пользоваться. На кой ты вообще нужен, если общедосьупную информацию получить не можешь?
>>945059 (OP) Сап, доброкун, а ты не думал перезалить на более качественный хостинг свой проект и сделать там генератор .pdf, .doc, .epub, .fb2 слепка сайта. Ты же вроде еще не бросил учить анонов, а так бы было всем желающим удобно получать все в одном месте, я вот читаю с андроида, оно вроде бы удобно, но иллюстрации распидорашивает и если изначально у тебя была задумка с пошаговым изучением, то затем все меню сайта расползлось куда-то в ебеня, а материал все равно прибывает. Вот если бы ты сделал в более читабельном виде и автоматическую генерацию, то тебе бы не надо было бы каждый раз обновлять весь набор работ, а пользователи бы просто догружали файлы по завершенным "аркам" уроков. Инб4: сделай сам Я бы и рад, да пока знаний на этот счет не особо, но если вообще тебе нравится идея, то я бы покопался на этот счет и как найду в себе силы, то готов сделать это вместо тебя.
Обрисую ситуацию. Я обычный гуманитарий, учитель по образованию. Работаю в школе, и тут мне подкинули задание - сделай-ка ты нам сайт школы. В общем, как бы сам сайт делать мне не пришлось, его нам зарегистрировали и создали на джумле какие-то левые типы. Но теперь директор постоянно ебет мозги. Нанимать умеющего человека она не хочет, поэтому все село на меня, а я этим делом даже и не интересовался никогда. По-быстрому скачал какой-то шаблон, накидал информации (как от меня и требовалось), но теперь, оказывается, требуется сделать все красиво.
^ Сам сайт. И я так и не смог понять, как сделать отображние материалов, как это обычно идет на всех сайтах - прикрепленное фото с кратким описанием либо началом материала, которое можно увидеть, непосредственно открыв этот материал. У меня почему-то всегда получается простой список заголовков материалов. Пытался читать туторы, решения моей проблемы так и не нашел. Извините, если ошибся тредом, но не мог бы кто-нибудь тезисно объяснить мне, как это сделать? Всем добра.
Анон, у меня установлена ubuntu 16.04 с apache сервером. Когда пытаюсь зайти через localhost - то все нормально. Но когда ip, то у меня просят логин и пароль. Так вот, отчего это чего этот логин и пароль должен быть? Что ни пробовал - не подходит.
сделай условие: если длина материала выше n символов, то проверить, есть ли краткое описание материала и отобоазить его, если такошо нет, то отобразить первые первые n символов материала. И в конце добавь строку с ссылкой на страницу материала, или на расширение статьи. Во втором случае обрезать материал будешь через js и jquery.
>>949761 Сразу видно, что учитель из тебя не очень. Запрягаешь ученика 9 - 11 класса за пятёрку в четверти сделать сайт и всё, проблем нету. Ещё потом и хвастаетесь другим школам, что у вас вот такие ПРОГРАММИСТЫ умные в школе есть. А вообще гугли создание блога на джумле, хотя там всё должно работать хорошо из коробки, но я уверен что весь нужный функционал для сайта будет в таких статьях.
Помогите плез, вот у меня есть массив, и я хочу сделать ещё один массив с определённого номера (?) Например есть ['a','b','c','d','e','f'] И я хочу отсечь всё с номера 3 включительно, так чтобы новый массив выглядел так - ['d','e','f'] Как мне это сделать?
Вот ещё вопрос по архитектуре (или чему-то подобному). На сайте есть таблица в некими полями. Одно из полей предназначено для миниатюр фотографий, которые загружают пользователи. Но как эти файлы лучше хранить? Помещать в БД, вроде, не стоит. Просто хранить в отдельной папке, а в БД сделать таблицу соответствий (Фото164542.jpg - это вторая миниатюра для записи №476)? Или сразу переименовывать (Фото164542.jpg -> Фото164542-2-476.jpg), а потом парсить всю папку силами пхп?
Читаю этот php.net и просто охуеваю, все написано через пень колоду, никакой структуры, никаких мануалов по работе и взаимодействию php mysql apache,спрашиваешь где лучше почитать , что бы не распыляться на миллиард мануалов, сразу прибежал оберштурмбанвахтер с криками "В печь полезай унтерменш!"
>>949921 Я часто работал с такой схемой, что миниатюры и прочие пресеты (у нас их штук 100 на сайте одном было) хранятся по разным путям. То есть например оригиналы по адресу /originals/image-name.png, а к примеру миниатюра 100х100 для этого же лежит в /100x100/image-name.png. Довольно наглядно выходит. Там конечно структура на реальном проекте будет сложнее, но ничего сверхъестественного. Вариант с названием самих файлов тоже нормальный. В бд, конечно же, изображение лучше не хранить.
>>949927 >миниатюры и прочие пресеты (у нас их штук 100 на сайте одном было) хранятся по разным путям Это понятно. >Вариант с названием самих файлов тоже нормальный. То есть, оптимально будет при загрузке файла добавлять в его название информацию, к чему он относится, а когда нужно прикрепить изображение к странице, парсить имена файлов? А если файлов будет несколько десятков тысяч? У меня ожидается добавление примерно 30-40 тысяч картинок в год и сайт с этим должен работать хотя бы лет пять.
>>949930 Я видимо не понял, какую ты задачу решить пытаешься, ибо при любой схеме с составлением пути или имени файла по каким-то определенным тобой правилам ничего тебе парсить не нужно будет в поисках нужной картинки. Опиши тогда саму задачу подробнее.
>>949933 Задача такая: Для контроля выполнения работы, работнику нужно сделать фото до, в процессе (возможно, несколько) и в конце. Кроме того, проставить время выполнения и некоторую другую информацию. Для этого, сначала менеджер забивает заказ в таблицу заказов и выбирает исполнителя (через интерфейс менеджера). Исполнитель заходит под своим логином на сайт (через интерфейс исполнителя) и видит, что у него образовался заказ, а так же его параметры. В ходе выполнения, он делает фотографии и загружает их на сайт. У них автоматически проставляется время. А менеджер в офисе видит в строке заказа миниатюры. Ну или хотя бы текст типа "2 фото прикреплено", кликнув по котором, можно эти фотографии просмотреть.
На сервере фотографии скорее всего будут сразу ужиматься до некоторого стандартного разрешения и делаться миниатюры. А вот с тем, как потом быстро и удобно прикреплять их к страницам, пока не разобрался.
Да, я ебанутый . Вот создал я такие настройки в апаче. <VirtualHost *:80> DocumentRoot /home/lpkn/bogdan-footer ServerName www.koloda.org <Directory "/home/lpkn/bogdan-footer"> allow from all Options +Indexes </Directory> </VirtualHost> Как нужно обратится к www.koloda.org в браузере что бы оно показало мои файлы , а не ресурс в интернете?
Есть кусок задачи: "Создайте две страницы сайта, используя технику шаблонов и класс View из предыдущего ДЗ: 1.news.php - отображает список всех новостей. Заголовок у каждой - ссылка на страницу этой новости, под заголовком - краткий текст 2.article.php?id=NNN - отображает новость номер NNN с полным текстом" Объясните, пожалуйста, как именно должен передаваться get запрос. Переход на article.php ведь осуществляется по ссылке на страницу, а не через <form> с кнопкой.
Друзья, помогите 27-летнему вкатывальщику. Я только начал изучать PHP. Задача стоит следующая, после PDO::FETCH_CLASS, из базы я получаю массив объектов своего класса (длина массива неизвестна). Допустим $clients. У объектов есть несколько свойств включая, допустим $clients->state (бинарная false || true). Теперь мне необходимо создать два цикла, которые позволят мне обработать все свойства объекта. Но дело в том, что в одном цикле должны быть только объекты со значением state == true, а во втором только с фолсами. Проблему можно решить, просто составив два SQL запроса в БД, (вроде SELECT хуй FROM игрушки WHERE state = false). Но мне нутром кажется, что можно не дергать лишний раз базу, а как-то раскидать по двум циклам массив объектов исходя из свойства state. Мальчиков налево, девочек направо. Внимание, как это сделать? http://php.net/manual/ru/language.oop5.iterations.php тут читал, нихуя не понял. Похоже это даже не то что мне нужно.
>>949875 >ДЮСШ >пятёрку в четверти Чета обзмеился. >хвастаетесь другим школам, что у вас вот такие ПРОГРАММИСТЫ умные в школе есть А потом его заставляют за бесплатно поднимать и обслуживать сайты всем этим другим.
Вообще, >>949761 выглядит неплохо, но тебе с нулевыми знаниями тяжело будет, пиши >>949829 анону полюбасу.
>>949968 Просто прописываешь в ссылке на файл после названия и расширения это ?id='number', это и передает GET запрос. т.е, на новой странице ты уже можешь получить 'number' через $_GET['id]. Мимо несчастный с циклами
>>950000 'к. Порешаю обязательно. Циклы и ветвления я немного знаю, просто похоже действительно сегодня переработал. А ООП сразу, потому что в конторе, сказали приходи через месяц с PDO и ООП и возьмем тебя за еду. В любом случае больше чем есть сейчас.
>>949617 Потом удаляешь все файлы через unlink, подключаешься через сокет к апишке сервера и запускаешь детонатор, чтобы взорвать сервак к чертям. А все потому что пользователь ввел невалидный email.
Так взялся за студентов, начал читать за роутинг. "делать роутинг средствами сервера. Для каждой страницы в папке public создается отдельный скрипт (index.php, register.php) и из него либо вызывается соответствующий контроллер, либо прямо там же и пишется код контроллера" Что за папка public? Это типо public_html на убунте? Что за контроллеры? Их надо писать средствами php? Я нихуя не понял, простите, я туповат, да , на пальцах , примерах только понимаю.
>>950235 Тут нет другого варианта, кроме как прочитать кучу статей и уроков по теме, попутно пытаясь сначала повторить, а потом сделать свою поделку. У меня на это действительно много времени ушло.
Я учил не по ОП-посту, но там в принципе тоже все есть и объясняется проще чем на хабре.
GET-запрос это когда браузер запрашивает страницу с определенным URL с сервера. GET-параметры пишутся после знака вопроса в этом URL. Форма не обязательна.
Браузер преобразует имя узла (www.koloda.org) в Ip-адрес этого узла с помощью системы DNS, отправляя запрос на DNs-сервер. Однако, с помощью файла hosts можно указать соответствие имени и IP явно, и в качестве IP прописать адрес твоей машины (127.0.0.1). Тогда браузер будет соединяться с запущенным на ней веб-сервером (Апачом).
Раз у тебя есть папка public, надо бы в нее перенести index.php и сделать ее корневой папкой веб-сервера, а то у тебя весь код наружу выставлен получается.
Идея bootstrap-файла в том, что он инициализирует приложение, а не запускает разбор запроса. Он нужен на тот случай, когда у тебя несколько точек входа в приложение, например cli-скрипты. И не хочется копипастить один и тот же код в начало каждого из них.
В твоем варианте bootstrap тут никак не помогает и вообще его правильнее было бы назвать index.php, а не bootstrap.php.
Идея ООП в том, что у нас каждый компонент отвечает за свою часть задачи. Один класс, который умеет соединяться с БД и выполнять запросы, другой класс, который умеет искать пользователей в базе, третий класс, который умеет еще что-нибудь.
Ну и название - "модель" тоже очень неудачное. Что такое модель, в твоем понимании?
Ну например у тебя в каждом объекте-модели свой объект PDO в то время как правильнее создать один объект и совместно его использовать.
Далее, у тебя смешано много задач. У тебя базовый клсс модели занимается:
- чтением конфигов - установкой соединения с БД - выполнением SQL запросов
https://github.com/grigoryMovchan/auth/blob/auth_mvc/app/core/Model.php#L69 > } catch (PDOException $e) { > //TODO: убрать при переносе на сервер, строка только для отладки > echo '<p>' . $query . '</p>'; Ты собрался catch и echo ставить после любой функции, которая может выкинуть исключение? Это ведь будет почти каждая функция в программе. И зачем ты выводишь сообщения? Какая польза посетителю твоего сайта от непонятных сообщений на английском?
Вообще, PHP по умолчанию сам выводит на экран сообщение при выбрасывнии исключеия. Ты зачем-то пытаешься повторить то, что PHP и так умеет делать по умолчанию (если включено отображение ошибок).
Тебе надо разобраться с исключениями.
https://github.com/grigoryMovchan/auth/blob/auth_mvc/app/core/Model.php#L43 > switch ($type) { Свитч сделан не очень правильно. Если передать в качестве type неправильное значение (например, из-за опечатки), то твой код притворятся что все в порядке, вместо того, чтобы сообщить тебе что ты передал неправильное значение. Так ошибку в коде придется искать намного дольше.
Вообще, это плохая идея сделать одну функцию с вариантами выбора. Надо тогда делать N функций, на каждый вариант свою.
Также, view не должен лезть в POST-данные. Это из-за того, что ты пока не научился разделять код на отдельные независимые действия. Должно быть так:
- получить данные из POST - сделать с ними что-ниудь - проверить их - ... - вывести форму
А у тебя это смешано. Когда код разбит на отдельные действия, в нем легче разбираться, его легче править. А твой запутанный код очень тяжело поддерживать, так как изменение в одном месте ломает что-нибудь в другом.
Тебе бы стоило сделать задачу на Вектор, если ты ее не делал. Она в том числе пытается научить этому разделению на части.
Файл помещаем на диск, после этого в таблицу - относительный путь к нему. Для уменьшенной картинки можно либо формировать путь из пути к основной, либо хранить в базе оба пути.
Всегда надо сначала сохранять файлы, а только потом записывать в БД, чтобы не было такого, что запись в Бд есть, а файла нет. Удалять в обратном порядке.
Иногда исплоьзуют схему, когда имя файла как-то формируется из id, чтобы не надо было брать его из базы, но там есть свои недостатки - неудобно сохранять картинку.
Так как у тебя к записи можно приложить несколько картинок, нужна отдельная таблица для них.
Еще какие-то полезные вещи могут быть в комемнтариях к задаче про файлообменник в ОП посте.
Нужно просто делать нормальное сообщение об ошиюке. Не читается файл - напиши, какой, не можешь соединиться с сервером - напиши, с каким, передано неверное значение - напиши, какое. Поможет при поиске ошибок.
Можно делать свои исключения и делать у них дополнительные поля, но это на тот случай если тебе надо потом их извлекать. Если не надо, то пиши все в сообщении.
Для отладки можно использовать логгирование. Или показывать подробности ошибки только на локальном сервере.
Ну например если ты не можешь соединиться с базой то АПИ не должно отдавать эти подробности (а тем более - с какой базой с каким логином). а просто писать, что временно недоступно.
- а что если несколько ошибок? - а что если у одного поля несколько ошибок? - а что если есть предупреждение? - а что если мы хотим знать у какого именно поля ошибка? - а что если мы хотим иметь код ошибки, чтобы программно его проверить ифом?
Не знал, что надо фильтровать любые данные, думал только те, которые можно подставить через get или через формы. И сейчас честно говоря пока не понимаю зачем. Если у меня допустим эта переменная лежит в базе (и у этого поля тип INT), то это только чтобы перестраховаться на случай, если злоумышленник влезет в базу или есть еще какие-то способы подменить значение таких переменных?
PHPч, ПАМАГИ! Я заебался. Использую XAMPP для функций апача и MySQL, у него для работы с БД (MySQL) встроенный phpMyAdmin. Как нужно корректно определять кодировку при создании БД в phpMyAdmin в браузере, чтобы непосредственно на моём сайте, который вытаскивает данные из MySQL кириллица отображалась нормально, а не "??????"? Нужно указывать сравнение или выбирать какую то конкретную кодировку? Алсо, я видел в интернете на десятках источников предлагают непосредственно в PHP при каждом соединении с БД устанавливать кодировку на сессию, но разве это выход? Это ж накладные расходы по времени при каждом соединении.
>>949829 Прости, анон, что не написал вчера и, скорее, всего, не напишу сегодня. Просто Я ДОЛЖЕН ПРОИЗВЕСТИ ИНВЕНТАРИЗАЦИЮ ВЫБРОСОВ ВРЕДНЫХ ВЕЩЕСТВ В АТМОСФЕРНЫЙ ВОЗДУХ. >>949875 У нас школа другого плана. >>949876 Да я вообще хотел сделать сайт на укозе каком-нибудь, кому какая разница? Но нет, директор хочет сайт на домене второго уровня, и сам сайт заказал у каких-то левых типов.
>>950263 >Файл помещаем на диск, после этого в таблицу - относительный путь к нему. Для уменьшенной картинки можно либо формировать путь из пути к основной, либо хранить в базе оба пути. >Всегда надо сначала сохранять файлы, а только потом записывать в БД, чтобы не было такого, что запись в Бд есть, а файла нет. Удалять в обратном порядке. >Так как у тебя к записи можно приложить несколько картинок, нужна отдельная таблица для них. >Еще какие-то полезные вещи могут быть в комемнтариях к задаче про файлообменник в ОП посте. В общем, понятно. Буду делать таблицу.
>>950215 Вот ты не вбросил текст заданий и зря - мне попались другие. Твоё 3-е на JS в одну строку: let third = (str) => str.concat('_').match(/.{2}/g); https://jsfiddle.net/ans4w1q1/ По второму: непонятно почему ты запрещаешь использовать float/double - в PHP есть функция is_numeric. Твоё первое задание не понял.
>>950270 В исходном коде страницы (Ctrl+u в Firefox) можно найти задания. Но я посоветую зайти хотя бы на codewars - там задания в меру сложные, но без олимпиадного задротства как на codeforces.
Кстати, я недавно видел статью адепта реакта, так он пел что MVC - все , пойте отходную, что веб эволиционировал на новую ветвь и что mvc - крик неондертальца которого словили кроманьельцы и режут его на ремни.
fetchAll(PDO::FETCH_CLASS, 'Student') – ругается на конструктор, так как все свойства, кроме id обязательны (он не нужен при регистрации), так вот как этого избежать? конструктор нужен в других случаях, если все поля на = null, то появляется уязвимость в других случаях. Знаю про | PDO::FETCH_PROPS_LATE и третий парапетр у fetch (можно как-то туда сами поля из БД передать?), но как тут это может помочь? Пока сделал все параметры конструктора необязательными
>>950571 Он, небось, намекает на ивент драйвен в духе ноды (аналоги уже повсюду есть). Но тут такое. Где-то будет лучше, где-то будет хуже такой подход. Поидее фронт это не должно беспокоить, просто жсеры обязательно играются с нодой, и вот результат.
>>950583 Лет 10 назад я еще не знал, что в эту тему залезу. Пописываю на ноде микросервисы, выполнить на ней здоровущий проект с жесткой бизнес логикой желания не возникает, во всяком случае сейчас. Продроченным жсерам либо похуй, либо они идейно сопротивляются присутствующим неудобствам. Редуксы ваши тут тоже не серебряная пуля нихуя, да и не ново это ниразу.
>>95058 Хе-хе, самое смешно что я так и не получил удобоваримого объяснения что такое flux. Идея MVC зато проста как лопата. >>950588 А что было раньше. Срачи разводить вы горазды, зато вопрос задашь - как хуев в рот набрали , хоть бы одна жопа пернула.
Сначала конечно надо изучить реакт, так как эта система под него заточна. Реакт, как известно, это библиотека, реализующая view, а flux видимо должен помочь реализовать остальные части.
Вполне возможно что оно заточено под специфические нужды фейсбука (реализация интерактивных интерфейсов на отдельных страницах сайта).
Я особо в нее не вникал и что-то прокомментирвоать трудно. Если кто-то хочет на флуксе и реакте сделать задачу на SPA из Оп-поста - всегда пожалуйста.
Бляяяять, а классы, классы где?! Полез блять читать пасту про MVC, а там с ходу классы пошли. Все мое терпение лопнуло, дайте мне просто ссылок на нормальные книги где все струтурировано, я знаю что я тупой и немогу в гугол, и можно было все найти , но я так не могу.
>>950606 Cуть не в стрелочных функциях, они там только ради читабельности. Суть в том, что для решения той задачи не нужны цикл+иф как у того анона, достаточно коротенького регулярного выражения.
>>950595 Работать закончил, покормлю. А нахуй тебе нужно спрашивать про флукс, если ты сам знаешь что это? В двух словах способ управления данными, основанный на хранилище (хранит модели и работает с ними), диспетчере (регистрирует и дергает ивенты между хранилищем и вьюхой), ну и вьюха, которая без задней мысли в любой непонятной ситуации перерендеривается по причине изначальной ориентации на реакт. Пойдем дальше. Этот инновационный паттерн родился по той причине, что некоторые фронты чувствовали потребность в решении извечной проблемы "МЫ ЗАПУТАЛИСЬ В СВОЕЙ ЛАПШЕ, СПАСИТЕ". Проебываем и еле находим состояния во всяких ангулярах, нокаутах и прчоем, скопы все перемешались и ебут друг друга в жопу и уже нет архитектуры, просто каша, да ко всему нормального паттерна для работы с новой мокрой писечкой реактом нет, а без гайда мы удобную архитектуру выстроить не в состоянии - и тут снизошло откровение от фейсбучных гуру "а давайте все данные держать в куче и изолируем их нахуй". На самом деле ничего плохого, удобство присутствует, и фронт пилить в этом стиле очень даже неплохо, но и новизны тут особой нет, просто фанатичные жсеры снова подхватили велосипед с неуемной энергий и в лучших традициях баранов пытаются притащить свою моду в каждый чужой монастырь. А идея, тем временем, не нова, и встречалась во множестве проектов, где оказывалась к месту. У меня на работе в одном из приложений на андроид реализована практически такая же архитектура для некоторых целей. Все просто и наглядно, притом о флуксе вообще никто не думал, когда пилили. Была задача - нашлось ее решение. И все же это не спасительная таблетка. Теперь к изначальному тезису - мвс в вебе качается не только фронта. Переходим к беку - там у нас, во первых, есть самые настоящие хранилища в виде бд и слоя с моделями на любом фреймворке, не в дикие времена ведь живем. А вот нахуя изобретать диспетчер событий, когда у нас в целом исполнение приложения линейное? В реализациях схожих с нодой (а этого добра уже прилично) это тоже нахуй не уперлось, т.к. в беке вьюха не занимается тем, что судорожно перерисовывается на каждый чих, и отдельно взятый запрос все равно остается линеен, не говоря уже о том, что значимая часть бекенда это различные апи и им в принципе нихуя рендерить не нужно. Вебсокеты всякие и без того сильно отличаются от обычного бекенда, так и там хранилищем выступает какой-нибудь редис, у которого и так под любой изврат из коробки находится решение, и вьюх тут вообще не существует. Впрочем тут еще концепция флукса сама собой хорошо проявляет себя. В целом в беке как было удобно мвс, так и осталось. Флукс сюда тащить попросту не за чем, это наркомания самая настоящая.
>>950595 Жабогосподин в треде, приходилось недавно в проекте работать с React+Redux+TypeScript, как же заебала эта параша.
Суть там в SPA, т.е. вместо нескольких страниц существует одна, которая динамически меняется (т.е. ее DOM). Например, убирается окно логина (в виде <div> компонента), отображается другое окно, с профилем пользователя. Плюс у каждого компонента хранится состояние, ну типа чтобы реже обращаться к базе.
На MVC с шаблонами все это реализуется намного проще, а данные из базы можно кэшировать. Но хуесосы весь фронтенд перевели на этот Flux (Redux - одна из его реализаций). Ебал я в рот это говно.
Подскажите сайт на котором сравниваются репозитории на гитхабе по количеству коммитов, старту разработки и т.д. Натыкался на него, когда набирал в гугле КОСТЫЛЬ1 vs КОСТЫЛЬ2, а сейчас не могу найти.
Вот я кстати думаю, что рендеринг через реакт хорош для задач вроде обновление циферок на странице, но такие вещи, как появление нового окна, переключение вкладок, в общем, навигация, лучше делать не через реакт. Так как иначе мы должны в страницу вставить кучу скрытых окон, причем они возможно будут пересчитываться при каждом изенении, то есть как-то неэффективно это выглядит.
То есть лучше сделать это окно логина отдельной сущностью со своим контекстом, который мы активируем при появлении и отключаем при скрытии.
Вообще, у меня такое ощущение, что реакт делался не для полноценных SPA приложений, а для мини-приложений, интерактивных интерфейсов в рамках страницы. Чтобы там можно было нажимать кнопки, и менялись какие-то циферки.
- у wasm кода нет доступа к DOM, значит JS-прослойка нужна - wasm код это результат компиляции, неудобно при разработке, после любой правки надо перекомпилировать код, в то время как с JS таких проблем нет
Так что я за то, чтобы не заменять JS, а не использовать его без надобности, а если использовать, то писать правильный код, а не брать вкатывальщика, который до этого работал менеджером по продажам и единственный его талант - врать не краснея.
>>950647 >В двух словах способ управления данными, основанный на хранилище (хранит модели и работает с ними), диспетчере (регистрирует и дергает ивенты между хранилищем и вьюхой), ну и вьюха, которая без задней мысли в любой непонятной ситуации перерендеривается по причине изначальной ориентации на реакт. Нихуя не понял, а чем оно от мвц отличается?
>>950664 > у wasm кода нет доступа к DOM Это допилят, JS ведь тоже хотят запускать через WASM. Значит, будут все возможности. >wasm код это результат компиляции, неудобно при разработке, после любой правки надо перекомпилировать код Пакетный менеджер будет компилить и запускать. Как сейчас TypeScript, по одной команде npm start выполняется пересборка и запуск.
>>950661 Лол чем хуев JS? Обычный язык, проблема то в вебе. Натаскали хворосту , хуев собачих, говен кошачих, и все шо было в доме и давай кашу из топора варить. Кто шо хочет, то и кидает в каструлю.
>>950667 У тебя нет контроллера. У тебя есть вью, есть модель и хранилище. А еще есть диспетчер, принимает события от вьюхи и регистрирует события на изменения хранилища. Вьюха (обычно через фабрику называемую action creator) отправляет события диспетчеру, тот на них реагирует, харнилище чего-то там с моделями творит, по итогу зарегистрированные на изменения события вызываются, и по канону связанному с реактом вьюха без всяких подумать просто перерендеривается целиком (типа так можно, потому что реакт на виртуальном доме работает, там оверхеда нет для реального дома при рендере)
Она похожа, но там есть разница. В MVC контроллер может дергать любые методы модели, получать данные, менять данные. А тут у нас есть диспетчер, и у него N методов для изменения данных в модели. То есть диспетчер + хранилище примерно соответствуют модели из MVC. Через диспетчер ее можно менять, с другой стороны view ее может читать.
И важный момент в том, что сторы подписываются на события в диспетчере.
Вообще, я плохо это все представляю, как например там делаются формы и валидация. Где хранятся данные формы, как валидируются, как выводятся ошибки, и тд.
Если мы храним модель формы и ошибки внутри хранилища, то должны тогда в диспетчере делать методы на изменение каждого поля в каждой форме? Или делаем один метод для всех полей? Один метод для всех форм? Кто работал с реактом, напишите, интересно.
- с JS: отредактировал файл, обновил страницу. В отладчике виден код, можно ставить брейкпойнты, выводить выражения - с другими языками: надо ждать пока все перекомпилируется, отлаживать нормально нельзя, так как в отладчике будет виден JS
В случае с wasm отлаживать вообще придется ассемблер.
Я думаю, он для тех случаев, когда нужны какие-то производительные вычисления. Например, аудиотрек сконвертировать, PDF отобразить. На практике конечно будут использовать для просчета анимированных рекламных баннеров.
А может какой-нибудь маньяк додумается сделать фреймворк, чтобы вместо HTML сделать канвас на весь экран и на нем рисовать сайт с помощью wasm. Преимущества: нельзя масштабировать, прокрутка работает так как решил автор кода, нельзя выделять текст, сохранять картинки, блокировать рекламные баннеры.
О, а еще можно скопилировать вебкит в wasm чтобы избавиться от разницы в поддержке технологий браузерами.
И тайп хинтов нет. Там вообще статической типизации нет.
Вот мне интересно, а как работают с большими проектами на Питоне? Можно ли в IDE кликнуть по методу и перейти к его определению?
Я тут пробовал открыть большой проект в Eclipse и обнаружил косяк - она не может перейти к методу, если не знает, какого класса объект. То есть в случае использования DI контейнера вроде :
Она не знает класс объекта $doctrine и не может перейти к method. ПРиходится копировать имя метода, и вызвать диалог "Search method", где он и ищется.
Для сравнения, Sublime text 3 не анализирует код, а лишь индексирует имена методов и классов. И он умеет переходить к определению, ища метод по имени. Правда, если там распространенный метод вроде get, он вываливает список всех классов, где он определен, что минус.
В общем, я плохо представляю как с большими проектами на Питоне работать. А как понять, данные каких типов нужны функции?
Плюс, там меня напрягает необходимость писать self в методах. что за атавизм?
Из тех языков, которые хорошо реализованы - это наверно C#. Вижуал студио делает полноценное автодоплнение, умеет переименовывать методы, и перед каждым методом даже пишет, сколько раз он используется.
>>950678 > А еще есть диспетчер, принимает события от вьюхи и регистрирует события на изменения хранилища. Короче, это когда бородые хипстеры объебались перебродишим смузи и решили переименовать MVC.
>>949624 >Зачем вбрасывать исключение при проверке данных введенных пользователем? Низачем. Не слушай наркомана. Кидать исключение при неправильном заполнении пользователем формы это bad practice. Суть исключений в том, чтобы выбрасывать их, когда ход программы пошел не так, как было задумано - т.е. против твоего изначального замысла. А ввод пользователем неправильного имейла или формата телефона не должен выбрасывать исключений, это абсолютно регулярное и постоянно происходящее, нормально, адекватное событие. То что кто-то оформляет таким образом обычные сообщения о неправильно заполненной формы очень и очень дебилистичностранно. Можно таким же образом вообще без вьюшек обойтись и бросать исключения тут и там. Но исключения предназначены не для этого.
>>950687 Lisp тоже продуманый и че? Тут же как в той пасте про перфициониста выдрачивающий продукт и васян четкий который выбросил продукт самый первый. Продукт выброисл на рынок корявый и забаженый, но первый. И пока перфик выдрачивал свой продукт еще, вася четкий патчил свое поделие и выпускал обновления. И пока перфикцтонист доедал хуи без соли, васян разбил второй лексус. Бля сука, ну я пишу откровеную хуйню, а вы блять на обычный вопрос не отвечаете.>>950676
существуют ли в природе удобные редакторы для похапе? phpstorm клевый, но пока он запустится, пропадает желание кодить. Пользуюсь brackets что на линуксе, что на виндовсе, и вроде бы все неплохо, но он ориентирован на фронт + недостает автоподставлений имен функций итд.
>>950808 PHP storm IDE а не редактор. Там можно не только набирать код, но и подключить те же базы данных, композер, в нем есть консоль. Автодополнение переменных с баз данных, опять же. Там встроен GIT, и UI к нему оформлен просто отлично. Можно коммиты на гитхаб отправлять, прямо из редактора. Да много чего, проще сказать что он не делает.
тормозит прям ужасно. Пока запустится - я умру. У меня атом, обмазанный тем же функционалом, запускается быстрее и работает идеально, но я от него отошел, т.к пересел за бракетс. В нем идеально все, кроме автозаполнения я по невнимательности иногда допускаю мелкие ошибки и в итоге все ломается к чертям
пропустил твой ответ. Вим не очень хочу, т.к он довольно-таки своеобразный и надо выделять пару дней на его изучение, чтоб нормально в нем работать, а потом еще пару, чтоб дополнения, а потом я еще свое захочу написать, в итоге забуду зачем он мне.
>>950854 Нетбинс попробуй, только качай только пакет где хтмл/цсс+пхп+жс что бы не тормозило. По части всяких автодополнений годнота не хуже шторма, но всякие фишки типа встроенного гита и композера похуже, естественно. Зато швабодно и шустро работает.
Я вот чего понять не могу. Вот есть у тебя класс, охуеный такой класс, здоровый сука, на странице MySweatPussy.php и тебе например нужно в другом файле YouBigCock.php унаследовать етот класс или как нибудь с ним взаимодействовать, как происходит это соитие? И вообще эта раскиданость по разным страницам программы просто сбивает с пантелыку, как вы с этим спраляетесь?
А ты знаком с протоколом HTTP и таким понятием как "заголовки ответа"? header просто добавляет заголовок к HTTP-ответу. Также она может задавать код статуса (404, 503, 302 и тд).
Привет, анон. Не могу понять, RewriteBase нужен только при внешнем редиректе? Почему вне зависимости от того указываю я его или внутренний редикт работает правильно?
Он был нужен в Apache 2.2, если реврайт делается не в корне сайта, а в папке в нем. Ну например если мы хотим реврайтить /folder/x на /folder/x.php и htaccess находится в /folder.
Разделители в виде скобок не нужно экранировать, если они также используются как метасимволы в шаблоне, но как и с другими разделителями их нужно экранировать, если они используются непосредственно как символы. >экранировать Это как? Что значит экранировать? Ещё одни скобки поставить?
>>951009 Извиняюсь за несколько сообщений сразу, просто пока я читал эти слова, вызвал сатану. >квантификатор, означающий 1 или более вхождений Вхождений чего и куда?
Погромисты, как html c css в формат libre office или еще какого опен офиса перегнать? Дали задание веб-сервис продокументировать и в pdf загнать, а там только html/css экспорт. Импортил его в libre office, чтоб дальше редактировать, весь css по дороге теряется, остается один html. Его естественно в pdf не заэкспортишь, ибо все вкривь и вкось. Может кто сталкивался?
Читаю вот эту пасту https://github.com/codedokode/pasta/blob/master/arch/mvc.md и вот там есть такая функция public function addPost(Post $post) { // Проверим, что объявления еще нет в списке if (null !== array_search($this->posts, $post, true)) { throw new \Exception("Post already added"); } Что обозначает (Post $post) ? Из переменой зразу лепят обьет класса Post?
Я бы не сказал, что он не востребован совсем. Есть проекты на Питоне, но начинающим там конечно не особо рады, нужны опытные разработчики. Также часто его используют как вспомогательный язык, для написания каких-то простых скриптов.
Ну а оценить востребованность по моему нетрудно поиском на сайте с вакансиями.
Вообще, редко такое бывает, что достаточно знать один какой-то язык. Обычно нужно знание какой-то области, например: веб-разработка, десктопные приложения, приложения под Андроид и тд.
Вхождений символов из регулярки в строке. "вхождение" тут значит "в строке встречаются символы, которые указаны в регулярке".
Это слово используется примерно так: "в строке abcabc найдено 2 вхождения подстроки bc". "Подстрока" - значит часть строки.
Квантификатор - это символ, указывающий на то, что предыдущее выражение может повторяться. Например, плюс, звездочка: a+ значит "1 или более повторений буквы a".
>>951055 Спасибо, нашел. Действительно прикольная штука, все необходимые действия с базой легко доступны. Не вижу только где делать экспорт/импорт, ну да и хуй с ним.
Ну например, \$ вставляет в строку просто знак доллара:
echo "\$"; // выводит $
Допустим мы хотим в регулярке искать знак доллара. Так как это спецсимвол, мы должны его экранировать как \$. Но если мы напишем "\$" то PHP создаст строку из символа доллара, без слеша. Потому мы должны дополнительно заэкранировать бекслеш, чтобы он передался как есть:
echo "\\$"; // выводит \$
Эти сложности из-за того, что бекслеш используется для экранирования на 2 уровнях:
- сначала при интепретации строки в двойных кавычках - затем, в регулярке
Самый сложный случай - это если ты хочешь искать безслеш регуляркой. Согласно правилам регулярок, мы должны его заэкранировать и писать так:
\\
Но в строках бекслеш имеет специальное значение, и чтобы вставить в строку бекслеш, мы должны его записать дважды. Так как тут бекслеша два, то мы должны вписать в итоге 4 бекслеша. Проверим:
echo "\\\\"; выведет \\
Если использовать строки в одинарных кавычках, то там комбинаций с бекслешем меньше и например \$ можно писать как есть (а можно и как \\$). Также, если использовать синтакси nowdoc, где бекслеши не интепретируются, то регулярку можно будет писать как есть:
if ($error) { вернуть ответ с ошибкой } else { вернуть $result; }
Другой вопрос, что если у тебя код бестолково написан, и ты хочешь из любого места кода возвращать ошибку, а не только из doSomething() - но это скорее всего просто говорит о том, что код некачественный. И добавляя исключения ты его качественнее не делаешь.
Я еще у себя включил синхронизацию с ФТП, тоже очень удобно, сохранил файл и он сразу обновился на сервере. Также недавно начал коммитить в гит прямо из нетбинса без юзанья командной строки.
>>951190 Было тоже самое, что ты с возвратом описал. Попросту менее читаемо и все равно требуется обработчик исключений для перехвата говна, прилетевшего с чужого кода. Насчет качественно не качественно - работает стабильно, занимаюсь только поддержкой и пробросом новых маршрутов, на все уходит по несколько минут, в правках не нуждается, создание нового маршрута в среднем занимает строк 10 (в минимальном виде всего одну вообще). Я тут еще много написал про внутреннюю работу, потому что критика (множество ошибок, логирование и тд) хз с какой колокольни берется, но стер. У меня исключения обеспечивают самую гибкую и при этом простую работу с ошибками из всех, что я видел. Но я не смогу в этом убедить авторитетов этого треда, так что впизду простынями тут расшаркиваться еще. Пускай я буду говнокодером и закроем эту тему, потому что от выстраданного за 1.5 года опыта работы над такими задачами я от исключений в этом контексте не откажусь, как от наиболее прозрачного механизма возврата ответов с отличным от 200 кода. Сириусли, не убедите, просто останемся при своем. Новичкам тогда не советую, раз людям так моя система не нравится. Уточню еще, что говорил я об апи, для сайтов самих я такую схему не использую.
Ну вот, я тут теперь выгляжу злодеем, который предлагает сломать работающее решение. Мне это не нравится.
Я предлагал различать ожидаемые ошибки (клиент передал неправильные данные, в базе нет нужной записи) от неожиданных (не удалось соединиться с БД, нет записи, которая обязана быть). И для первых не использовать исключения. А для вторых - возвращать ошибку 503 без подробностей, логгировать в лог, чтобы разработчики их исправили.
>If an object is converted to an array, the result is an array whose elements are the object's properties. The keys are the member variable names, with a few notable exceptions: integer properties are unaccessible; private variables have the class name prepended to the variable name; protected variables have a '' prepended to the variable name. These prepended values have null bytes on either side.*
>>951128 Мне редактировать же еще его надо, хотя тоже вариант, да.
>>951153 >Кроме печати в PDF, есть еще утилиты для командной строки, преобразующие HTML в PDF. Попробовал популярный pandoc + miktex, при первой же попытке вывалился с критическими ошибками. Причем если просто от руки создаешь html + css, то нормально конвертит. Но чуть что более сложное, и он падает. Похоже в 2017 в мире так и не тула, чтобы html+css перегнать в любой подходящий для редактирования в редакторе формат. В итоге 5 часов писал свой скрипт для open office на office basic, который недостающую css разметку сам генерит уже в формате офиса, благо там немного разметки было.
>>951408 Спасибо! А вот тут: var_dump(strlen($employee->name)); выводит int(21), но ведь там Иван Иванов! Какого, спрашивается? Там же должно быть int(11)?
>>951514 Короче, я не понял, что такое с идеоне, но с латиницей всё работает: http://ideone.com/9UQfxt mb_internal_encoding("UTF-8"); почему-то перестало работать, я не понял. Что по задаче, верно?
Как сделать класс пагинации? Ну сами функции я понимаю с запросами LIMIT и OFFSET, а как лучше организовать? В контроллере класс Pagination или Pager вызывает методы маппера, он же и ссылки формирует? как-то много передачи аргументов из $_GET (из контроллера в пагинатор, потом в маппер). Мне кажется, GRASP паттерны нарушаются.
Друзья, подскажите, есть ли в регулярке изящный способ поставить такое условие: "подстрока, от двух до трех символов которой должны быть цифрами, а остальные могут быть произвольным количеством пробелов и дефисов"?
>>951585 Ну вот в чём дело! Спасибо, ОП. А то я помню же, что всё работало отлично с mb_strlen, а сейчас выдаёт ошибку. Ну а так по задаче вроде нормально всё, следующий пункт делаю.
Yii2. Не получается сделать хэлловорлд. Проблема: не могу передать параметр в action контрллера. Включил urlManager, apache настроил, rules прописал как в мануале, результат пикрелейтед.
вот я сделал роутинг, и, вопрос вот: в файле есть функция получения ссылки, объявленная приватный. Далее идет метод run, который собственно определяет нужный контроллер и экшен.
Квк мне вызывать получение ссылки? $this->getURI(); self::getURI(); обе строки работают и вроде бы даже одинаково по скорости. Вкусовщина?
Шапку бы вам добавить, ато тут муси-пуси, вот пременая мы ее тут можем сложить и тут хуяк классы, ни слова про шаблонизанию, сегодня увидел в пасте расширение файла phtml, подумал что опечатка. Как отлавливать ошибки уже сервере, Да и вообще очень мало практики, только основы языка, как работать на реальном апаче ничего нет.
При работе с Апачом ошибки пишутся по умолчанию в лог ошибок Апача (под windows это обычно папка logs в папке Апача, под линукс это /var/log). Но все, конечно, зависит от настроек Апача и PHP.
Для себя ты можешь запускать код используя встроенный в PHP сервер, чтобы не мучаться с Апачом.
А так да, по апачу надо по идее отдельный подробный урок делать. Хотя вроде есть же документация на английском...
>>951643 $this вызывает через экземпляр класса, self только статические методы на самом классе. Php позволяет вызывать так же статический метод через $this, но это криво. Статические методы лучше не использовать, они ведут к созданию кривой архитектуры, т.к. с ними ты создаешь всякие синглтоны и не используешь инверсию зависимостей, что ведет к созданию тесной связи между классами. Их стоит использовать, когда тебе действительно нужен синглтон, например если предполагается одно соединение с БД на весь проект.
>>951658 Ознакомься с докой по статическим методам: http://php.net/manual/ru/language.oop5.static.php По скорости разницы нет конечно, только по структуре твоего кода. В нормальном коде не должно быть статических методов, они используются лишь в исключительных случаях, когда без них не обойтись. Если будешь городить статические методы везде, то быстро придешь к проблемам с архитектурой.
Так, помощи прошу. Правильно ли я сделал то, что на скрине? http://ideone.com/Zjk63v Не пойму, для чего мы будем применять метод класса к $employee в цикле, когда проще сделать $totalHours += $employee->getTotalHoursWorked(); $totalSalary += $employee->getSalary(); $totalOvertime += $employee->overtimeHours; Это всё в цикле же сложится и посчитается. Чую, не то делаю, но не пойму, объясните! Или в том же методе getNormalHours($variable) нам и нужно было указать return $variable += $this->hours; И потом просто делать в цикле $totalHours = $employee->getNormalHours($variable) ? Что-то такое?
>>951871 >$totalHours = $employee->getNormalHours($variable) То есть там будет так, наверное: $totalHours = $employee->getNormalHours($employee->hours); Ну а смысл?
Ты сделал неправильно. Ты сделал свойство overtimeHours, как будто бы это какая-то отдельное, независимое от других, свойство. Но это не так. Оно вычисляется из hours.
Соответственно ты вручную занимаешься теми подсчетами, которые нужно было переложить на компьютер. overtimeHours не надо вводить руками, надо просто взять hours и все, что больше 40 часов в неделю - это овертайм. А normalHours это соответственно все, что в пределах 40 часов в неделю.
Потому свойство overtimeHours не нужно, так как переработку всегда можно вычислить из значений в hours.
>>951880 Спасибо за помощь! Ну а как сейчас, всё верно: http://ideone.com/n2qlzR ? Чувствую, что начинаю немного нащупывать суть ООП :3 Но пока боюсь дальше заглядывать.
Сложную конструкцию в getNormalHours() можно упростить с помощью функций min/max. А можно упростить еще сильнее, если вспомнить что normalHours + overtimeHours= TotalHours.
Попытался решить задачку из http://archive-ipq-co.narod.ru/l1/strings.html (задача "На словах ты Лев Толстой"), но вместо аккуратного результата получился мусор. 1.Как сделать перенос по строкам в рамках одной переменной? 2.Как исправить ошибку рендома, из-за которой получается одинаковый результат при генерации?
>>951999 >Сложную конструкцию в getNormalHours() можно упростить с помощью функций min/max. Хм, не понял, как это сделать. Ведь в min/max возвращается единственное большее или единственное меньшее значение в массиве? А у нас в массиве с часами может быть как угодно: [40, 50, 60, 45, 35]. >А можно упростить еще сильнее, если вспомнить что normalHours + overtimeHours= TotalHours. Точно, спасибо: http://ideone.com/Tly7EQ
>>952035 Первые две строчки однотипные, поэтому могут быть в цикле с for, где $i < 2. Я впервые вижу, что такой текст на идеоне работает, раньше только с EOF работали переносы строк.
http://archive-ipq-co.narod.ru/l1/pasta.htm Что это за конструкция ? foreach ($question->answers as $letter => $answer) Что за $letter => $answer, это что для того что бы letter воспринимался как массив? Больше никаких задач конструкция не несет?
>>952741 Что ты имеешь в виду под "проверять"? Если ты хочешь проверить равна ли вся длинна строки, скажем, 15 - регулярка тут нахуй не нужна, используй встроенные средства языка для этой хуйни. Если же количество символов это только часть того, что ты ищешь, то хуле нет-то? ^.{3,12}$ - найти любой символ (.) от 3 до 12 раз Ну или там ^[a-z]{20}$ - найти строку ловеркейсных латинских букв ровно в 20 символов
>>952779 Да я уже разобрался, просто мне эти регулярки напоминают черное колдовство. Например, не могу понять почему нельзя сделать диапазон типа a-Z, а надо обизательно писать a-zA-Z, уебство какое-то. Алсо /^[а-яА-Яa-zA-Z-']{1,10}$/u Норм регулярка для валидации имени? Тире и апостроф для экзотических двойных имен, или там О'Коннелы всякие.
>>952792 Если как упражнение, то наверно норм, хуй знает. Если в реальном ирл мире™ то валидировать номера телефонов, имена, имейлы и подобную хуйню регулярками - говно полнейшее, если меня родители уебанским именем на дохуя букв назвали, что мне, уже твоим сервисом нельзя воспользоваться? >а надо обизательно писать a-zA-Z потому что "-" это оператор диапазона, если посмотришь в таблицу символов юникода, ловеркейс и аперкейс символы сгрупированы отдельно друг от друга, так что диапазон a-Z нихуя в себя не включит то, чего ты ожидаешь.
>>952801 > Если в реальном ирл мире™ А как еще можно валидировать? Без учета длинны что ли? Вообще расскажи в кратце как это в крутых фреймворках делается, что бы самому не лезть поперед батька в пекло.
>>952841 Ну можно ебануться на отличненько как ютуб и позволить вообще всё, что угодно. Крутые фреймворки не думают за тебя, та же симфони позволяет указать разные требования к полям при валидации, типа "Не должно быть пустым" или "Может содержать только цифры", или кастомное какое угодно условие, тут вопрос не в регулярках, а в общей идее. Отсыпь юзеру символов двести по длинне и не ограничивай диапазон, если тебе норм с тем, что какой-то один из тысячи хипстер засунет туда залго и эмодзи. Если не норм, то всё равно, нету никакой причины вводить бессмысленные анальные ограничения на 10 символов в имени, или невозможности напечатать там какую-то польско-чешскую диакритику с точечками и хвостиками, или ещё что. Если же такая причина у тебя есть, и она хорошая - тогда ограничивай, хуле
Чуть больше недели изучаю php. Сегодня после пяти часов мучений сдался и пришел за помощью.
Необходимо через стандартную хтмл форму получить пост запрос и внести результат в сессионный массив.(Тут проблем нет пока) Следующий ввод значения чтобы добавился следующим элементом без потери прошлого результат.
И когда наберется 5 элементов в массиве, то вывести его и провести сортировку, но это уже ерунда, сам справлюсь.
>>952891 $array[$value] = $value прямо в цикле, будет тебе ассоциативный массив. array_push($array, $value) - просто добавит значение в конец массива. Наверное ты вообще плохо усвоил основы работы с массивами.
>>952971 Вангую что у тебя ssl в конфиге пхп не включен, эта залупа пытается по https сконектиться с своим сервером, жрет говно и, естественно, не показывает сообщение об ошибке, обходясь стандартным "что-то пошло не так". Ну или чего-то другого у тебя в системе не хватает, curl выключен, хуй знает,
Приветик, может кто подсказать, как мне решить мою задачу: Мне необходимо, чтобы со стороны сервера постоянно выполнялась определенная функция класса, которая будет выполняться, допустим, каждые 10 минут или в определенный момент времени (В 12:00 в субботу)? Функция должна выполняться с определенного класса, язык обязательно PHP.
В laravel можно как-то забиндить команды на таймеры, но ларавел мне сейчас не надо, я хочу решить эту проблему на чистом PHP. Может кто-то подсказать? Предлагайте решения, где гуглить, куда смотреть.
>>953035 ideone любит ломаться, палю годноту https://3v4l.org/ хоть и немного не для того предназначен, но ваши скрипты в десять строк похуй где исполнять, а для чего-то поинтереснее придется поднимать сервер (учитывая что блядь в пхп уже встроен веб сервер который в одну строку поднимается, не вижу смысла возиться с онлайн хуитой вообще)
https://3v4l.org/fd5qV - вот эта задача на ООП. Что здесь у меня не так? Что-то почва из-под ног ушла, не пойму, в чём обосрался. Методы непонятные в классах с вопросами дублируются - вроде так нормик. Не пойму, в чём дело.
Логика проверки ответа на правильность в разных типах вопроса разная. Потому в каждом классе будет своя реализация этого метода.
Но в твоем случае, у тебя код методов checkAnswers почти полностью совпадает в обоих классах. Копипаста - это плохо, и ее быть не должно. Это первая ошибка.
Вторая ошибка в том, что у тебя checkAnswers предполагает что все вопросы в массиве одинакового типа. Но они могут быть разного.
Третья ошибка: класс Question представляет один вопрос в тесте. Но метод checkAnswers работает не с одним вопросом, а с массивом вопросов, и наверно, в этом классе ему не место.
Тебе надо подумать, что в коде проверки ответов - общее для всех видов вопросов, а что для каждого вопроса свое.
Ну например, вот это:
> if (count($questions) != count($answers)) { > die("Число ответов и вопросов не совпадает\n"); > } Одинаково для всех видов вопросов.
Надо сделать так: внешняя функция checkAnswers принимает массив вопросов и ответов. И для каждой пары вопрос-ответ вызывает метод проверки на правильность. Вот этот метод проверки, правильный ли ответ к тесту, и должен быть описан в классах вопросов.
Перечитай внимательно 3 проблемы с твоим кодом, и попробуй понять их, чтобы больше таких ошибок не повторять.
Также, еще одна вещь. Допустим мы хотим добавить новый тип вопроса. Для этого мы должны создать класс, наследующийся от Question. А в нем сделать метод проверки ответа. Но это нигде не описано. Глядя только на класс Question, об этом никак не догадаться. Тут могут помочь абстрактные методы. Если все наследники класса обязаны реализовать какой-то метод, то надо объявить его как абстрактный метод в базовом классе. Тогда унаследоваться, не описав этот метод, будет нельзя. Ну и будет сразу видно, что мы обязаны добавить такой метод в класс-наследник.
>>953203 Спасибо за разбор, бро, завтра уже постараюсь вдуплить и советы учту. >Также, еще одна вещь. Допустим мы хотим добавить новый тип вопроса. Для этого мы должны создать класс, наследующийся от Question. А в нем сделать метод проверки ответа. Но это нигде не описано. Глядя только на класс Question, об этом никак не догадаться. Тут могут помочь абстрактные методы. Если все наследники класса обязаны реализовать какой-то метод, то надо объявить его как абстрактный метод в базовом классе. Тогда унаследоваться, не описав этот метод, будет нельзя. Ну и будет сразу видно, что мы обязаны добавить такой метод в класс-наследник. А ведь у меня там так и есть:
abstract class Question { ... abstract function checkAnswers($questions, $answers); }
>>953211 Наркоман штоле сука, у тебя в >https://3v4l.org/fd5qV у квесчена ни одного метода нету Ну и если мы тут дрочим на правильное ооп, то тут вообще творится какой-то форменный пиздец. В конце один из вопросов принимает в себя массив всех вопросов, одним и тем же методом проводит санити чек, сверяет ответы, печатает, играет на балалайке и вышивает крестиком. По хорошему, у тебя должен быть класс, грубо говоря, игры, который и будет делать то, что сейчас делает checkAnswers, а один отдельно взятый вопрос должен только говорить, правильный ли ему вариант ответа предложили, или нет. Баллы-хуялы тоже должна играть менеджить, а не один ответ.
Сайт отличный, у него даже есть вкладка "VLD opcodes", которая показывает, в какие опкоды компилируется программа. Опкоды - это низкоуровневые инструкции (вида "взять число из переменной и прибавить к числу на стеке") в которые преобразуется программа, перед тем как ее выполнять.
>>953216 >>953234 Ой, ребята, извините, я не разобрался с тем увалом просто. Почему-то он при сохранении выдал другую ссылку: https://3v4l.org/bIDqI Или я что-то напутал, извините. Советы учту ваши, сейчас пока не менял то, что было вчера сделано.
Где можно прочитать, как работает SteamAPI, чтобы я мог управлять аккаунтом: смотреть свой инвентарь, принимать и передавать предметы на другие аккаунты?
>>953484 Для работы с стим апи тебе в первую очередь нужен ключ, который получается тута http://steamcommunity.com/dev/apikey Авторизация работает как обычный OpenID провайдер, так что найди библиотеку, которая работает с OpenID, если лень разбираться, и хоть на си, хоть на пыхе, хоть на аллахе пиши, получай свой токен, и делай хттп реквесты. А вообще ты хуесосина очередную ебливую РУЛЕТОЧКУ КСГО ИЗИ ДЕНЬГИ пилишь, так что желаю тебе рака яиц и больше помогать не хочу.
Сука, накидал пару методов в некий класс за 5 минут, потом джва часа искал почему не работает некая хуйня, оказалось в конфиге закомментил то что нужно для ее работы зачем-то и забыл нахуй, потом искал еще джва часа почему из запрос не проходит, прогуглил полинтернетов, оказалось что вместо INSERT было INSER. В итоге полдня проебано и ничего не сделано. Блять.
>>953544 Ты пишешь в блокноте, поэтому иде тебе не могла подсказать насчет синтаксической ошибки и отключил сообщения об ошибках, поэтому реакция бд на твой запрос в стиле "что такое INSER нахуй начальник выпустите меня я не буду с этим запросом сидеть" тоже до тебя не дошла?
Здоровенько вам в хату. Излагаю суть проблемы: скачал PHP Version 5.6.30. Дошёл до уроков про ООП. Но у меня никак не работают функции mb_internal_encoding() и mb_strlen(). На всем форумах говорят скачать php_mbstring.dll и в файле php.ini разкомментировать extension. .dll у меня уже было в папке ext, с .ini тоже разобрался (кстати, почему их два?). А всё равно ничего не запускается.
>>953581 Учимся дебажить пхп для самых маленьких, ебанарот. Хуяришь файлик в котором написано <?php phpinfo();
исполняешь его, ищешь во-первых mbstring и смотришь, что про него сказано, во-вторых ищешь loaded configuration file и смотришь из какого именно пхп.ини твое пхп берет настройки (да, оно проверяет в нескольких местах, дил виз ит) > (кстати, почему их два?) production и прочие версии, это пресеты более безопасных настроек для продакшена, в отличии от разработки, и тп.
>>953610 Ну вот, в этом твоя проблема. Ты вносишь изменения в конфиг файл, который пхп даже не читает. Почему оно его не читает, это уже другой вопрос. Начнем с тупого: Ты уверен что у тебя файл называется php.ini, а не php.ini-dist, например?
>>953610 Алсо апач на винде это вообще адов спермоцирк В том же пхпинфо выше у тебя будет Configuration File (php.ini) Path, это путь, где система сейчас ожидает увидеть инишник, если там C:\Windows, значит пришло время ебаться с конфигом апача, который настолько охуевший, что PHPIniDir может хотеть чтоб ты написал "C:\php\zalupa", а может хотеть "C:\php\zalupa\"с трейлинг слешем в конце, а может хотеть слеши "/" вместо "\". У меня уже пичот от этой хуйни, как вспоминаю.
>>953628 >>953626 Оно не так работает, бака. Пхп хочет увидеть файл который называется php.ini, поэтому если ты хочешь использовать девелопмент конфиг, ты берешь файл -development и ПЕРЕИМЕНОВЫВАЕШЬ в php.ini
>>953638 Кто знает, ты при установке пхп должен был указать директорию, где она ищет инишник. Может исправится, может нет, на крайний случай можешь засунуть инишник в то место, которое в пхпинфо указано как Configuration File (php.ini) Path
>>953653 Спермовеселье на спермовинде, хуле. Сам на ней сижу Да, это нормально, если ты скачал архив, значит кто-то другой скомпилировал его за тебя и указал эти настройки за тебя. Ну и переменные среды в винде тоже не прописаны, очевидно. Если у тебя не хочет читать инишник из дефолтной директории, можешь поебаться с реджистри ключами http://php.net/manual/en/configuration.file.php
>>953670 Так ты эцсамое, у тебя по пути D:\sperma\php5\php.ini есть теперь? В той же папке, где php.exe и прочая куча файлов, без продакшенов-хуякшенов в имени, просто пхп.ини? И дальше Loaded Configuration File (none) ?
>>953675 И чем тебе не нравится? Просто пока ты нуфаг у тебя куча времени на это уйдет, а потом оно само собой все придет. Или почитай уроки ОПа, я уж не знаю куда проще чем у него разжевано.
>>953689 Хуямп. Если ты их, как говоришь, выучил, то примеры того, зачем они нужны, должен был видеть в учебниках. Они нужны, чтоб разбивать твою систему на логические компоненты, если ты в теории понимаешь, что это, но все эти примеры с котиками и собачками, наследующими класс животное, и менеджерами и уборщиками, наследующими класс сотрудник это какая-то невнятная хуйня для тебя, то никто тебе не скажет магические слова, которые ВНЕЗАПНО обьяснят тебе, что такое классы и зачем они нужны. Гугли любые задачки по ООП и решай их, пока не почувствуешь сам, зачем.
>>953705 Тут у человека с одним конфигом проблема, а ты предлагаешь ему целый стак из технологий навернуть, которые непонятно как работают, и вообще хер знает с какой стороны к ним подойти, если что-то сломается. Нюфане надо не только язык изучить, но и среду, в которой он вариться будет, тоже, даже если придется лишнюю неделю угробить на возню с конфигами и вырывание волос из жопы с воплями да почему ты не работаешь сука не могли всё проще сделать, в будущем окупится.
>>953711 Если не ньюфаг, то почему элементарно не можешь проверить наличие расширения или хотя нагуглить как это делается? >>953717 На примерах типа $котик->рычи() и правда тяжело разобраться в ООП.
>>953731 Я вообще не он, я на твой совет отреагировал. Он же ничему не научится и не поймет вообще сути работы вебсерверов, если подсядет на игру ксампов и опенсерверов. Там развертка руками простейшая 10 минут всего, без изощренной ебли с конфигами, обо всем почитать можно, хоть на винде, хоть на линухе, хоть на аллахе. А да хуй с ним, зря влез только.
А, тогда другой случай. Опять же, открываем мануал, главу "Установка" ( http://php.net/manual/ru/install.php ) и смотрим, как определяется путь к php.ini при запуске в командной строке:
> Директория веб сервера (для SAPI модулей), или директория PHP (иначе в директории Windows).
Звучит немного странно, потому я для верности посмотрел английскую версию:
> The web server's directory (for SAPI modules), or directory of PHP (otherwise in Windows).
Соответственно вопрос, куда ты положил php.ini? В ту же папку, что и php.exe? И он точно называется php.ini? Если редактировать файл блокнотом винды, то он может добавлять .txt
>>953742 >Слеши должны быть прямые. Это написано в самом конфиге английскими буквами. Угумс~, и в всем конфиге стоят прямые слеши. Кроме ссаной PHPIniDir, где у меня стоят обратные. Если я сейчас пойду и поставлю там прямые, она перестанет работать. В LoadModule стоят прямые, в PHPIniDir обратные, иначе нихуя не работает. Почему - я до сих пор не знаю.
>>953736 > Он же ничему не научится и не поймет вообще сути работы вебсерверов, если подсядет на игру ксампов и опенсерверов. С тобой можно согласиться. Да только вот все равно дальше чем "браузер отправляет запрос на сервер - сервер возвращает ответ" он не разберется, лол. И смысла в начале глубоко копать я считаю нет, без какого-либо опыта в разработке оно будет мертвым грузом ему. Давайте еще учить ньюфагов конфигурировать апач, лол.
Няши, у меня к вам вопрос. Сам я в php не умею пока что, могу немного в плюсыООП, STL, Win32 API, и совсем чуть-чуть во всякое другоенастолько чуть-чуть что нет смысла называть.
Подскажите, реально ли запилить такое за месяц-другой, с учётом того, что свободное время у меня есть. Стоит ли писать движок с нуля, или использовать CMSесть ли для них годные реализации фриланс биржи? В общем, направьте на путь истинный, если не трудно.
Планирую запилить небольшой магазин чтоб хвастаться работодателям и заказчикам. Бекенд будет на yii, причем в виде REST api, а фронт будет на реакте и будет выполнятся еще на сервере (изоморфизм и все дела). У меня в голове это все выглядит вроде как вполне круто (всякие мобильные приложения будет легко подключать к бекенду и т.д), но как оно будет на самом деле абу его знает. Собственно как вам такая идея, стоит ли тратить на нее время?
Добрый вечер, такой вопрос: собирай данные с клиентской стороны через serializeArray(), потом формирую объект через .reduce и отправяю кусками аяксом, проблема в том, что прилетают побитые ключи как на пике 1. Код функции отправки на пике 2. serialize() не подходит так как возвращает строкове представление, formData поддерживается не всеми браузерами. Подскажите как пофиксить ключи либо как можно ещё собрать данные из формы в массив-объект.
>>953551 >>953552 Я пишу в иде и внутри кавычек, где текст запроса, иде ничего не предлагает. Сообщения вкл, было что-то вроде sphinxql: unexpected IDENT near blalala. Естественно я полез в доки сфинкса что за идент и вообще, потом полез в консоль, и только потом случайно увидел что буковки то не хватает. Вобщем смысл рейджа в том что я просто в глаза продолбился полдня.
>>953787 Дефайн "тебе предложили запилить". Верстка и дизайн тоже на тебе? Хуярить будешь в одиночку, а спрашивать будут как с высокобюджетной команды. И самое главное - есть ли тех заказ и насколько он четкий и дерзкий. Если быстро новые технологии осваиваешь и не будешь тупить с понятиями роутинга, контроллера и прочей хуйни, ну за два месяца биржу сможешь сделать, эз ин там можно будет размещать обьявления, создавать аккаунты, писать заказчикам и оставлять отзывы. Если же весь заказ звучит как "сделай как вон там ёпт, ну ты ж компуторщик", то нахуй и впизду, просто завалят деталями, прикрути посредников, логи, рефанды, комиссии, десять разных апи оплаты, небо и аллаха. И всё за два месяца, да. Насчет готовых решений для такой хуйни ничего не скажу, увы.
>>953787 С твоим опытом, мне кажется, если ты чего и сделаешь то это все равно дерьмо какое-то будет. CMS-ки тут вряд ли подойдут, лучше уже фреймворк какой взять
>>953801 var dataToSend = {} $.each(mySerializedArray, function(k, fieldData){ dataToSend[fieldData.name] = fieldData.value }); отправляешь серверу JSON.stringify(dataToSend) на сервере соответственно json_decode'ишь то, что получил
>>953839 Что у тебя до serializeArray происходит, ты уверен что данные до отправки на сервер это красивые пачки key value пар? Логируй данные на каждом этапе трансформации, хуй знает, что тут ещё сказать. Ну и ещё >serialize() не подходит так как возвращает строкове представление как что-то плохое, $meow = array(); parse_str($_POST, $meow);
Прямо сейчас читаю мануал для PHP, в жизни ничего на нём не писал.
Есть вакансия, которую я хочу занять, требования: "C++, Perl, PHP". Пишу на плюсах, с Перлом знаком. Не совсем понятно, что имеют ввиду, когда говорят PHP, так как без HTML или фреймворка это ничего не значит.
Перед тем, как буду откликаться и рубить правду матку и просить тестовое, спрашиваю у вас: что имеют ввиду, когда говорят "PHP"? Zend Framework кокойнить?
>>953864 PHP имеют в виду PHP. Это как спросить что имеют в виду, когда говорят "С++"? QT кокойнить? Хуй знает, может фреймворк, может инхаус решение, может мейнтейн легаси говна, может всё вместе.
>>953847 Да, структуру я не менял, до этого данные отправлялись обычным постом без ajax и на бэкенде был многомерный массив, сейчас мне надо разбить отправку на мелкие порции. >как что-то плохое, >$meow = array(); >parse_str($_POST, $meow); Изначально форма была не особо большой, сейчас модуль вырос и передается единомоментно 1200 переменных, после serialize() я не смогу разбить строку таким образом, чтобы потом собрать целостные данные на PHP, поэтому я разбил массив на куски и отправляю их порционно по порядку (порядок тоже важен)
> Бекенд будет на yii, причем в виде REST api, а фронт будет на реакте и будет выполнятся еще на сервере (изоморфизм и все дела)
Изоморфизм подразумевает, что на сервере код будет на Node.JS и Yii тогда не подходит. Как ты это себе представляешь?
Мое личное мнение - выделение REST API это лишнее усложнение кода, так как во многих случаях проще написать 1 кусок кода на сервере, генерирующий страницу, чем 2 куска (генерирующий данные + код для фронтенда, интепретирующий эти данные).
Ты как-то все переусложнил. Во-первых твой код не позволяет слать массивы с именами вида name[], во-вторых, какой смысл добавлять дополнительное перекодирование в JSON и обратно, если данные можно отправить напрямую?
Усложнение кода ради усложнения и модного 5 лет назад слова JSON.
Без ООП, MVC, фреймворка, баз данных SQL это ничего не значит. Если есть время, можешь порешать наши задачки в ОП посте, рано или поздно все вышеперечисленное освоишь.
Ты что-то где-то переусложнил. В PHP конечно есть ограничения на число входных данных, они настраиваются в php.ini, но тебе лучше бы подумать, как слать меньше данных за раз.
>>953896 >Что делает splice(0, 105)? ты просто выкидываешь част данных? Не выкидываю, я из переданного массива беру 105 первых элементов и передаю их в пост, дальше рекурсивном через промисы передаю остаток первоначального массива обрезая по 105 элементов за каждый виток рекурсии. >как выглядит POST запрос (на вкладке Network), какие там данные Пик 1 - что возвращает serializeArray() Пик 2
>>953899 >но тебе лучше бы подумать, как слать меньше данных за раз. Минимум затрат по времени это просто слать данные кусками. Если менять способ сохранения - мне придется как минимум менять не только способ сохранения но и всю логику модуля, на что уйдет намного больше времени.
>>953896 С php-v8 можно ебашить изоморфизм на пхп, но ящитаю слишком сыро и экспериментально, так что нахуй не нужно. Разбить на фронтенд и рест апи в принципе норм тема, если у тебя интерактивности дохуя на странице, магазины как раз из этой оперы.
>>953905 Нет, проблема была не в этом, проблема в обертке была { data : chunk_data, ... } почему это при отправке оборачивало часть ключей в [], отправил просто как chunk_data и прилетела нормальная структура: пик >>953906 parse_url
Я понял почему меня так бесит ваш учебник из шапки. Там все наисано для вывода в эмуляторе? Я все через браузер делаю, и вот возик вопрос как разделять эти выводы, вот сейчас чита про ооп классы и там есть такая хуйня padRight, padLift вот они для браузера или для эмулятора? Гуггл хуйню рыгает, и как вообще проверят куда можно выводить результаты программы?
>>953899 ОПчик, не выебывайся. JSON был "модным" лет пять назад, сейчас это нативно поддерживаемый стандарт. В жкверивском аякс методе много подводных камней с отправкой урлэнкодед массивов из массивов, особенно если оставить dataType и contentType по умолчанию, так что если мне надо заниматься диагностикой по снипету кода из трех с половиной строк, я его пережму в жсон и не буду заниматься микрооптимизациями. Какое отношение имеет >Вы бы изучили сначала multipart/form-data и apllication/x-www-form-encoded прежде чем JSON советовать. к посту >>953847 я вообще не понимаю.
>>953930 "смеющаяся над долбоебом Саша Грей* Эмулятор-хуятор, там всё можно на Ideone.com делать, можно на Apache+PHP+IDE/Блокнот/какое дерьмо по вкусу.
>>953930 Какой эмулятор, чего вообще? Хоть бы где ты запускал, echo и подобные будут куда-то печатать, в документ для браузера, в stdout, в твой эмулятор, что бы это не было.
>>953930 Браузеру можно сказать что бы выводил ввиде обычного текста. Для этого нужно отправить http заголовок. Добавь в начале скрипта ДО любого вывода строку: header('Content-Type: text/html; charset=utf-8'); Правда я не уверен, что кто-нибудь понял что ты хочешь.
>>953997 В ивентах написано по какому урлу находится скрипт, который их обрабатывает, ф12 твой лучший друг и всё такое. А по теме могу отметить, что ты используешь event.target в обработчиках, и в этом случае ничего плохого в этом нету, но когда ты начнешь создавать элементы динамически и биндить к ним ивент хендлеры, незнание разницы между event.target и event.currentTarget укусит тебя за жопу.
Вообще, JSON тут имеет смысл передавать, так как у него 1200 полей, а у PHP есть ограничение на число элементов в POST, и подозреваю, онопо умолчанию ниже.
Еще есть ограничение на длину URL, 1000-2000 байт, если используется метод GET.
Но если большого числа полей нет, то никакого смысла использовать JSON для данных формы нет. Если писать код праивльно, то все должно передаться нормально.
Ну и использование JSON усложняет код. Например, ты должен строить многомерные массивы, которые пол умолчанию за тебя строит PHP при разборе POST-данных.
> В жкверивском аякс методе много подводных камней с отправкой урлэнкодед массивов из массивов, Это называется "лень читать документацию" и по моему лучше ее читать, чем усложнять код без надобности и лепить костыли.
> так что если мне надо заниматься диагностикой по снипету кода из трех с половиной строк, я его пережму в жсон и не буду заниматься микрооптимизациями. Это не оптимизация, а отладка и исправление ошибок. Данные из serialize() и serializeArray() можно передавать в $.ajax в поле data, ничего сложного в них нет, и content-type для них по идее $.ajac должен выставлять атоматически (либо multipart/form-data, либо application/x-www-form-encoded)
>>954007 Дело не в большом числе полей, дело в урлэнкодинге рекурсивных структур (массивов из массивов) >Это называется "лень читать документацию" А вы таки не повегите, но оффициальная тм документация жквеги гекомендует использовать json во избежание всякой хуйни как газ в таких случаях >Это не оптимизация, а отладка и исправление ошибок. Нет, как раз рекомендация запаковать в джейсон это поиск ошибки, исключим хуйню при передаче, будем искать хуйню при создании, а аргументы уровня "зачем тут кодировать чтоб на сервере ещё раз раскодировать", это как раз микрооптимизации. Вас что, хипстеры макбуками избили, с таким джихадом против джейсона?
>>954029 Если совсем примитивно - фронт контроллер это единственная точка входа в твою программу, какой бы урл у тебя не запросили, он придет к фронт контроллеру. Вот приходит тебе на сервер реквест mypage.com/images/nigra.jpg Фронт контролер создает диспетчера и передает ему этот запрос. Диспетчер вызывает роутер, передает ему этот реквест и спрашивает, что он о нем думает. Роутер сравнивает его с списком роутов, находит роут "/images/*.jpg" и говорит обратно диспетчеру "да у нас же картинку запросили, ебать" Диспетчер говорит "понял, вызываю спеца по картинкам" и вызывает отвечающий за картинки метод контроллера (не путать с фронт контроллером) сайта Тот уже в свою очередь что-то делает, ищет, существует ли в базе данных запись о такой картинке, хуемое, создает респонс, куда пакует картинку, выставляет хедеры, и вся эта ссань отдается обратно фронт контроллеру, который и отдает респонс в твой браузер.
почему часто вижу, как аноны оценивают сроки выполнения всяких заказов месяцами? я для себя написал интернет-магаин резиновых хуев категориями, описаниями, корзиной, регистрацией и всем осталтным с админской панелью за две недели, а дизайн еще неделю делал. И это я кодил часа по 3 в день. Чем коммерческие проекты такие сложные и большие?
>>954376 Не все заказы - магазины. А магазинчики в большинстве своем покрываются функционалом готовых цмсок, их хоть жопой жуй, это уж твое или заказчика желание писать самому так то.
ну, ту же фриланс биржу выше в неск.месяцев оценили, хотя принцип, на мой взгляд, примерно тот же. Только каждый юзер-заказчик добавляет товар(заказ), и прочие мелкости
>>954389 >прочие мелкости Дьявол в мелочах кроется, большая часть функционала запиливается быстрее, чем отдельные микрописечки в нем, с которыми возникают проблемы. Потом качество кода это не шутки. Можно нахуярить быстро, и даже самому нормально им пользоваться, в том числе не замечая очевидных косяков, а как только в руках юзера окажется, который немного по другому мыслит так сразу и пойдет отваливаться все к хуям. Заказчик без правок не обойдется никогда, даже если ты с ним кровью скрепишь договор, что при первой же просьбе о правке он должен будет зарезать всю свою семью и скормить свой хуй собаке. Правки будут все равно, когда он уже глазами, а не умозрительно, на проект посмотрит. Есть такая тема, как работа со сторонними сервисами. Не всегда это впиливается быстро и прозрачно. На цмске можно брать не ссыкуя большую часть заказов с магазинами, и то понимая, что скорее всего придется плагинами своими докидываться, кроме как верстку натянуть.
>>954389 >>954398 Качество кода это особенно не шутки, если тебе придется потом сопровождать этот код, когда от тебя потребуют впилить фичу потом через полгода, а ты во-первых нихуя не понимаешь как эта ссань вообще работает, во-вторых у всех компонентов настолько tight coupling, что tighter только писечка у лолей из хентая. Зато в свое время за две недели по три часа в день справился, да.
https://3v4l.org/GE6vo - ну и как мне теперь вызвать этот паблик метод у этих классов - checkAnswers($questions, $answers);? Пробую форычем, пробую просто $questions[0] - это не то. Упустил суть, блин, помогите!
С eval вот какая проблема - при смене ip он меняет ссылку и при простом запуске кода. В тот момент, когда я обкакунькался, то же было, походу.
>>954433 Да забей ты на эти онлайн иде, срсли. Ставишь пхп, кидаешь свой код в файлик index.php, в папке с ним в консоль делаешь php -S localhost:8000 и всё, рефрешь http://localhost:8000/ в браузере и смотри на изменения. По коду - может ты опять что-то не то отправил, но у тебя тот же пиздец остался, что и в прошлый раз - checkAnswers это метод одного отдельно взятого вопроса, а должен быть отдельной функцией, как и printQuestions. Ты не заставляешь один вопрос печатать все вопросы, но почему-то заставляешь один вопрос проверять все ответы. Отдельная функция проверки ответов будет обходить список из всех вопросов и список из всех ответов и предлагать одному вопросу один вариант ответа, а тот должен всего лишь ответить за себя, правильный этот вопрос или нет.
В бд хранится формулы (администратор может их редактировать). Данные для них я получаю из $_POST и валидирую их так: $а = (int) $_POST["a"]; затем использую eval. возможно ли злоумышленникам обойти сию валидацию?
>>954511 Если после этого ты будешь работать исключительно с $a, то всё хорошо. Если же ты решишь что если intval($_POST['var']) вернул ненулевое значение, то значит с $_POST['var'] всё хорошо, то тут тебя ждет приятный сюрприз. https://3v4l.org/iSovA >>954517 У них разное применение. div это, ну как сказать, технический элемент. Твой документ состоит из частей, у которых есть стили, классы, к ним прикручены какие-то данные и обработчики событий. article, header, footer, section, nav и подобное - это семантические элементы, когда поисковик индексирует твою страницу, ему похуй из каких дивов она состоит, но если ты ему подскажешь, что вот это заголовок, это главная статья, ради которой эта страница создавалась, а вон там список глав в твоей статье, ему это (по идее) будет полезно. Суть семантик элементов - предоставить другим программам, которые будут смотреть на твою страницу всякие полезные метаданные. Это не значит что вместо дивов надо верстать секшенами теперь, если чо.
>>954526 Это потому что, во-первых, хер знает что они точно делают. Если бы гугл наебашил заявление, что мол так и так, если ваш документ семантически разбит на части, то мы будем индексировать его намного выше, то адопшн пошёл бы быстрее и веселее. А во-вторых, человеческой спецификации тоже нету, описания в стиле "элемент предназначен для группирования контента по темам", ну охуеть теперь, у всех немного свои идеи насчет того, что это значит.
>>954540 >мол так и так, если ваш документ семантически разбит на части, то мы будем индексировать его намного выше, то адопшн пошёл бы быстрее и веселее. Поговаривают, что в будущем так оно и будет.
>$a <=> $b >Spaceship >An integer less than, equal to, or greater than zero when $a is respectively less than, equal to, or greater than $b. Available as of PHP 7.
>>945059 (OP) Господа, кто-нибудь работал с CodeIgniter? Я не пойму, почему при отправке аяксом мне не возвращается строчный ответ, а только цифры. НА стаке пишут, что этот фреймворк пинимает только данные в виде джейсон строки. Мне нужно через аякс динамически подгрузить данные из бд без перезагрузки страницы. Пример. var url = window.location.href; $.ajax({ url: url, type: "POST", dataType:"json", data: {"gender":"m"}, success: function(data){ console.log(data); } });
В контроллере пишу echo $_POST["gender"]; (причем если использую кодеигнитовский $this->input->post("gender") - тоже ничего) и в консоли у меня ничего не выводится. а я хочу, чтобы дата ответ подгружалась в хтмл. пробовал dataContent подставлять - ничего. притом просто вставить значение в базу данных через аякс я могу, а вот именно вернуть ответ и загрузить в хтмл через аякс - нет.
>>954701 У тебя вопрос настолько сумбурный, что я даже не понял, у тебя проблема в том, что ничего не приходит в контроллер, или что? Ты уверен что контролер вообще отрабатывает? window.location.href в качестве урла меня смущает, но может это только пример. Дампни полностью $this->input и посмотри в каком формате тебе данные приходят, если контроллер правильно вызывается.
Исходники других сайтов - это не образец, так как неизвестно кто и с каким уровнем подготовки их делал. Назначение тегов описано в спецификации HTML, но она сложная и на английском и может тебе не захочется ее читать.
Суть в том, что теги используются для смысловой (семантической) разметки. Ну к примеру, если ты хочешь каким-то тегом выделить шапку,то для этого придуман тег header.
div используется только если нужного тега не существует.
А так конечно, CSS позволяет переопределять любые свойства и можно страницу хоть одними тегами <a> сверстать, пусть люди и роботы потом мучаются и расшифровывают.
>>954650 Что тебе мешает постить в этом треде, зачем новый? Почитай первые ~200 постов треда - сплошной оффтоп из-за толпы случайных людей. Добавь тред в избранное.
>>954468 По моему опыту, проекты на том же Yii, в общем случае, такого же низкого качества, как и на битриксе, всё из-за низкого порога входа. Так что мы тут все в разной степени говноеды. А 1С-Битрикс тем временем проводит олимпиады с весьма нескучными задачами. Вот пример: На вход подаётся файл, в котором через запятую перечислены следующие параметры: текущая дата, начало/конец рабочего дня, выходные (номера дней недели), даты выходных в компании, количество задач, время выполнения каждой задачи в часах, приоритеты задач. Нужно вывести времена окончания каждой из задач с учётом всех выходных, праздников и так далее. К примеру, для таких данных: 23.12.2016 12:15:00 9 18 6 7 01.01.2016 23.02.2016 2 9 1 10 20
Ответ: 23.12.2016 13:15 26.12.2016 13:15
Объясняю ответ: начинаем с отметки 23.12.2016 12:15:00, вторая задача (та, которая делается за час) приоритетнее первой, поэтому выполняем её, выводим 23.12.2016 13:15. Время на выполнение второй задачи - 9 часов, до конца рабочего дня - 4 часа 45 минут. 24-е и 25-е февраля - суббота и воскресенье (6 и 7 дни недели, по условию выходные), пропускаем их. 9 часов + оставшиеся 4 часа 15 минут - 13:15, число мы уже выяснили - 26-е.
Это запутывает, так как можно подумать что ты хочешь найти разницу, а не сравнить числа. А тут сразу видны намерения. Плюс, он возвращает строго -1, 0 или 1.
> The header element represents introductory content for its nearest ancestor sectioning content or sectioning root element. A header typically contains a group of introductory or navigational aids.
>>954460 >Надо сделать так: внешняя функция checkAnswers принимает массив вопросов и ответов. И для каждой пары вопрос-ответ вызывает метод проверки на правильность. Вот этот метод проверки, правильный ли ответ к тесту, и должен быть описан в классах вопросов. Блин, бро, я ни хрена не пойму, какое отношение имеет проверка правильности ответа к классу Вопрос или к его наследникам? Разве не логичнее делать это всё в отдельной функции? Вот у нас массив с вопросами, но нам ведь этот метод можно применить к одному вопросу, а нужно будет в этот метод передать массив вопросов? Что за голимая байда? Вы мне втиrаете какую-то дичь!!1 Шучу Ну что за бредятина: у меня есть класс Вопрос и этот же класс работает с массивом ответов! Не лучше ли сделать тогда уж в классе Вопрос проверку конкретного соотношения ответ пользователя/правильный ответ? Вот так попробовал: https://3v4l.org/i76fY Notice: Undefined property: ChoiceQuestion::$correctAnswer in /in/i76fY on line 14 - что за перда, что тут не так? Верный ли подход?
>>954465 Браток, у меня Yii2 развёрнут, там что-то в httpd.config прописано - пока не запускаю сейчас скрипты на локалке. Ну там реально годный сайтец, идеоне нервно курит в сторонке. Единственное - при любом запуске кода даёт новую ссылку, код поправить нельзя после запуска. Типа версии или я просто тупой.
> Блин, бро, я ни хрена не пойму, какое отношение имеет проверка правильности ответа к классу Вопрос или к его наследникам? Разве не логичнее делать это всё в отдельной функции? Примерно так и надо, но проверка одного ответа к одному вопросу - она зависит от типа вопроса и потому для разных вопросов ее код будет разный. И потому этот код надо поместить в класс.
Я же тебе написал: вот у нас есть задача проверить массив ответов на массив вопросов. Вопросы разных типов и у каждого свой способ проверить ответ. Мы должны разбить код проверки на части:
- то что общее для всех видов вопросов - вынести в отдельную функцию - то, что у каждого вида вопросов свое - поместить в класс вопроса
> Не лучше ли сделать тогда уж в классе Вопрос проверку конкретного соотношения ответ пользователя/правильный ответ?
Я об этом и писал. Объект Вопрос должен проверять только свой ответ, а не все воросы и ответы в массиве.
> Notice: Undefined property: ChoiceQuestion::$correctAnswer in /in/i76fY on line 14 Если посмотреть на класс Question то в нем нет поля correctAnswer. Почему ты к нему обращаешься в 14-й строке? Это неправильно.
>>954728 >Браток, у меня Yii2 развёрнут, там что-то в httpd.config прописано - пока не запускаю сейчас скрипты на локалке. Поэтому я тебе и говорю запускать скрипты на серваке пхп, чтоб ни с чем не конфликтовать, ну то такое.
>что за перда, что тут не так? Твой абстрактный класс это предшественник, у него нету свойства correctOption и correctAnswer, к которым ты обращаешься в том методе, потому что эти свойства появляются только в наследниках, отсюда и ошибка. Ну и ещё у тебя метод checkQuestionAndAnswer зачем-то первым аргументом принимает в себя самого себя, хоть этот обьект и так доступен через this внутри метода.
>>954728 А, и если хочешь ещё поломать голову, то ответь вот на какой вопрос - не лучше было бы в этом случае применить интерфейс, а не абстрактный класс, и почему.
>>954037 Странная схема. Зачем такое нагромождение классов? Почему в точке входа просто не принимать все роутером (там вообще класс по сути не нужен, это обычный php файл, где роутеру передается пару переменных из массива $_GET), а роутер уже отдает контроллер + метод по мапу роутов, который тут же и вызывается. Дальше весь запрос уже в полученном от роутера контроллере обрабатывается. Где смысл диспатчера и фронт контроллера? Какие-то излишние сущности получаются без четко отведенной им роли.
Я тебе советую решить все задачи в главе про ООП, так как сейчас ты пока не понимаешь, что к чему.
В этой задаче важно правильно разбить код: что-то пойдет в один класс, что-то в другой, а что-то вообще будет в отдельной функции.
Надо начать с того, что представляет и за что отвечает класс Question и унаследованные от него классы? Он представляет собой один вопрос в тесте. Он хранит информацию об этом вопросе.
Далее, что он должен уметь делать (какие у него есть методы)? Пока не понятно, потому посмотрим, что нам надо сделать в задаче.
А в задаче нам дам массив вопросов, массив ответов, их надо проверить и посчитать баллы.
Очевидно, что один объект Вопрос не может проверять все остальные вопросы, он отвечает только за себя, потому напишем отдельную функцию, которая будет перебирать ответы, проверять их, считать баллы.
Но когда мы дойдем до проверки ответа, мы обнаружим проблему. У каждого типа вопроса свой способ проверки ответа. Ну например в случае если это Вопрос с вариантами, то мы должны проверить, что выбран верный вариант. Если это Вопрос, где ответ - число, то мы должны проверить, что оно находится в определенном диапазоне.
Мы конечно можем сделать if вроде такого:
если (вопрос - экземпляр класса ChoiceQuestion) { проверить что ответ совпадает с корректным; } инчае если (вопрос - экземпляр класса NumericQuestion) { проверить что ответ попадает в диапазон; } иначе { вывести ошибку; }
Но тут есть недостаток. Что если завтра мы добавим новые типы вопросов? Этот код надо будет переделывать. Это неудобно, и ООП как раз должно решать эту проблему, а не создавать ее.
Более того, с точки зрения ответственности логично переложить задачу проверки ответа на класс соответствующего вопроса. То есть пусть у каждого вопроса будет метод проверитьОтвет(ответ) и пусть он по своему алгоритму его проверяет. И соответственно алгоритм получается такой:
для (каждой пары вопрос-ответ) { результат = вопрос->проверитьОтвет(ответ); если (результат == правильно) { ... } иначе { ... } }
Таким образом при добавлении новых типов вопросов нам не придется переписывать эту функцию проверки ответов. Тот, кто написал новый класс, обязан будет сделать в нем метод проверитьОтвет.
Твой код неправильный. Ты пытаешься добавить метод проверки в базовый класс, но это неправльно по такой причине:
- базовый класс ничего не должен знать о наследниках, так как ты сам не предугадаешь, кто от него будет наследоваться в будущем.
Соответственно базовый класс не может обращаться к тем полям и методам, которых в нем нет.
Таким образом мы разделили ответственность:
- проверка ответа на один вопрос - ответственность класса Question и наследников - подсчет очков, вывод подсказок - ответственность отдельной функции проверки ответов
Это важно понять, потому я советую тебе решить все задачи из главы ООП, чтобы полностью разобраться.
>>954746 >Почему в точке входа просто не принимать все роутером Это в любом случае фронт контроллер, если у тебя есть одна точка входа, это уже фронт контроллер паттерн. >Зачем такое нагромождение классов? Да незачем, роутер может сам быть фронт контроллером, матчить урл, сам лезть в базу данных, получать оттуда данные и тут же печатать в аутпут хтмл, таким образом он будет фронт контроллером, роутером, моделью, контроллером и представлением одновременно. Поздравляю, ты раскрыл заговор ООП жидорептилоидов, классы и фреймворки придумывают просто чтоб объебывать тебя на бабло. За тобой уже выехали
>>954693 В перле этот пейсшип есть уже лет 20, и является багофичей (специально не вводили). В использовании видел разве что в ебантяйских скриптах, обфусцированных почти до уровня однострочника rm -rf.
>>954737 >- то что общее для всех видов вопросов - вынести в отдельную функцию >- то, что у каждого вида вопросов свое - поместить в класс вопроса Общее у них - плюсуются баллы и количество правильных ответов, если правильно отвечено. Своё у них - различие в наименовании "правильного ответа": $correctAnswer и $correctOption. Я вот так сначала и хотел сделать - метод в каждом потомке класса Вопрос проверяет пункт из массивов $questions и $answers с учётом наименований своих правильных ответов. О, тупанул: мне надо просто в классе Вопрос этот метод сделать абстрактным, а в потомках реальные методы - чтобы проверялся один вопрос и один ответ, а не как у меня сначала было - проверялись массивы. Тогда каждый экземпляр будет со своим определённым методом работать. Так, пока пробую это. И вроде все ошибки должны пропасть. Пока писал это - сделал: https://3v4l.org/3CJfg То ли это, что было нужно? Вроде схватилось что-то.
>>954748 >Очевидно, что один объект Вопрос не может проверять все остальные вопросы, он отвечает только за себя, потому напишем отдельную функцию, которая будет перебирать ответы, проверять их, считать баллы. Да, вот это я сейчас схватил, уловил. >Соответственно базовый класс не может обращаться к тем полям и методам, которых в нем нет. Да, уловлено, а то я навертел несуразицы.
>>954768 Языки, в которых намешано всё на кучу, чуток процедурщины, чуток ооп, чуток функциональщины, типа пхп или плюсов, они хуево учат ньюфагов ООП, ящитаю. Если бы эту задачу человек решал на каком-то языке, где его заставили бы создавать классы и только классы сразу, ему бы пришлось создать класс Игра, в котором бы были контейнеры вопросов, у класса игра были бы методы показать вопросы, получить ответы, ну и проверить ответы интуитивно захотелось бы запихнуть туда же. А тут у нас функции которые не методы, просто висят в воздухе, понадобился способ проверить ответы - ну прицепили его к какому-то обьекту, в него масивчик передали, вообще процедурный стиль пошёл, нуачо, работает же.
Это я к чему - долбись об эту хуйню головой, дойдет в итоге. Если в процессе написания тебе придется копипастить абзацы кода и вставлять в другое место, чтоб поменять там три переменных, это знак того, что надо остановиться и подумать над иерархией ещё раз. Если у тебя есть функция, но ты не можешь решить, кто из обьектов её должен выполнять, опять таки хороший повод остановиться и подумать над схемой в целом. На листочке не стесняйся классы с стрелочками порисовать, тоже помогает.
>>954774 В целом то, но ты продолжаешь передавать в обьект самого себя $questions[$i]->checkQuestionAndAnswer($questions[$i], $answers[$i])
В методах проверки у тебя есть защитный стейтмент if (isset($this->correctAnswer)) но ничего не написано на тот случай, если он действительно не будет определен, если ты исходишь из того, что он всегда будет определен, то зачем он вообще нужен?
> Своё у них - различие в наименовании "правильного ответа": $correctAnswer и $correctOption.
Не только это, там еще может быть разный алгоритм проверки. Например, для числового ответа может быть не одно число, а диапазон, от x до y.
Именно потому, из-за разного алгоритма проверки, проверка должна быть в виде метода в классах-наследниках Question.
> public function checkQuestionAndAnswer($question, $answer) Вот здесь, если посмотреть на вызов метода, видна избыточность:
> if ($questions[$i]->checkQuestionAndAnswer($questions[$i], $answers[$i]) == true) {
Зачем 2 раза указывать $questions[$i]? Объект, на котором вызван метод, доступен внутри метода в переменной $this. То есть передавать $question через аргументы не надо.
Также, не нужен isset. Поле либо гаратированно есть, либо его гарантированно нет (и обращаться к нему нельзя), и isset не требуется.
Еще у тебя много раз повторяется $questions[$i], не лучше ли это в переменную поместить?
А так, идея верная, остается только ошибки исправить.
Также, позже советую добавить в код тайп-хинты.
Тайп хинты позволяют указать, что аргумент функции должен быть определенного типа (например быть объектом определенного класса или его наследника). Тайп хинт делает код понятнее (так как видно какого типа переменная) и надежнее (так как PHP не позволит передать что-то неразрешенное и ты сразу увидишь ошибку). Используй их везде.
Обрати внимание, что php7 усовершенствовал систему тайп-хинтов - теперь можно в их качестве указывать примитивные типы вроде int/string, а в php7.1 стало можно указывать тайп-хинт для возвращаемого функцией значения: https://habrahabr.ru/post/267799/ (увы, возможность вернуть null пока не реализовали, так что ждем)
Не соглашусь. Простые скрипты удобнее бывает просто как последовательность команд записать. А в той же Яве начинающий должен изучить классы до того, как напишет Hello World. Язык явно не для начинающих (хотя надо вспомнить что он пришел на замену C++ и в сравнении с ним невообразимо лучше. Вообще, Си и Си++ это боль и мрак).
Так что делать класс ради того, чтобы он был, не требуется.
>>954792 Ну типа спецификация усорта говорит что туда должен приходить именно больше, меньше или 0, так что оптимизации хуемое.
>>954795 >Простые скрипты удобнее бывает просто как последовательность команд записать. Я где-то говорил из пхп яву сделать? Ява вообще параша та ещё. >А в той же Яве начинающий должен изучить классы до того, как напишет Hello World. И если ты хочешь научить начинающего именно оопшной парадигме, это очень хорошо. Да, скорее всего, тебя будут учить говорить public static void main как магическому заклинанию, которое надо произнести в начале, чтоб твоя программа заработала, щито поделать. Что бы ооп-сектанты не утверждали, это совсем не интуитивно понятная вещь, которая вот прямо охуенно позволяет описать реальный мир, это такой же маняаутизм, как и все остальные модели, в который надо въехать, а чтоб в что-то въехать, желательно, чтоб у тебя было поменьше альтернатив, потому что "А зачем, и так же работает"-мышление это просто адов пиздец, который приводит к тому, что люди пишут хуйню, а раз их хуйня работает, то убеждаются в том, что они всё делают правильно и в штыки воспринимают пожелания не писать хуйню. >Вообще, Си и Си++ это боль и мрак Я тебя найду и укушу, насчет крестов согласен.
А почему насчет Си не согласен? Чего стоят только пляски с подключением dll, которая скомпилирована с одной версией рантайма Visual Studio, к exe-файлу, который скомпилирован другой версией. Я уж не говорю про случаи, если они разными компиляторами скомпилирваны. Это же надо так безнадежно все сломать было.
Ну и отстутствие менеджеров пакетов, допотопные системы сборки с кучей препроцессоров, это же боль и мучения сплошные.
Я тебе чисто по секрету скажу, что нормальные люди crt в винде не юзают. Алсо, никто тебя не заставляет линковать либу - загрузил, понадергал адреса мокрописек и вызывай по указателям.
>>954804 Маленький и очень статический, соответственно шустрый как говно язык. Содержит одну парадигму, по минимуму абстракций, и при его минимальности, на нем можно написать всё. Насчет рантаймов - все претензии к мс, не одной вижуал студио живем, знаете ли. Менеджер пакетов и всё такое, это очень мило, но их отсутствие это не боль и мрак, ничего в этом мире не бывает бесплатно. За каждый import sdelatzaebis, за каждый джиттер и автоматический менеджмент памяти надо платить чем-то ещё, поэтому у нас и есть разные языки для разных областей.
>>954806 Более того, если тебе от yoba.dll нужно две процидурки (то есть ты не пишешь dll-прокси типа читов для кваки, запиханных в opengl32.dll) - то и необязательно грузить адреса всего шлака.
>>954808 Выше смотри, рантайм нормальные люди вообще ебут по минимуму. Потому что почти все, что умеет это говно мамонта из белл лабс - умеет и ОС, только лучше.
Может ты не понял, в чем проблема. Проблема в том, например, что есть 1.dll скомпилирована VS2003, а 2.dll - VS2008 то у них у каждой может быть свой менеджер памяти и куча, и не только.
А что насчет dll, собранных разными компиляторами?
Чтобы они были совместимым, должен быть какой-то единый ABI. Таблиа импорта в dll определяет по моему только адреса функций, но знать только адрес недостаточно.
>>954816 >strdup Есть виндовый аналог >fopen Вообще нахуй никому не нужен что в винде, что в никсах. Не умеет в опции типа кэширования, синхронного/асинхронного ВВ по желанию, мапинга в память и так далее.
>>954814 Вот как раз чит под контру я и писал. При этом контра скомпилена VS6, системная либа по-моему 2008, а моя дллка, подменяющая пару-тройку функций - gcc.
>>954814 Так мы про крестовую парашу или что? Если хочешь кидаться объектами, или выделять через new в одном рантайме и deleteить в другом, ну готовь вазелин, хуле. С стайл апи таки попроще и поинтероперабельнее будет.
Есть смысл менять mod_php на php-fpm, если не предполагается статический файлов? На хосте крутится soap веб сервис на soap server от php для импорта-экспорта, больше ничего. Статикой отдается только wsdl и xsd файл, который не так часто нужно заново грузить. Вызовов самого soap сервиса с гигабайтами разных данных очень много, с разных ip. Выигрыш от php-fpm будет какой, или стоит оставить mod_php?
>>954833 у фпм меньше потребление памяти и проца. Кроме того, сысоев впереди апача/фпм нужен не столько для отдачи статики, сколько для того, чтобы быстро забрав у тормозного бэкэнда данные, потом отдавать их клиенту на той скорости, на какой позволяет его канал. Количество процессов у сысоева от этого не увеличится, в отличии от пэхапни с форками.
>>954711 данные вообще не приходят. притом, если я отправляю не джейсоном, а обычной строкой, то при вызове echo [название переменной с пост запросом] выводит аж всю хтмл страницу. наверное тип возвращаемых данных надо указать, я хз, как там пхп тип указать? по-моему это анриал. или в джейсоне возвращать? у меня тока цифры выводятся при передачи джейсоном данных через аякс, а строки = нет((
>Это конечно хорошая идея, добавить поддержку gzip, но тогда надо дописать генератор сжатых версий файлов (и тщательно протестировать это в разных браузерах). В условия, кроме проверки наличия сжатого файла, стоит еще добавить проверку существования оригинала.
Что понимается под генератором сжатых версий? В интернетах я встречаю мнение, что .htaccess достаточно и не надо себе голову делать лишними скриптами. Все что я нашел по этой теме датируется древними годами.
>Я не помню, давал я тебе такую задачу или нет. Чтобы лучше понять идею MVC, надо бы сделать альтернативный контроллер и вью для той же задачи. А именно: надо сделать скрипт для командной строки, позволяющий загружать файлы в файлообменник с локального диска и выводящий ссылку (ссылки) на них.
К этому я вообще не знаю как подойти. Если это cli, то как и зачем вью? И что будет из себя представлять контроллер? Мне в голову кроме допустим switch с кейсами в виде опций командной строки ничего в голову не приходит.
>>954900 То, что ты отправляешь, это не json data: JSON.stringify({"krokodil": "zalupa"}) Дампни весь весь пост массив, весь инпут и посмотри, приходит ли туда что-то и под каким индексом. Код контроллера и скрипта нормально запости, в конце концов
>>955080 Удели внимание изучению языка и релейтед технологий. С помощью фреймворка ты можешь написать цмс, с помощью цмс ты можешь делать только то, что предусмотрел автор цмс, если функционал понадобиться расширить, то см. в начало. Сколько платят натягивателям верстки на цмс понятия не имею, но почему-то мне кажется, что не шибко много.
Аноны, нужна ваша помощь, не понимаю как в printf вставить переменные или какой либо код. В интернете не смог найти как это сделать. Пытаюсь так, но не получается:
$s = 731656; printf(' Эту страницу посетили ',$s,' раз');
p.s. Знаю что для данного примера проще использовать echo, но работаю с printf и в нем нужно разместить код.
Лушче использовать require которое вызывает ошибку при отстутсвии файла. А так да, эта система предупреждений в PHP безнадежно плохая, должны быть только исключения.
Так, до конца решил задачку на наследование от класса Вопрос: https://3v4l.org/cgP74 Теперь с $deviation в типе вопроса с указанием числа.
Перехожу к "Вектору", и сразу появились вопросы. 1. Нужен ведь класс Компания? 2. Нужны ведь класс Департамент и его наследники - отдельные департаменты? 3. Нужны ведь отдельные классы Менеджер, Маркетолог и так далее?? Это ж сколько будет кода, я стесняюсь спросить... 4. Как создавать экземпляр класс Менеджер, например? Функцию отдельную, у неё в аргументе количество манагеров и их ранг, такое? На верном ли я пути?
Планируется ещё: Написать пагинацию по мере появления тредов Поиск с google-like(?) синтаксисом запросов Может кто-нибудь подскажет готовое решение? Свои стили и скрипты, возможно Технические исправления
Ещё у меня есть отличная идея: Я видел как тут аноны собираются в конфочки, поэтому я подумал что можно написать наш собственный мессенджер внутри этого сервиса. Что скажите? Стоит сделать?
Сервис абсолютно сырой и наверняка содержит большое количество багов, поэтому любой фидбэк будет полезен. Если можно, с готовым решением Фидбэк можно написать сюда или мне на почту [email protected]
Один большой баг уже удалось найти: Иногда при обновлении тредов в БД добавляется тред с записью NULL и созданием поврежденного json-файла с пустым именем. Установить причину бага не удалось т.к. такое поведение было замечено лишь однажды.
Баг приводит к крашу индексной страницы. Так что если вы увидите пустую страницу, то это поэтому.
Я правильно понимаю что сначала нужно создать адрес а затем аккаунт, и потом делать с этим всё что я захочу? А где тут пароли или то что аутентифицирует кошелек?
>>955423 >всего за полгода Мой первый коммит студентов был 9 декабря 2015. С какой конкретно точки я продвинулся за эти пол года? Могу я узнать ваш гитхаб?
>>955441 >уеб Оценил иронию. Не могу сказать что это не правда. Буду стараться ещё больше.
protected function getFields() { return ['post', 'displayname', 'duration']; }
foreach ($this->getFields() as ...) { ... }
Более того, этот код (вынесение свойств из массива и заполнение объекта) можно сделать в базовом классе ActiveRecord. И там же можно сделать метод для генерации INSERT'ов.
Ну и еще в AR проблема с тем, что PDO надо передавать в каждый объект File. Часто разработчики AR просто отказываются от DI и делают где-то глобальный метод для получения зависимости.
Ну и конечно, стоит помнить, что есть Доктрина, которая конечно притормаживает иногда, но зато избавляет от необходимости вообще писать код маппинга.
Я не предлагаю делать так же, просто хотел показать примеры других реализаций.
Генерацию всех путей и URL стоит вынести в хелпер, просто в статические методы.
Для страницы 404 очень желательно выдавать HTTP заголовок 404. Всего одну строчку header() надо добавить.
Threader лучше было назвать ThreadController.
> $count = $post->getCountByThread($somethread->number); Это возможно стоило встроить в класс Thread, чтобы можно было вызывать $thread->getPostCount();
Также, если интересен вопрос оптимизации выборки, то тут придется усложнять схему БД. Сейчас, чтобы вывести посты на главной, приходится делать много запросов, и они не очень эффективные (например, подсчет числа постов в каждом треде отдельно).
Можно добавить в тред поля для хранения числа постов, а также ссылки на последние посты (либо сделать это через отдельную таблицу связи тред - последние посты). Соответственно данные можно будет выбрать в 2 захода: выбираем треды, затем собираем из них id ОП-поста и последних постов и выбираем их одним запросом. Но это конечно немного усложнит работу с базой, так как при изменениях надо обновлять эти дополнительные поля. Но зато снизит нагрузку на базу при выборке.
Также, строить цепочку постов через выбор всех постов в БД очень неэффективно. Лучше сделать таблицу связи "многие-ко-многим", связывающую посты, может быть такого вида:
from_id | to_id
или такого
from_id | to_id | depth
То есть мы берем пост, и для каждой ссылки в нем вставляем записи в таблицу связи. Можно вставлять только ссылки из самого поста, тогда надо делать несколько SQL запросов, чтобы построить цепочку, а можно вставлять ссылки еще и на посты с большей глубиной вложенности, тогда цепочка выбирается одним запросом, но таблица будет больше по объему.
В интерфейсе есть небольшая проблема: на главной странице невозможно догадаться, что с нее можно перейти в тред. Стоит после ОП поста добавить ссылку вроде "Просмотреть тред целиком" или как-то так. Догадаться, что можно кликнуть на номер треда, невозможно.
И еще, может стоит добавить опцию, чтобы сохранялись и выводились ссылки на тред в архиве /pr/ и в архиваче, если они есть. Просто, чтобы было.
А так, прикольно, почти что отдельная доска, состоящая только из PHP тредов.
> Поиск с google-like(?) синтаксисом запросов Может кто-нибудь подскажет готовое решение?
Есть поисковый демон Sphinx, который умеет строить индексы на основе БД и искать по ним, и у меня есть старый урок, и в интернете полно инфы: https://gist.github.com/codedokode/10539366
Если сфинкс на хостинге запускать не разрешают, то можно использовать полнотекстовый индекс и поиск по нему в MySQL:
Ну и при желании можно нагуглить еще статьи. Преимущество исопльзования MySQL:
- не надо ничего дополнительно ставить - не надо настраивать индексирование
Недостатки:
- вставка и обновление таблицы влечет обновление полнотекстового индекса, и увеличивает нагрузку на базу, особенно если эти операции часто выполняются, то очень сильно увеличивается нагрузка. Но так как в данном случае никаких частых вставок нет, то это не проблема. - у сфинкса больше возможностей по настройке индекисрования и поиска, например, он умеет делать стеммииг (отбрасывание окончаний у слов, чтобы можно было искать слово в разных формах, падежах, числе, времени), поиск по части слова, в общем, много всего - умение работать со сфинксом может где-нибудь пригодиться
Оба этих способа (полнотекстовый поиск в MySQL и сфинкс) подразумевают создание индекса примерно таким способом: берутся все документы, они разбиваются на слова и строится такой индекс, похожий на таблицу:
слово | id документов, где оно встречается | позиция (порядковый номер) слова в документах
Позиции слова хранят, чтобы можно было при поиске фразы найти документы, где слова стоят близко друг к другу.
То есть строится по сути огромная таблица со всеми словами из всех документов, оптимизированная на быстрый поиск по слову. Поисковый запрос разбивается на слова, для каждого извлекается список id документов, эти списки объединяются и итоговый список сортируется по "релевантности".
При этом слова перед индексировнием можно дополнительно обработать. Например, стеммингом отсечь окончания, чтобы искать слово в любой форме.
> Я видел как тут аноны собираются в конфочки, поэтому я подумал что можно написать наш собственный мессенджер внутри этого сервиса.
Если хочется потренироваться в написании мессенджеров, советую делать его как отдельный проект. Наверно тут понадобится JS-приложение, чтобы на каждый чих не дергать сервер. Можно и без JS, но будет работать наверно не очень быстро.
> Иногда при обновлении тредов в БД добавляется тред с записью NULL и созданием поврежденного json-файла с пустым именем.
Скорее всего где-то нет проверки на ошибки. Ну то есть не удалось загрузить файл, но код все равно продолжает бодро выполняться дальше. Нужно ставить проверки и бросать исключения, если что-то не так. Обрати внимание на функцию json_decode: при ошибке в JSON-данных она просто молча возвращает NULL или false, не выдавая никаких предупреждений. Также, для file_get_contents стоит проверять результат и может быть Content-Type в http://php.net/manual/ru/reserved.variables.httpresponseheader.php
Также, картинки на дваче не хранятся вечно и надо их либо скачивать, либо не выводить.
Также, не знаю, нужно это или нет, но у меня есть кое-какие архивы с HTML-файлами тредов и картинками. Я их уже который год собираюсь выложить, но руки не доходят.
Там интересная схема. Там при создании кошелька генерируется набор случайных байт (то есть очень большое число). Это закрытый, секретный ключ, который позволяет делать любые операции с кошельком (им подписываются транзакции). Из этого ключа необратимым преобразованием генерируется открытый ключ (по моему, просто берется хеш от закрытого ключа). Это публичный идентификатор кошелька.
Соответственно когда ты создаешь новую транзакцию, и подписываешь ее закрытым ключом, участники сети, каждый, проверяют, что подпись соответствует открытому ключу и таким образом удостоверяются что ты именно владелец кошелька.
Транзакции в биткойне неотзываемые и необратимые. Если ты потерял закрытый ключ, то считай что потерял кошелек.
Если интересно, советую про все это почитать, это интересная система. Только возможно сначала стоит почитать про асимметричную криптографию, открытые и закрытые ключи.
И еще, я бы советовал выделить публичную папку и сделать ее корневой. Даже если хостинг не позволяет задать свою корневую папку, все равно обычно можно исхитриться и так закачать проект, чтобы публичной была только одна папка, а остальное было за ее пределами.
>>955449 Нет, я серьезно, ты молодец. Писать какие-то применимые в комюнити вещи всегда больше мотивирует, чем абстрактные упражнения, да и тестеров побольше наберется. That said, месенджер это совсем другой зверь, чем типичный вебсайт, с другим стаком технологий, отличных от привычного реквест - респонс - закрыть соединение цикла, если мы говорим о настоящем дуплексном соединении. Пхп вообще не очень язык для написания долгоиграющих приложений с ивент лупом. Для трех с половиной анончиков можно соорудить и решение из существующих технологий с помощью старого доброго поллинга, но и тут тебе понадобится продумать фронтэнд на жсе и апи твоего сервера, с которым он будет общаться.
Она интересна тем, что позволяет задавать разные опции (например не показывать свойство getTest/setTest при переборе циклом for ..in). Но наверно в задаче надо было написать свою функцию, а не использовать готовую, я уже не помню.
вопрос про прототипы > Я пытался задать метод через прототип и обратиться к нему в "конструкторе" функции, но мне выдалась ошибка о том что этот метод не является функцией: https://jsfiddle.net/3sjvm5gp/ > Почему так получилось? Ведь если функция не находиться в объекте она ищется по цепочке в его прототипе.
Верно. Но трюк в том, что свойство prototype не задает прототип для объекта-функции Foo. Оно задает прототип для объектов, которые будут созданы с помощью new Foo. В данном коде Foo.prototype - это просто обычное свойство с именем prototype.
А вот если мы сделаем var f = new Foo;
То у f будет взят прототип из Foo.prototype. И можно будет писать foo.func
То есть прототип задается объекту в момент создания. У Foo прототипом является Function (и она создается даже до того, как выполнится строчка Foo.prototype.func = ...), так как в JS все функции это объекты, созданные конструктором Function.
Важно не путать свойство с именем prototype и прототип объекта, который можно получить через Object.getPrototypeOf() или нестандартное свойство x.__proto__ которым я советую не пользоваться.
То есть задавать прототип объекту нужно в момент создания и есть 2 способа:
- var f = new Foo - прототип берется из свойства Foo.prototype - (ES5) var f= Object.create(p) - прототип берется из p
Если вдруг есть желание залезть в стандарт ES5, довольно тяжелый для чтения, то вот:
> 5. Let proto be the value of calling the [[Get]] internal property of F with argument "prototype". > 6. If Type(proto) is Object, set the [[Prototype]] internal property of obj to proto.
То есть при создании объекта берется значение свойства F.prototype и если это объект, то он становится прототипом создаваемого объекта.
Задача про addMethod и super > Что-то у меня не получилось понять подвоха этой задачи: https://jsfiddle.net/zmLjh7ur/ > Более того, я не смог понять как работает функция super(): https://jsfiddle.net/b073aLb5/1/ > В чем моя ошибка? Здесь же должна быть такая же ситуация, super должен искать метод в прототипе. Подвох в том, что функции super() в JS нету, и в задаче требуется ее сделать. То есть если просто сделать добавление метода так:
function addMethod(object, name, fn) { object[name] = fn; }
То super() конечно никак не сможет найти метод в объекте-предке. Она ведь даже не знает, из какого метода с каким именем, и на каком объекте она вызвана. А передавать имя метода или ссылку на объект в super() по условию задачи нельзя.
То есть addMethod должен быть чуть сложнее. Он должен вставлять в объект не fn, а функцию-обертку, которая перед вызовом исходного метода как-то найдет и передаст в super ссылку на объект-предок или на метод в предке. А после обнулит эту ссылку. Примерно так:
- задать ссылку на метод-предок для super - вызвать исходную функцию - (при желании) обнулить эту ссылку после завершения исходной функции
Дополнительный подвох заключается в том, что метод-предок тоже может оказаться такой "оберткой", вызывающей super().
Второй подвох, который стоит оставить на потом, в том, что исходная функция может выбросить исключение и выполнение метода прервется. Надо корректно это обрабатывать.
Это сложное задание, потому можно сразу спросить, если что-то не понятно, а не ломать голову. Я могу дать дополнительные подсказки.
> if (size == Hamburger.SIZE_SMALL || size == Hamburger.SIZE_LARGE) { > } else if (size === undefined) { > } else if (size != Hamburger.SIZE_SMALL || size != Hamburger.SIZE_LARGE) { В третьем случае лучше просто написать else. Также, можно убрать второй случай.
Также, может быть стоит хранить где-то список допустимых значений отдельно, чтобы было легко его править.
> определил this.menu Странно, я в коде не вижу this.menu = {}; Наверно это было в другой версии кода.
В остальном выглядит верно.
Электросеть
>> Для ЛЭП проще всего указать нули и учитывать их вклад отдельно (сделать у них методы для получения информации, сколько мощности доступно и по какой цене). > Но мы можем и даже должны иметь возможность узнать её мощность.
Да, но я предлагал сделать для этого отдельное свойство, ну например не "мощность", а "пропускная способность". Так как все другие потребители, кроме ЛЭП, могут сами посчитать, сколько они потребляют/генерируют, а ЛЭП не может, она должна дождаться пока мы подведем баланс. Потому я предлагал сделать у ЛЭП мощность 0 и сделать отдельные свойства для хранения пропускной способности и цены.
> А почему ЛЭП не может спросить сколько энергии нужно? Она может, но получается как минимум 2 проблемы:
- ЛЭП надо будет дать ссылку на Сеть, в то время как c другими элементами у нас односторонняя связь: у Сети есть ссылка на Элемент, а у Элемента на Сеть - нет. Такая односторонняя связь удобнее, ее проще поддерживать и лучше видно кто кем управляет - будет запутанная цепочка вызовов: Сеть опрашивает Элементы, сколько они генерируют, а ЛЭП в свою очередь опрашивает Сеть, какой получился баланс (а ей для этого надо опять опрашивать Элементы). Запутанное отношение, и тут легко даже сделать бесконечную рекурсию.
Потому удобнее сделать расчет, сколько мы закупаем/продаем энергии, в Сети, а ЛЭП эти цифры не давать, зачем они ей.
> Тут дело даже не в этом, ЛЭП сама по себе ничего не спрашивает - мы просто передаем энергию и пользуемся её функцией счетчиком, который работает с её же свойством цена.
Это можно, сделать у ЛЭП метод, который отвечает на вопрос, сколько будет стоит передача данного количества энергии.
>>Мне кажется, тут неправильно используется свойство power, так как у ЛЭП это не фактически переданная мощность, а пропускная способность (сколько максимум можно купить/продать), и логично для нее использовать другое название, чтобы не было путаницы. > В реальной жизни тоже некоторые свойства могут называться одинакового, не смотря на то что выполняют разные функции. Это плохая идея, так как повышает вероятность сделать ошибку. Лучше назвать по-разному, чтобы меньше была вероятность напутать.
Ну и код упростится: из этого цикла
> for (var element in this.elements) { > if (this.elements[element] instanceof PowerLine != true) {
Можно будет убрать if.
> power мы делим саму на себя чтобы узнать прибавлять или отнимать энергию каждый раз, чтобы достичь баланса, т.е. узнать обратный знак своего значения. То есть, мы каждый раз либо прибавляем или отнимаем по одному, до тех пор пока значение не станет нулём.
Вместо вычитания в цикле надо использовать деление или умножение и функции min()/max().
Здесь идея правильная, но код не очень логчный. Мы сначала спрашиваем сколько стоит передача энергии, а только потом - сколько можно передать. Логичнее сделать наоборот, узнать, сколько можно передать, а потом - сколько это стоит.
Ну и функции стоило назвать логичнее. Не countPower(), а например getTransferredPower(), хотя мне кажется что сделать тут min(balance, line.getThroughput()) было бы нагляднее.
> function Electrostation(power) { > NetworkElement.apply(this, arguments);
apply(arguments) тут использовать неправильно, так как у функций разные наборы аргументов и аргументы от одной функции не соответствуют аргументам от другой. В NetworkElement надо передавать мощность в ваттах, а в Electrostation в мегаваттах.
Тут нелогично, что мы сначала передаем в конструктор предка одно значение мощности, а потом меняем его на другое. А вдруг в предке в конструкторе будет например логгирование, или проверка какая-нибудь?
Лучше сначала рассчитать мощность, а потом вызвать конструктор предка и дать правильные значения.
Здесь есть маленький недостаток, что свойство power зависит от apartments и логично тогда power вообще не хранить, а просто вычислять из apartments в момент вызова getPower. Плохо хранить зависящие друг от друга свойства, так как есть риск что они перестанут соответствоват друг другу (если мы разрешим менять apartments например).
То есть надо либо не хранить this.apartments, либо не хранить this.power.
> как проверить что у объекта есть свойства от 0 до length - 1. Пройтись циклом от 0 до length - 1 и для каждого числа проверить наличие свойства с помощью in.
> А что с этим циклом делать? Нельзя же вернуть значение только по окончанию цикла, если in всегда были истины. Можно писать так:
для (i от 0 до length - 1) { если в объекте нет свойства i, то вернуть false; } вернуть true;
15. Напиши функцию неглубокого копирования объектов и массивов
Вот тут я бы обратил внимание на то, как копируются даты:
> var clone = new Date();
Мы создаем объект Date и копируем свойства по одному. Но тут есть подвох. Date это встроенный в JS объект и потому он не подчиняется общим правилам (более того, в разных браузерах этот объект может быть реализован по-разному). Например, у него могут быть свойства, которые не перебираются через for .. in (как свойство length у массива), или вообще скрытые внутренние свойства, недоступные из JS. Потому копировать его таким способом рискованно.
Вот, к примеру, если в консоли разработчика в Хромиуме сделать dir(new Date) то там нет никаких видимых свойств, только методы в прототипе.
В твоем коде дата не копируется (проверь), а создается объект с текущим временем.
В общем, встроенные в JS и в браузер объекты - это не обычные JS объекты и они не играют по общим правилам. Они могут делать все, что угодно, а вот с ними делать можно только то, что описано в документации. Если там не описаны свойства, то значит они могут быть скрытыми.
>>Не, до такой степени скопировать объект мы вряд ли сможем. Достаточно копировать только свойства самого объекта, копировать прототип не требуется. > А понял. Подвох в том что копируется не сам прототип а только его свойства, верно же?
Да. И мы скорее всего вообще не можем создать объект с таким же прототиом, что у исходного, так как не знаем, каким конструктором и с какими аргументами он был создан. Потому в задаче требуется только копировать обычные объекты вроде {x: 1, y: 2}, без копирования прототипов.
>>Тут в коде, я вижу, есть поддержка копирования объектов Date и обычных объектов, а что с массивами? Для них ведь надо изначально создавать пустой массив и копировать элементы. > А других встроенных объектов это замечание касается?
Да, если надо копировать встроенные объекты, то для каждого придется писать свою логику. Один способ для Regexp, другой для Function, и так далее. Встроенные объекты могут иметь скрытые свойства и просто циклом их копировать нельзя.
Глубокое копирование
В старом коде была такая строка:
> var clone = new object.constructor;
Тут есть проблема, что constructor это обычное свойство и оно может быть перезаписано, или неправильно проставлено, и твой код из-за этого сломается. Также, конструктор может иметь аргументы, а ты их не передаешь при вызове new. Потому я советую не пытаться вызывать неизвестный тебе конструктор.
Также тут та же проблема, что Date не копируется, так как у него свойства скрыты.
> } else if (variable instanceof Array) { Тут есть маленький подвох. Если объект был создан в другом окне или ифрейме и передан нам, то проверка не сработает. Потому что в каждом окне/ифрейме свой экземпляр window.Array и они не равны друг другу.
>>955473 >Вместо того, чтобы ручками копипастить вот это вот: > >$file->post = $result['post']; >$file->displayname = $result['displayname']; >$file->duration = $result['duration']; > >Лучше было бы сделать так: > >protected function getFields() >{ >return ['post', 'displayname', 'duration']; >} > >foreach ($this->getFields() as ...) { ... } > >Более того, этот код (вынесение свойств из массива и заполнение объекта) можно сделать в базовом классе ActiveRecord. Имелось ввиду получение свойств с помощью get_class_vars()? Хорошо ли это? В объекте могут быть свойства которые не предназначены для заполнения из БД. У меня были мысли написания универсального метода для заполнения, но sublime text позволяет мне редактировать такие записи в пару нажатий.
>Ну и еще в AR проблема с тем, что PDO надо передавать в каждый объект File. Часто разработчики AR просто отказываются от DI и делают где-то глобальный метод для получения зависимости. Да, у меня как раз возникали с этим проблемы - чтобы получить все записи какой-то сущности, мне нужно было создать сначала саму эту сущность. Мне хотелось написать статичный метод для этого и передавать в него PDO. Я думал переделать всё на TDG, но теперь мне интересно попробовать Доктрину.
>Если сфинкс на хостинге запускать не разрешают, то можно использовать полнотекстовый индекс и поиск по нему в MySQL: Возможно у меня получиться найти хостинг с большим доступом, а файлы хранить на этом на нём нету ограничения на использование места.
>>Я видел как тут аноны собираются в конфочки, поэтому я подумал что можно написать наш собственный мессенджер внутри этого сервиса. >Если хочется потренироваться в написании мессенджеров, советую делать его как отдельный проект. Наверно тут понадобится JS-приложение, чтобы на каждый чих не дергать сервер. Можно и без JS, но будет работать наверно не очень быстро. Можно написать и отдельно. Ведь ничего не мешает потом интегрировать это куда угодно.
>Также, картинки на дваче не хранятся вечно и надо их либо скачивать, либо не выводить. А они и так скачиваются.
>Также, не знаю, нужно это или нет, но у меня есть кое-какие архивы с HTML-файлами тредов и картинками. Я их уже который год собираюсь выложить, но руки не доходят. Это будет замечательно. Парсить из html-файла... Это будет сложнее. Сначала я разберусь с текущими замечаниями, затем возьмусь за это.
Завтра я глубже проанализирую ваши советы. Возможно будут ещё вопросы.
Не, имелось в виду что мы описываем список свойств руками в методе getFields(), а потом проходим по нему циклом и копируем из массива в объект. get_class_vars конечно не даст нам то, что нужно.
Некоторые фреймворки автоматически загружают список свойств из базы, запрашивая список колонок в таблице и кешируя информацию.
> У меня были мысли написания универсального метода для заполнения, но sublime text позволяет мне редактировать такие записи в пару нажатий.
Код будет проще. В твоем варианте трудно сравнить например что списки при INSERT и при загрузке записей совпадают и ничего не пропущено.
> Да, у меня как раз возникали с этим проблемы - чтобы получить все записи какой-то сущности, мне нужно было создать сначала саму эту сущность. Мне хотелось написать статичный метод для этого и передавать в него PDO.
Да, используют либо статические методы, либо сторонний объект PostFinder.
> Я думал переделать всё на TDG, но теперь мне интересно попробовать Доктрину.
Да, это хорошая идея.
> Парсить из html-файла... Это будет сложнее. Сначала я разберусь с текущими замечаниями, затем возьмусь за это.
Это может быть хорошим поводом изучить DOM и jquery подобные библиотеки. хотя конечно, да, там подвох в том, что верстка менялась со временем, и придется писать несколько версий парсера.
Я могу ошибаться, но по моему, первая задача, с которой к нам пришел someApprentice, была про написание то ли регистрации, то ли это была задача про сервис уменьшения картинок.
>>955524 Всё верно, вот эта задача https://github.com/someApprentice/simpleRegistration Сервис по уменьшению картинок мне оказался не по зубам, не мог справиться с ООП, поэтому я взялся за вектор а затем за студентов. Вашими усилиями теперь для меня такие вещи проще простого. Я действительно думаю что я ничего не сделал - я просто делал что вы говорили. Спасибо за всё что вы сделали. Я не знаю как я смогу отплатить вам за это. Возможно, если я сделаю что-то стоящее, это будет значить что это было сделано под вашим влиянием, а значит сделано благодаря вам. У меня просто нету другого выбора как сделать это.
Насколько я помню, я делал задачи и из учебника, только не скидывал в тред - я мог решить их самостоятельно.
>>955413 Молодец, отличная штука. Ты её сам делаешь, или пулл реквесты принимаешь? У меня есть несколько предложений по улучшению структуры проекта, архитектуры и других вещей. Я могу их подробно описать, потом мы это обсудим в треде или на гитхабе. Как тебе идея? Будет интересный опыт создания чего-то общего нашим уютным тредом.
>> Вывести информацию о пользователе, сколько лайков поставил/получил, сколько взаимных лайков > Решено пока неэффективно, с лишними подзапросами. Это можно сделать с 2 джойнами без подзапросов. Долго ломал голову, не понял как решить без подзапросов. Для того, чтобы сосчитать количество полученных/поставленных лайков нужно ведь сгруппировать по пользователю и выбрать count(), эта функция будет применяться к сгруппированным элементам. Но запрос вида "SELECT user.id, count(likes.from_user), count(likes.to_user) ..." выдаёт 2 одинаковых count'а. А JOIN ON ведь указывает только как фильтровать соединённые таблицы, как туда впихнуть свой count или группировку (без подзапросов) - не могу понять.
Насчет поиска числа взаимных лайков, тут конечно, интереснее. Подскажу: можно для каждой строчки в группе определить, является ли лайк взаимным выставив 0 или 1, и сложить эти значения.
Свойство companySalary избыточное, так как зарплату по компании можно всегда получить, просуммировав зарплату по департаментам. Хранить его - плохая идея, так как при добавлении новых департаментов, найме работников, изменении их ранга или зарплаты это поле надо будет не забыть пересчитать, а забыть легко (и получить в итоге устаревшие данные). Лучше вообще не хранить его.
> class Department { > public function setDepartmentEmployees($departmentName, $department) {
Здесь какая-то ерунда. передается какой-то двухмерный массив непонятной структуры. Вот например, что это значит?
> $department[$i][$i - 1]
Если $i == 5 то получается $department[5][4]. И в чем смысл этого выражения? Мы берем из массива элемент с ключом 5, а в этом элементе-массиве ищем элемент с ключом 4?
Ты можешь объяснить что это за массив и какого он вида, что хранит? Из кода понять невозможно.
Лучше просто сделать объект, поедставляющий работника, а в департменте - метод принятия работника на работу в этот департамент.
>>955495 >Пхп вообще не очень язык для написания долгоиграющих приложений с ивент лупом. В целом да, но это не нереально. Ратчет по бенчам примерно вдвое меньше реквестов, чем нода держит, к примеру, с чем так же работать можно. Обещали еще ускорить. Есть еще воркерман какой-то от китайцев, этот судя по гитхабу в каждой жопе затычка.
>>955473 >Можно добавить в тред поля для хранения числа постов, а также ссылки на последние посты (либо сделать это через отдельную таблицу связи тред - последние посты). Соответственно данные можно будет выбрать в 2 захода: выбираем треды, затем собираем из них id ОП-поста и последних постов и выбираем их одним запросом. То есть одним запросом? SELECT * FROM posts WHERE id IN (1, 2, ...)?
Я сомневаюсь что при хранении ссылок на последние посты и их выборка будет делать гораздо меньше нагрузки чем у простого запроса с OFFSET. Даже если мы сделаем отдельную таблицу связей, то мы все равно будем обращаться к ней на главной странице, что будет делать ту же нагрузку. Я провел тест чтобы проверить это, и если я правильно выбрал метод проверки, мои сомнения подтвердились:
mysql>set profiling=1; ... mysql>show profiles; +----------+------------+------------------------------------------------------------+ | Query_ID | Duration | Query | +----------+------------+------------------------------------------------------------+ | 1 | 0.00255000 | SELECT ∗ FROM posts WHERE thread=945059 LIMIT 3 OFFSET 938 | | 2 | 0.00241925 | SELECT ∗ FROM posts WHERE post IN (955807, 955816, 955833) | +----------+------------+------------------------------------------------------------+
Как мы видим, время выполнения почти одинаково.
Есть что-то что я упускаю? Или я путаю скорость выполнения запроса с его нагрузкой (по-моему, это пропорционально)?
Что касается создания поля с числом постов и таблицы с цепочкой постов, то с этим мне понятно.
>Также, строить цепочку постов через выбор всех постов в БД очень неэффективно. Лучше сделать таблицу связи "многие-ко-многим", связывающую посты, может быть такого вида: > >from_id | to_id > >или такого > >from_id | to_id | depth > >То есть мы берем пост, и для каждой ссылки в нем вставляем записи в таблицу связи. Можно вставлять только ссылки из самого поста, тогда надо делать несколько SQL запросов, чтобы построить цепочку, а можно вставлять ссылки еще и на посты с большей глубиной вложенности, тогда цепочка выбирается одним запросом, но таблица будет больше по объему. >а можно вставлять ссылки еще и на посты с большей глубиной вложенности, тогда цепочка выбирается одним запросом А что находиться в глубине вложенности? Насколько я знаю глубина вложенности это расстояние до корневого узла. Как из этого получить всю цепочку?
>>955523 >Не, имелось в виду что мы описываем список свойств руками в методе getFields(), а потом проходим по нему циклом и копируем из массива в объект. get_class_vars конечно не даст нам то, что нужно. Как тогда определить такой метод в базовом классе?
> Я сомневаюсь что при хранении ссылок на последние посты и их выборка будет делать гораздо меньше нагрузки чем у простого запроса с OFFSET.
Конечно, на практике скорость выполнения запроса зависит от многих факторов, но один из главных факторов - это сколько строк таблиц должна MySQL обойти, чтобы получить результат. Индексы тут конечно тоже влияют на результат, позволяя вместо изучения всей таблицы быстро найти строки, подходящие под условие.
Чтобы сделать OFFSET, мы сначала должны сделать COUNT() для постов в треде, а это обход N строк, где N = число постов в треде. Затем, взятие 3 последних постов через OFFSET это обход и пропуск почти всех постов в треде. Тут кстати можно было просто остортировать посты треда по убыванию даты и взять первые 3, если есть индекс по (thread_id, post_date) то запрос SELECT FROM posts WHERE thread_id = ? ORDER BY post_date DESC LIMIT 3 приведет к обходу только этих 3 постов (MySQL в индексе найдет самый последний пост треда и сделает 3 шага по индексу чтобы найти 3 последних поста).
Но даже в этом случае, я вижу тут недостаток: мы должны делать 2N запросов, где N - число тредов, так как для каждого треда мы должны 1 запросом получить ОП пост и вторым - последние 3 поста. Тут конечно можно выкрутиться, используя UNION, тогда нам надо сделать N запросов, а не 2N.
Много запросов - это не очень хорошо, так как каждый запрос поразумевает накладные расходы (формирование запроса, передача данных по сети, разбор запроса, построение плана и оптимизация) и потому 1 запрос, выбирающий 10 записей выгоднее чем 10 запросов, выбирающих 1 запись. Так как во втором случае накладные расходы добавляются на каждый запрос. Они маленькие, на практике это может 0.2 - 1мс, но когда запросов много, в сумме может набежать много времени.
Если хочешь, можешь сделать тест, меряющий разницу между 1 и 10 запросами. Не забудь запустить его несколько раз, например 5 раз, и взять среднее, чтобы убрать погрешности. Можно даже просто сравнить запросы вида SELECT 1 и SELECT 1 UNION SELECT 2 UNION SELECT 3 .. чтобы не обращаться к таблицам и считать только накладные расходы на передачу данных.
Потому я и предложил такую схему, чтобы взять сначала N тредов, затем выбрать из них (или из доп. таблицы связи) id нужных постов и запросить посты одним запросом через WHERE id IN (?). На практике конечно надо тестировать, я мог что-то не учесть.
> Есть что-то что я упускаю? Или я путаю скорость выполнения запроса с его нагрузкой (по-моему, это пропорционально)?
А ты отключил кеш запросов? MySQL имеет кеш результатов, то есть если выполнить одинаковый запрос 2 раза, второй раз результат вернется из кеша. Надо либо отключать его через SET какой-то глобальной переменной, либо конструкцией SELECT SQL_NO_CACHE.
Также, можно посмотреть план выполнения запроса через EXPLAIN SELECT ...
Я сомневаюсь, что обход 938 строк занимает то же время, что выбор 3 записей по индексу. Ты точно отключил кеш? На 1000 строк разница должна быть заметна, даже если эти данные целиком поместились в память, и не вызвают обращения к диску.
> А что находиться в глубине вложенности? Насколько я знаю глубина вложенности это расстояние до корневого узла. Как из этого получить всю цепочку?
Глубина вложенности - это расстояние от первого поста цепочки до самого глубокого, если идти по ссылкам. Мы можем представить посты в цепочке как дерево, где корень это оргинальный пост, узлы второго уровня - посты, на которые ссылается оригинальный пост, и так далее. А у дерева есть глубина.
Если A ссылается на B, B на C, C на D то глубина цепочки получается 3.
Я предложил 2 варианта, чтобы для оригинального поста выбрать все дерево постов, на которые он ссылается:
1) таблица хранит просто связь между исходным постом и теми, на которые он ссылается (один уровень). Чтобы выбрать все дерево, надо сделать N запросов где N - глубина дерева. Таблица небольшая.
Для примера выше будут записи:
A -> B B -> C C -> D
2) таблица хранит для каждого поста ссылки на все листья дерева, то есть для примера выше там будут записи
A -> B A -> C A -> D B -> C B -> D C -> D
Соответственно выбрать дерево постов можно 1 запросом.
>>Не, имелось в виду что мы описываем список свойств руками в методе getFields(), а потом проходим по нему циклом и копируем из массива в объект. get_class_vars конечно не даст нам то, что нужно. > Как тогда определить такой метод в базовом классе?
Использовать абстрактные методы: abstract protected function getFields().
9: https://jsfiddle.net/9mvy5jr7/ Тут отступ текста привязан к ширине жёлтого блока, это неправильно? Где-то читал о препроцессорах, там ширину блока можно загнать в переменную, тогда отступ текста не нужно будет менять при изменении ширины жёлтого блока.
> $("body img") body тут лишний. Не стоит усложнять селекторы.
> $that.width() Это не ошибка, но тут я хотел заметить, что важно знать различия между $that.width(), $that.outerWidth() и that.prop('width'). Первые 2 - это размеры элемента на странице, заданные через CSS, третье - это исходный размер картинки.
> $("body form textarea, input, button, select [name]") Неправильный селектор. запятая работает не так, как ты думаешь, и выражение равносильно:
> $postList.map(function () { Зачем тут функция map() если ты никуда не сохраняешь результат? Для простого перебора ведь есть функция each? Map нужна для преобразования одного массива в другой.
А вообще, конечно, мне не нравится эта дурацкая тенденция лепить какие-то функции там, где должен быть цикл:
Разве это норально? Разве для перебора массива не принято использовать циклы (по крайней мере в других языках)? Какая выгода от добавления тут функции? разве это не лучше читается?
для каждого (x в массиве y) { сделать что-нибудь с x; }
Это не претензия к твоему решению, это претензия к Яваскрипту и людям которые в каждой первой статье вместо цикла городят какие-то костыли. Может и вместо if функции будет использовать? Поехавшие, честное слово, услышали что функциональный подход это модно и лепят его везде, а сами даже hello world на хаскелле написать ведь не могут.
Вот кстати, статья, где человек делает функцию для if, раз тебе нравятся функции вместо циклов, тебе может и статья понравиться: https://habrahabr.ru/post/321078/
> data.postName = $postTitle.html(); Неправильно ведь. Нам нужен не HTML код, описывающий название поста, а простой текст. Ну к примеру если в названии используются HTML-сущности вроде & lt; то мы хотим получить соответствующие им символы, а не эти коды.
> var data = { > "postName": null, > "views": null, Тут ведь не требуются кавычки. И мне кажется, было бы читабельнее вычислить значения до того, как создать объект:
var postName = ... var data = { postName: postName, .. };
Или даже так:
var data = { postName: $(...).text() };
> $comments = $comments.html(); Это конечно дело вкуса, ставить доллар или нет в переменных, но в данном случае если переменная содержит число комментариев, а не jquery элементы, то что там делает доллар?
Твой код анимирует body.scrollTop. Ты его тестировал в разных браузерах? Как я помню, Webkit/Blink (движок Хрома и Сафари) и Gecko (движок Firefox) используют разные элементы, один body, а другой html для прокрутки. Обычно анимируют оба элемента по этой причине.
У меня в ФФ (правда, не самом новом) страница просто прыгает скачком. Лучше чем ничего, конечно.
> Почему-то click у jQuery не работает, использовал нативный. У меня все работает. Я зашел в консоль в браузере, перешел там внутрь ифрейма с результатом и после этого выполнил 2 команды:
var test = $("a[href='#anchor2']"); test.click();
И все заработало.
Ты все правильно сделал? У тебя в коде там click() стоит раньше чем ты ставишь обработчик на body, может в этом дело?
Ну и важно еще, чтобы страница не была уже прокручена к нужному элементу.
> Насколько знаю, есть 2 пути: > - вычесть эти 2 пикселя из ширины элемента. Получится width: 578px, выглядит как магическое число: В новом CSS для этого придумывают calc и переменные: width: calc(600 - 20 - 2), также в препроцессорах CSS (которые мне не нравятся) есть вычисления и переменные, но я не вижу проблемы. Можно комментарий добавить при желании.
Если ты например захочешь сделать колонки шириной в 1/8 родителя, там ведь тоже считать придется.
Хотя конечно логика в твоих словах есть. Но использование вычислений сокращает набор поддерживаемых браузеров, оно того не стоит по моему.
> выставить ширину с учётом паддингов и использовать box-sizing: border-box: Так тоже можно.
> Оба подхода дали одинаковые результаты, какой лучше? Оба верные. box-sizing не поддерживался в древних фаерфоксах по моемуи в ИЕ7-, но их вряд ли где можно встретить сегодня.
> font-family: "Trebuchet MS"; Нужно тем, у кого нет шрифта, давать альтернативу в виде стандартного шрифта (serif, sans-serif и тд) которые определены стандартом CSS. Хотя требушет конечно почти везде или есть, или задана альтернатива, но все же такие правила.
> #content #list #content тут лишний так как id уникален на странице
У тебя проблема с прочностью верстки. Попробуй сократить текст статьи до 2 слов, и увеличить число пунктов в меню, и увидишь, что рамка не охватывает меню. Я вижу что ты пытался там сделать clearfix, но clear действует только на float идущие в том же "стакане" до элемента с clear (то есть на флоаты внутри статью или перед ней), а у тебя меню в коде идет после контента. Чтобы его "очистить" тебе надо ставить clearfix на #container.
> padding-bottom: 100px; Это ведь костыль какой-то? Я думаю, это тут не нужно.
> // var [depth, current] = stack.shift(); Ага, это ES6 и мало где поддерживается. Я даже насчет использования ES5 не уверен, а ES6 и подавно.
> var stack = list > .filter(node => node.parentId === null) > .map(node => [0, node]); Этот код повторяется 2 раза, стоило вынести в функцию.
Так, в общем верно. Хотя конечно я видел дерево, нарисованное горизонтально в комментарии, и надеялся что увижу алгоритм его вывода....
Также, ты бы мог чуть улучшить (ну или запутать) код, если бы разделил код на 2 части: обход дерева и посещение вершин. Чтобы было примерно так:
traverseTree(list, visit);
И чтобы мы например этот обход где-то еще могли бы использовать.
Также, на больших деревьях оптимальнее будет вначале преобразовать линейный список в древовидную структуру, чтобы не обходить его каждый раз.
Так, решено верно.
> На PHP вышло многословно: https://ideone.com/YKik59 Ну да, тут анонимные функции чуть более громоздкие. Но зато у нас в PHP есть нормальный foreach! И тайп-хинты.
> form input { Хочу предупредить, такие селекторы можно использовать только в учебных задачах. На реальном сайте этот селектор заденет все инпуты во всех формах.
> form input, button { Ты наверно хотел написать form input, form button?
Так, в общем верно.
> 8: https://jsfiddle.net/7w3eg396/3/ > У меня получилось так, что примечание можно добавить к любому тегу p, вставив aside перед ним. Так и нужно было? Да.
Но у тебя есть проблемка: попробуй поставить 2 или 3 примечания подряд. Они накладываются друг на друга. Надо решить эту проблему. Ну и опытный верстальщик конечно должен предугадывать возможность появления такой проблемы.
> Добавил границы, чтобы удобнее было смотреть отступы. Тут удобно использовать outline, так как оно не влияет на верстку и размеры.
> 9: https://jsfiddle.net/9mvy5jr7/ > Тут отступ текста привязан к ширине жёлтого блока, это неправильно? Ничего не поделать.
> Где-то читал о препроцессорах, там ширину блока можно загнать в переменную, тогда отступ текста не нужно будет менять при изменении ширины жёлтого блока. Да, есть такое. Но мне они не нравятся тем, что появляется дополнительный этап и надо перекомпилировать код чтобы увидеть изменения. Но это мое личное мнение. Также, в новом CSS будут переменные (с жутким синтаксисом, сделанным чтобы их никто не хотел использовать): http://frontender.info/css-variables-why-should-you-care/
Вообще, раз тебе интересны препроцессоры, я советую с ними познакомиться. Самые известные - LESS и SASS, увы, не помню какой из них сейчас в моде. Изучи их, это недолго, но вдруг что полезное увидишь.
на практике по моему нет. Там есть функции вроде headers_sent, но они часто возвращают что-то не то (или они делают не совсем то, что описано в названии).
Я когда-то давно проверял ее и она врала. По умолчанию, кстати, там есть какая-то буферизация и если ты вывел немного текста, то заголовки еще по-прежнему можно слать, но это зависит от конфига PHP и используемого веб-сервера.
Нужно настроить веб-сервер, чтобы он например для URL /xyz вызывал бы нужный тебе скрипт. Это настраивается по-разному в разных серверах. В Апаче через .htaccess и mod_rewrite. Обычно просто все нестатические УРЛ переадресовывают на index.php.
Ну это такие особенности PHP. Там разница в том, что во втором случае toString вызывается неявно. Я бы советовал не использовать такое в своем коде вообще. Также, мне не нравится tosString так как при его наличии можно не заметить ошибку (использование объекта там, где нужна строка).
А так, ты правильно делаешь, что читаешь документацию. Если ты новичок, с большой вероятностью на собеседовании будут вопросы или тесты по ней.
Это пример неудачного проектирования функции. Ты, как будущий разработчик, должен учиться на таких примерах и не повторять чужих ошибок в своем коде. Да, всегда лучше иметь один строго заданный тип данных и для аргументов, и для результата.
>>Это конечно хорошая идея, добавить поддержку gzip, но тогда надо дописать генератор сжатых версий файлов (и тщательно протестировать это в разных браузерах). >> В условия, кроме проверки наличия сжатого файла, стоит еще добавить проверку существования оригинала.
> Что понимается под генератором сжатых версий? В интернетах я встречаю мнение, что .htaccess достаточно Там предлагают сжимать файлы на лету, то есть тратить какую-то часть времени процессора ради уменьшения трафика и ускорения отдачи файлов. В принципе смысл в этом есть, если сервер используется только для раздачи файлов, то скорее всего у него процессор не сильно нагружен, да и gzip современные процессоры не сильно грузит. Но есть и другой подход - заранее положить на диск сжатые версии файлов и отдавать их клиентам, заявляющим о поддержке сжатия. Так мы не грузим процессор, но появляется необходимость создавать и обновлть эти сжатые копии файлов.
На практике можно смотреть на загрузку процессора - если свободные ресурсы есть, то можно жать и на лету. Обычно они есть.
> К этому я вообще не знаю как подойти. Если это cli, то как и зачем вью? Я думаю, там не нужен отдельный вью, хватит команды echo.
> И что будет из себя представлять контроллер? Простой php-файл в папке с названием вроде cli или command.
> Мне в голову кроме допустим switch с кейсами в виде опций командной строки ничего в голову не приходит. Есть стандартная функция getopt, если она не подойдет, пиши свою функцию разбора аргументов.
> `json` varchar(128) DEFAULT NULL Название неудачное, JSON это ведь формат хранения, а не смысл хранимых данных. Правильнее metadata например или properties, как-то так.
> `uploadTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, Почему время загрузки может меняться при обновлении записи?
Это позволяет брать данные из конфига или из переменных окружения или просто задавать их 1 раз.
Хотя если это усложнит код, может тут и не стоит это использовать. Подумай.
> sql_field_string = name А зачем объявлять name как отдельный атрибут? Это как-то используется? Если нет, то лучше не тратить память на дублирование данных которые есть в БД. для поиска не требуется создавать атрибут. Атрибут нужен для фильтров по нему и для хранения данных в сфинксе.
> source name можно было придумать название источника получше
> html_strip = 1 Не очень понятно зачем вырезать HTML-код из имен файлов, где его в общем-то и нет.
https://github.com/never3ver/fileshare/blob/master/copyBootstrap.php#L13 тут нет перевода строки, и возможно, при ошибке лучше выкидывать исключение? Или завершать скрипт с ненулевым кодом. А сейчас твои ошибки увидит разве что человек, а при автоматизированном разворачивании проекта никто и не заметит.
По поводу тестов: а ты бы не хотел попробовать подключить CI сервер к гитхабу, который может автоматически прогонять тесты на каждый коммит? Также ты сможешь добавить в ридми значок, показывающий текущий результат тестирования.
Из этих сервисов мне знаком Travis CI. Это коммерческий сервис, я не говорю что он лучше или хуже других, и не рекламирую его, просто он бесплатен для открытых проектов.
Для интеграции надо сделать в репозитории конфиг, который описывает порядок разворачивания проекта и запуска тестов, задает разные настройки. Все это описано в документации:
При желании можно на гитхабе легко найти примеры готовых конфигов.
Тебе надо будет настроить в конфиге установку зависимостей через композер, разворачивание БД, установку и запуск сфинкса, если он участвует в тестах.
После того, как конфиг готов, надо настроить интеграцию на гитхабе, чтобы он сообщал в Travis о каждом коммите и забирал результаты тестов. Ну и можно добавить бейджик в ридми.
Также, phpunit умеет генерировать coverage report, то есть считать, какая часть кода была задействована в ходе тестирования.
Можешь попробовать, если есть время. Я, конечно, могу подсказать что-то по настройке.
> php_value max_execution_time 500 Вот эта строчка мне не очень нравится, она ведь защищает от кривых зависших скриптов, может быть время загрузки файла не учитывается тут и нет необходимости повышать это ограничение?
> $container['FileDataGateway'] > $container['sphinx'] Надо привыкать называть однотипные вещи единообразно, а у тебя одно название с маленькой буквы, другое с большой.
> $app->post('/', function (Request $request, Response $response) { > if ($_FILES) { > много кода > } > }); А что будет, если if не сработает? Надо бы ошибку выдавать. И конечно надо этот if перевернуть, не надо такие огромные ифы делать.
И лучше было проверять не _FILES, а результат getUploadedFiles(), мы же с фреймворком работаем.
> $tmpName = $this->FileDataGateway->createTmpName(); > if ($this->FileDataGateway->isTmpNameExisting($tmpName)) { Это лучше было сделать по-другому, если не удалось сгенерировать имя с N попыток, то выбрасывать исключение.
Более того, я тут вижу баг: ты сначала генерируешь имя и проверяешь на уникальность, а только потом приписываешь к имени папку с датой. То есть проверяешь ты непонятно что.
И где тут разделение ответственности? Кто отвечает за генерацию и проверку имени, FileDataGateway или index.php?
Ну и может стоило имена как-то почеловечнее сделать.
> if (!is_dir($this->helper->getFilePath('') . $datePath)) { Это какие-то костыли, ты передаешь в функцию вместо имени пустую строку. Это же неправильно. И вдобавок код генерации имени файла размазан по index.php и другим классам.
Сделай просто нормальную функцию, которая получает на вход UploadedFile, генерирует подходящее имя, создает папки и помещает туда файл, и может быть, возвращает это временное имя.
Заодно эту функцию можно будет покрыть тестами.
> $file->setType($uploadedFile->getClientMediaType()); Я бы советовал особо не доверять переданному типу. Там может быть что угодно. Если ты вызываешь getId3, то стоит брать тип, который она определит.
> $url = $this->router->pathFor('list'); > $response = $response->withStatus(302)->withHeader('Location', $url); А не лучше редиректить на страницу с самим файлом?
> if (is_readable($this->helper->getFilePath($file->getTmpName()))) { > } else { > throw new \Slim\Exception\NotFoundException($request, $response); Это тоже неправильно. При внутренней ошибке на сервере надо использовать код 5xx, коды 4xx предназначены для ошибок в запросе от клиента. Почитай про коды состояния HTTP хотя бы в википедии, когда какие применяются.
Если файл есть в БД, но нет на диске, я бы предлагал бросать исключение. Чтобы информация попала бы в логи ошибок. Это ведь именно ошибка на сервере, а не 404.
> if ($file->getJson() != '') { > $sql = "INSERT INTO fileshare (`name`, `tmpname`, `size`, `type`, `json`)" > . " VALUES (:name, :tmpname, :size, :type, :json)"; Если JSON отстутвует, незачем делать второй вариант SQL запроса, можно просто передать вместо него NULL.
Про то, как формируются эти типы, что значит vnd и плюсики, можно прочесть в википедии.
Насчет метаданных - я бы предложил попробовать класть объект с метаданными внутрь File. Чтобы мы могли вызывать $file->getMetadata()->getBitrate(). Надо будет немного заморочиться с преобразованием в JSON при сохранении и с обратным преобразованием при загрузке из БД. Хотя, может конечно, это лишнее усложнение.
Также, я бы сделал 2 отдельных статических конструктора: для случая когда надо сгенерировать данные, и для случая, когда надо восстановить их из БД. Так было бы намного нагляднее и меньше шансов допустить ошибку.
Не уверен, что нужно передавать контейнер в FileInfo, это не соответствует DI, лучше передавать конкретные сервисы. А еще лучше - не передавать зависимостей вообще (кроме GetID3 при генерации данных).
https://github.com/never3ver/fileshare/blob/master/app/FileInfo.php#L58 Мне кажется, эта функция должна быть не тут. Класс называется FileInfo и хранит информацию о файле, почему он еще создает какие-то папки? Я бы посместил эту задачу в сервис работы с файлами, можно туда же, где и функция сохранения файла в хранилище.
Что-то у тебя плохо с разделением обязанностей между классами. Ну не, правда, код как-то случайно раскидан по классам.
И кстати, превью для png не обязано быть в формате png.
Можно еще подумать над генерацией превьюшек для видео.
> public function getImagePreviewUrl($tmpName) { > return '../files/preview/' . $tmpName; Это ненадежная функция, так как относительный путь зависит от текщего URL. Не надо так делать.
> INSERT INTO rt VALUES (:id, 'temp', :name)"; Тут надо указывать, в какие колонки ты что вставляешь, а то у тебя все зависит от порядка в котором определены колонки в конфиге. Ненадежно.
Я не вижу единой функции поиска, которая бы искала данные и в обычном, и в RT индексе и объединяла результаты.
Однако, нам может понадобиться отдельный конфиг. Для этого вводят такое понятие, как окружение: в тестовом окружении данные берутся из одного конфига (config_test.php), в продакшене - из другого (config_prod.php). Окружение можно выбирать через переменные окружения, например APP_ENV.
Другой вариант - можно переопределять настройки в переменных окрежения. В случае то же Travis это позволяет прописать настройки тестовой БД прямо в конфиге тревиса и не загрязнять ими код:
Также, есть еще такой вариант: делаем основной конфиг (config.php) и дополнительный (config.local.php), который переопределяет часть настроек. Локальный конфиг не отравляется в гит и может отсутствовать вообще.
Я бы просто проверял, что возвращается не пустая строка, может дополнительно - что она содержит определенные символы, но уж точно не стоит закладывать в тест конкретную длину строки, если только она не прописана в ТЗ на разработку приложения.
Вот попробуй подумать с точки зрения требований к функции: нам принципиально, чтобы она генерировала имена ровно в 45 символов? Наверно, нет. Нам надо чтобы она 1) генерировала имена файлов 2) чтобы они не повторялись с уже существующими. При этом требование 2 без базы проверить сложно.
Ты опираешься на знание о том, как работает внутренняя логика класса. Ты передаешь имя несуществующего файла, зная, что класс не будет к нему обращаться. Это ненадежно, так как завтра он начнет проверять наличие файла и тест сломается.
В принципе ради теста вполне можно сгенерировать или загрузить файл, который автоматически удалить после теста в tearDown(). А вот опираться на знание внутренней логики работы класса не стоит. Тестировать надо публично доступные интерфейсы, то, что класс выставляет наружу, что что описано в комментариях к функциям.
В твоем случае можно заказчать заранее подготовленную картинку или текстовый файл. Но важно сделать тест так, чтобы он тестировал именно логику в твоем коде, а не например способность getId3 определить битрейт видеофайла - это уже не наша задача.
Что тут можно протестировать? Первое - что код просто работает и не падает (smoke test). Берем заранее подготовленный файл, создаем для него FileInfo, и просто проверяем что он что-то распознал в файле (что свойства файла не пустые) и не упал с ошибкой.
Затем можно проверить корректность сохранения и восстановления JSON данных. Мы берем файл, создаем для него FileInfo. Затем генерируем JSON и создаем новый объект FileInfo из этого JSON. И проверяем, что оба объекта возвращают одинаковую и корректную информацию о файле. Пр этом сам JSON код мы не анализируем, так как его формат может со временем меняться.
Еще можно протестировать функцию генерации превью, но она на мой взгляд должна быть где-то в другом классе.
То есть мы берем класс, смотрим на его публичные поля и методы и формулируем требования, которым они должны соответстовать. Именно требования к публичному интерфейсу, без закладывания слишком конкретных деталей. Не надо проверять, что функция генерирует путь к файлу длиной ровно в 45 символов, достаточно проверить что она его генерирует вообще.
Представь, что ты - ручной тестер, тебе дали тостую распечатку с техническим заданием на приложение, дали приложение. И ты открываешь ТЗ, берешь первое требование, тестируешь. Берешь второе, тестируешь. И так далее. А не смотришь на внутреннуюю логику кода и отражаешь ее в своих тестах. Это будут плохие, часто ломающиеся и мало полезные тесты.
Что касается testGetDataForTemplate(), я думаю, что функция getDataForTemplate не нужна, а значит не нужен и этот тест.
> require_once 'vendor/autoload.php'; Обрати внимание, что в конфиге phpunit.xml можно указать путь к бутстрап-файлу.
Также, тестировать FileDataGatewayTest удобно так:
- вставить запись в БД - запросить эту запись и проверить, что она вернулась - удалить запись - запросить снова и проверить, что результат пуст
Таким образом мы тестируем несколько функций и не особо зависим от начального состояния таблицы, есть в ней записи или нет.
Но конечно в общем в примитивных методах вроде вставки и удаления записи тестировать особо нечего, можно просто вызвать их и проверить, что они не падают.
Вообще, тестирование важная тема, хорошо бы в ней разобраться, может у тебя какие-то вопроcы есть? Можете тебе подсказать, что в каком классе можно проверить?
Пока на мой взгляд главная проблема - отстутствие нормального разделения обязанностей между классами, некоторые вещи не вынесены в отдельные функции, а просто вписаны в стену кода.
> function createClick(elem) { Название лучше было сделать setPopupClickListener или как-то так.
> document.querySelector("#" + target.dataset.popupId Проще использовать getElementById
При обработке клика не учтено, что если кнопка содержит внутри другие DOM элементы то target может указывать на них. Для решения этой проблемы мы ищем нужный элемент с помощью closest() в новых браузерах или его аналога. В jQuery тоже есть closest.
Вообще, я сейчас подумал, конечно, что с jQuery эту задачу решать удобнее, так как она избавляет от необходимости решать эти проблемы кроссбраузерности, что closest, dataset, querySelector (часть стандарта DOM Level 3 по моему) есть только в новых браузерах.
Далее, в задаче, увы, не решена проблема автоматического определения размеров попапа. Важно понимать, как это делать, какие есть подводные камни. А они есть, такие:
- для элементов скрытых через display: none нельзя получить размеры, они не считаются браузером - для многих случаев высота зависит от ширины. Ну например, абзац текста может иметь разную высоту в зависимости от выделенной ему ширины - некоторые элементы задают минимальную ширину, меньше которой элемент не ужать, например очень длинное слово, картинка, кнопка - для автоматического определения ширины в CSS часто используется алгоритм shrink-to-fit, а его результат зависит от ширины родителя: https://github.com/codedokode/pasta/blob/master/html/shrink-to-fit.md - таким образом, чтобы получить размеры попапа, мы должны как-то выбрать ширину контейнера для него. И попробовав отрендерить его в контейнере этой ширины, получим его истинные размеры. - можно также добавить в разметку подсказки, например, задающие рекомендуемую ширину
В общем, хотелось бы, чтобы ты сделал автоматическое определение оптимальных размеров попапа. Есть идеи, как это сделать? Например, задавать ширину в data-атрибутах, но разрешить попапу быть меньше, если в нем мало контента.
Теперь про позиционирование. Хорошо бы учесть такие факторы:
- если элемент уезжает за левый или верхний край страницы, то эту часть никак не увидеть. Может стоит в такой ситуации ужимать попап по ширине или переносить на противоположный край? - если элемент выезжает за правый или нижний край, он вызовет удлинение полосы прокрутки - соответственно, при определении ширины/высоты можно учитывать ширину окна браузера - можно учитывать положение кнопки в окне. Если кнопка сверху окна, то логично попап выводить под ней, и наоборот
И это еще не все. Ты позиционируешь попап относительно левого верхнего угла страницы. Это имеет тот недостаток, что если на странице что-то поменяется (например появится новый элемент или пользователь изменит ширину окна) и кнопка уедет вверх/вниз, а попап останется на месте. Это можно решить, добавив пустой дивнулевых размеров перед или после кнопки и позиционировать попап относительно него. Но тут появляется другая проблема, а можем ли мы гарантировать, что этот див будет всегда правильно расположен, независимо от верстки окружающих элементов? И есть еще третий вариант, обернуть кнопку в див и позиционироваться относительно него. Там есть свои недостатки, можно сломать верстку.
Это наверно получается совсем сложно, но ты подумай, может что-то можно улучшить. Нет, так нет.
По коду в function positioningPopup(elem, popup) - нельзя ли его упростить? а то выглядит как стена кода.
>>946704 >>947452 На постгрес меня хероку заставил перебраться. Ты писал о том, что в постгрес можно использовать regex-ограничения для полей, но я не совсем понимаю зачем. Мне кажется, если злоумышленник обойдёт PHP-ограничения, то продублированные регулярки на стороне БД вряд ли чем-то помогут. Про CI прочитал, попробую поднять. Насчёт уровня покрытия тестами, то мне кажется, что чем он выше, тем более хрупкими будут тесты (так как их придётся постоянно подстраивать под изменения в проекте).
Ну и можно делать файлообменник на Симфони? Там уже много чего настроено из коробки (есть дебаг-панель, cli-утилиты, проще тестировать, чем Silex, есть плагин для PHPStorm, добавляющий автодополнение для сервисов/шаблонов/функций Twig и так далее). Понимаю, что оверхед, но взамен готов делать более сложные задания по файлообменнику.
Вот я делаю студентов и уткнулся в проблему. Есть bootstrap.php и в нем перехват ошибок/исключений вида http://ideone.com/EkC1Qr . И все было хорошо и лампово, пока я не начал делать скрипты для вызова из консоли, что бы заполнять базу фейками (да я узнал про fzaninotto/faker и уже не мог остановится). В скриптах конечно вывод в консоль, а значит при возникновении ошибок обработчик исключений крошится при попытке отдать заголовки. Завести глобальную переменную с флагом для консольных скриптов? Сделать отдельный bootstrap для них с другим обработчиком? Как это лучше исправить?
Аноны, у меня небольшой вопрос. Тут же есть люди с нулевым опытом, которые делали первое задание про список студентов? Как у вас вообще получилось к нему подступиться? Чувствую себя полнейшим идиотом, который не способен выполнить даже самую простую задачу.
Посмотри эти уроки, и спрашивай, что именно не понятно. Если не понятно, с чего начать, то сделай 2 PHP страницы (файла), выводящие слова "список студентов" и "регистрация" соответственно, и подними веб-сервер, чтобы на эти страницы можно было зайти через браузер.
>>957237 Спасибо за первую ссылку, ее не видел. Но проблема даже не в этих ссылках. Самая жопа заключается в самом mvc, потому что вариантов реализации куча, а у каждого все по-своему. Ладно, пойду дальше дрочиться. Когда-нибудь да сделаю.
переделал давеча автозагрузчик из простого перебора массива путей до компонентов в неймспейсовый и у меня сломался механизм логининга. Всегда активным юзером становится первая запись в базе данных вне зависимости от ввода ну и вообще побей меня палкой за косяки, если не сложно
>>957256 Mvc это вообще самое простое. Задача MVC просто держать весь код по отдельности, все что за отображение - во view, за ход процесса, запуск моделей и вводы-выводы - в контроллере, логику - в моделях. Варианты реализации там вообще неважны, главное чтобы все эти вещи оставались, и код друг с другом не смешивался. Накосячить можно, если во view модели например пихаешь.
>>957351 >Mvc это вообще самое простое. Как же выводят из себя такие отеты. На любой затык - это элементарно! Скоро будут писать - полиморфизм, инкапсуляцию и абстрактные фабрики даже даун сразу поймет.
Так вот, самое простое - это хеллоуворд написать и то если сервер не надо ставить, все остальное - не просто. Тот кто так пишет, либо пхп учит не первым языком, либо уже забыл как тыжело было вкатываться.
Простомэны кругом, теште свое тщеславие в другом месте
Но тот кто про MVC спросил, тем не менее, жопа ленивая. У него ведь нет конкретного вопроса, он просто поленился нагуглить несколько статей , причем в оппосте тоже есть хороший материал на эту тему, и попробовать сначала что-то руками сделать.
>>957422 Да, ты прав, мимокрокодил. Я помню, как меня дядя учил кататься на велике: ну что тут сложного, берешь и крутишь педали, балансируешь, ну что ты никак не поймёшь! Я как вспомню - так ору от его педагогических способностей.
>>957754 На этом сайте только выражение надо вставлять. Справа будет разбор по частям тобой написаного регекса, снизу можешь печатать и в риал тайме смотреть какие части твоей строки попадают под условие.
>>957797 Потому что индекс первого символа у тебя 0, ты хочешь получить индекс последнего символа и передаешь туда -0, то есть ещё раз получаешь первый символ, соответственно первый шаг у тебя неправильный. Ну и ещё на идеоне мультибайт стринги тупо не работают. https://3v4l.org/VaKAJ
>>957422 >полиморфизм, инкапсуляцию и абстрактные фабрики даже даун сразу поймет. Вообще так и есть, это ж самое простое из ООП, ну разве абстрактные фабрики слегка сложнее. Сложность начинается, когда любую книгу по паттернам открываешь, или алгоритмы те же.
public function __construct() { // Список объявлений, который у нас жестко заложен в коде $this->posts[] = $this->createPost( 'Продам слона', '+79990000001', 'Продается пока еще небольшой дрессировнный африканский слон.' );
$this->posts[] = $this->createPost( 'Сдам 8-к квартиру около метро недорого', '+79990000002', 'Сдается квартира, евроремонт, без хозяев, только серьезным людям.' ); // .. при желании можно добавить еще }
Блин, почему тут в __construct() не передаются никакие аргументы?
>>958126 Я балда. То есть если бы мы получали какие-то введённые данные, то аргументы нам там были бы нужны? Я теперь понял, что у нас же просто там уже имеется информация, да.
>>958208 Вот, обьясните мне это мышление, я его слишком много раз видел. Человек не думает "В этой функции мне надо знать чему равно что-то там, как бы мне это туда передать", человек видел что где-то что-то можно передавать и спрашивает почему у него тоже что-то не передается, он не такой как все щтоле. Это как-то жопой кверху получается.
>>958222 Ну вот я только познакомился с ООП, познакомился с __construct() у ОПа и у Зандстры. В обоих случаях в конструктор передавались аргументы, которые при создании экземпляра класса мы передаём для нужных нам свойств у объекта. А тут раз - и пустой конструктор. Я как увидел, так сразу в треде спросил, а потом отвлёкся от MVC ОПовского. Для меня это было чем-то новым и непонятным абсолютно - для чего именно так, с __construct(), почему не просто метод сделать, который создаёт объявления. Так понятен ход мыслей?
Конструктор подготавливает объект к работе, задает начальные значения свойств, иногда что-то еще делает. Если ему для этого нужны какие-то внешние данные то тогда мы можем передать их через аргументы. Если не нужны - то аргументы тоже не нужны.
То есть обычно аргументы указываются, чтобы потребовать от пользователя класса задать какие-то значения при создании объекта. Но тут так получилось, что объекту ничего в общем-то и не нужно.
Создавать объявления отдельным методом можно, но это бы значило что их можно и не создавать. Нам в задаче это не требуется, потому проще создать их прямо в конструкторе.
Если бы PostsService работал с базой данных, то скорее всего мы бы в конструктор передавали объект соединения с БД вроде PDO, через который можно делать запросы к базе. Это подробнее описано в уроке про DI https://github.com/codedokode/pasta/blob/master/arch/di.md
Решаю задачу с регулярками, где надо из номера телефонов привести к единому виду, "8" и 10 цифр, без пробелов и так далее, но не могу додуматься, как в одно действие заменить и на "8" - "+7", и в то же время заменить символы "- ()" на пустоту, делаю в два действия. Это нормально или не очень? (строки 31-34)
>>957931 Хз, я вот до сих пор не понимаю как инкапсуляция организована в некоторых языках. Хотя это не мои проблемы, а проблемы нечётко типизированных языков.
Пожалуйста, пишите один большой пост вместо нескольких маленьких и не флудите не по теме. ОПу ведь все это читать придется.
Это тред для начинающих. Не написал за свою жизнь ни одной программы и имеешь тройку по математике? Ты наш человек.
Устанавливать пока что ничего не требуется, разве что редактор кода вроде Sublime Text 3, Notepad++, Visual Studio Code, Netbeans PHP или PhpStorm (с ним будет удобнее).
Предыдущий тред был тут: ( http://arhivach.org/thread/233392/ )
Еще предыдущие треды в архиве:
- 84 >>898502 http://arhivach.org/thread/224683/
- 83: https://2ch.hk/pr/arch/2016-12-26/res/880700.html
- 82: https://2ch.hk/pr/arch/2016-12-01/res/864640.html
- другие: https://www.google.ru/search?q=site:2ch.hk/pr/+%D0%BA%D0%BB%D1%83%D0%B1+php
Мейлач лежит? Есть запасной тред: http://dobrochan.org/s/res/23225.xhtml#i46467
Что самое главное для программиста? Умение аккуратно оформлять код (читай второй пост, прежде чем писать код).
Правила: ведем себя воспитанно, помогаем новичкам, постим ссылки на решения задачек, ОП их проверяет и дает советы и замечания. ОП заходит редко, где-то раз в 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/Symfony: https://gist.github.com/codedokode/8733007
- После нее можно изучать автоматизированное тестирование https://gist.github.com/codedokode/a455bde7d0748c0a351a
- Если ты все решил, переходи к 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://github.com/codedokode/pasta/blob/master/db/databases.md
Что почитать
- Мануал по PHP — http://www.php.net/manual/ru/langref.php
- Сайт phptherightway (перевод на русский: http://getjump.me/ru-php-the-right-way/ )
- По PHP: Профессиональное программирование на PHP Джордж Шлосснейгл
- По PHP: Мэтт Зандстра — PHP: Объекты, шаблоны, методики программирования
- JS: learn.javascript.ru
- Про Git: https://git-scm.com/book/ru/v1
Оформляй код аккуратно!!! — например пропусти через phpformatter.com . Также, если ты пользуешься IDE вроде PhpStorm, Netbeans, Eclipse, то в них эта опция встроена, подробнее: https://gist.github.com/codedokode/8759492
У ОПа нет аккаунтов и групп вконтакте, в фейсбуке, в твиттере, все "пхп-треды" там поддельные.
Платиновые вопросы
- Почему PHP? Потому что фейсбук и википедия на нем написаны, и вакансий море, и учить легко.
- Сайт опять упал!!!!! — Не паникуй, а открой http://rghost.ru/6bfCY9lfl и получи личную немного устаревшую оффлайновую копию сайта (можно читать хоть на андроиде без интернета)
- Что надо знать чтобы найти работу - разработчику: PHP, SQL, HTML/CSS, JS, ООП, Git, композер, MVC, фреймворк. Верстальщику - HTML/CSS, JS, jQuery
- Можно подробнее про поиск работы, собеседования - нет, ОП писать не будет, но может кто из анонов захочет рассказать. Поищите тред перезвонивших, а также раздел /wrk/.
- Сколько времени надо изучать все это? - все зависит от тебя, но не меньше 6-8 месяцев
- Посоветуйте редактор кода - Sublime Text 3, Notepad++, PhpStorm
- Нужен ли ООП, фреймворки, MVC, git, composer? — Да, однозначно. Посмотри любую вакансию.
- Что самое главное для программиста? Умение аккуратно оформлять код.
- ОП, сделай за меня мою работу или домашнее задание? — Это конечно, хорошая идея, но нет.
- Подскажи сайты для поиска работы, я не умею гуглить? — hh.ru, geekjob.ru, moikrug.ru (склеен с brainstorage.me), fl.ru, upwork.com (бывший одеск). Имей в виду, что кроме фриланса есть еще постоянная удаленная работа (remote job) когда тебе не надо тратить время на поиск заказов и переговоры с неадекватными заказчиками.
-------------------
Код нужно писать не как попало, а аккуратно и по правилам. Почему? Потому, что на неакуратно написанный код не хочется даже смотреть.
Если тебе лень выравнивать код руками, закачай его на http://beta.phpformatter.com/ и нажми «format». Робот исправит выравнивание и отступы в мгновение ока (да, прогресс не стоит на месте). Если ты используешь мощную IDE вроде PhpStorm, там тоже есть функция форматирования кода.
Горячие клавиши для форматирования кода в разных IDE: https://gist.github.com/codedokode/8759492
Вообще, в 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 пробела)
Вот ссылка на стандарты, где все это описано подробнее и даны примеры оформления:
PSR-1: https://github.com/samdark/fig-standards-ru/blob/master/accepted/ru/PSR-1-basic-coding-standard.md
PSR-2: https://github.com/samdark/fig-standards-ru/blob/master/accepted/ru/PSR-2-coding-style-guide.md