Вы видите копию треда, сохраненную 12 декабря 2018 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
Не используйте ideone для задач с многобайтными строками.
Тут мы изучаем язык PHP (а также JS/CSS/HTML/SQL), решаем задачки, печем печенье и даже делаем простые сайты! Зачем? Кто-то хочет изменить мир, кто-то заработать на лапшу быстрого приготовления, кому-то просто нечего делать.
Да, в нашем треде отвечают почти на все вопросы, только бампайте каждые 5 дней. И не разводите флуд, если вам скучно, сходите погуляйте, например. Может вас побьет какой-нибудь хороший человек и вы перестанете флудить в нашем треде.
Это тред для начинающих. Не написал за свою жизнь ни одной программы и имеешь тройку по математике? Ты наш человек.
Предыдущий тред был тут: >>1268753 (OP) . Остальные треды есть в архиве: https://phpclub.tech/ (там есть поиск, так что можно легко найти обсуждение какой-то задачи или ответы на свой старый пост) или ищутся в гугле по словам "клуб изучающих php" и в архиваче.
Мейлач лежит, модератор зверствует? Есть запасной тред на доброчане: /s/res/23225.xhtml#i46467
Форматируй свой код, если хочешь, чтобы его читали (как, написано во втором посте).
Правила: ведем себя воспитанно, помогаем новичкам, читаем учебники, решаем задачки, постим ссылки на решения, ОП их проверяет и дает советы и замечания. ОП заходит редко, где-то раз в 2-3 дня, у него мало времени, не жди его, решай задачки дальше. ОП отвечает на все вопросы по его задачкам и учебнику, а вот насчет каких-то других вещей - только если останется время. Но в треде немало анонимных экспертов разного уровня, так что вряд ли вопрос останется без ответа.
С чего начать
У нас есть свои уроки по основам PHP, они собраны и выложены по адресу http://codedokode.github.io/phpbook (вас отредиректит на другой домен, не читайте, не сохраняйте, не запоминайте его, он временный). Это учебник для изучающих с нуля, то есть если ты вообще ничего не знаешь, то можно начать с него. Он простой и понятный. Там есть задачи, их нужно решать (чтобы стать программистом, надо писать код — иначе никак). Пости ссылки на решения в тред, мы их проверим, напишем замечания и дадим советы по улучшению. С другой стороны, если этот учебник тебе не нравится, можно читать любой другой. Или официальный мануал. Или все сразу.
Устанавливать пока что ничего не требуется, разве что редактор кода вроде Sublime Text 3, Notepad++, Visual Studio Code, Netbeans PHP или PhpStorm (с ним будет удобнее).
Если не знаешь как решать, запости код, напиши в каком месте остановился и попроси подсказку.
Ты прошел весь учебник? Молодец, но это были лишь основы языка PHP, этого недостаточно. Вот что в идеале надо изучить еще: ООП, как работает веб-сервер, HTML/CSS, SQL, PDO, работа с таблицами в БД, работа с формами, MVC, git, composer, JS, фреймворки, автоматизированное тестирование.
Надо переходить к более серьезным задачкам, которые научат тебя всему этому.
- для начала прочти урок https://github.com/codedokode/pasta/blob/master/soft/web-server.md
- установи Апач + PHP (советы выше и ниже) и читай туториал http://php.net/manual/ru/tutorial.php
- Учи HTML/CSS и SQL, PDO, хотя бы основы
- Далее простая, но полезная задача сделать список студентов, в ней много полезных советов: https://github.com/codedokode/pasta/blob/master/student-list.md
- Более сложная задача сделать файлообменник на микрофреймворке Slim: https://gist.github.com/codedokode/9424217
- Еще более сложная и долгая задача на Yii/Symfony: https://gist.github.com/codedokode/8733007
- После нее можно изучать автоматизированное тестирование https://gist.github.com/codedokode/a455bde7d0748c0a351a
- Если ты все решил, переходи к Symfony 3/Doctrine 2
- Почитать про паттерны http://designpatternsphp.readthedocs.org/ru/latest/README.html (если ты не изучил ни одного фреймворка, то это будет рановато), тут с примерами кода http://designpatternsphp.readthedocs.org/ru/latest/README.html . Имей в виду что без примеров использования их учить бесполезно - не поймешь, хочешь увидеть примеры использования паттернов - ковыряй исходники Симфони, например Symfony Forms. Не заучивай паттерны - смотри код и думай, зачем тут они использованы.
Чтобы делать эти задания, тебе надо установить Апач + PHP (можно заодно сразу и MySQL) на компьютер. Вот полезные инструкции:
https://github.com/codedokode/pasta/blob/master/soft/php-install.md
https://github.com/codedokode/pasta/blob/master/soft/apache-install.md
Может тебе понадобится пользоваться командной строкой, вот гайд https://github.com/codedokode/pasta/blob/master/soft/cli.md
Решения задач лучше показать мне, особенно на ООП,так как сам ты вряд ли увидишь все ошибки. Пости свой код на гитхаб и вкидывай ссылку в тред по мере решения. Я прокомментирую и укажу на ошибки.
Параллельно стоит подучивать английский, на первых порах можно без него, но по мере развития придется все чаще сталкиваться с англоязычными статьями, так что лучше не откладывать. Читать можно news.ycombinator.com - это что-то вроде их хабра. Также можно начинать смотреть фильмы и видео на английском.
Также, у нас есть задачи которые позволят тебе изучить или подтянуть до нормального уровня знания JS/HTML/CSS/SQL. Решай их параллельно с задачами выше.
- HTML/CSS: https://github.com/codedokode/pasta/blob/master/html/html.md
- JS: https://gist.github.com/codedokode/ce30e7a036f18f416ae0
- SPA (сложно): https://github.com/codedokode/pasta/blob/master/js/spa.md
- Проверялка решений на JS: http://dkab.github.io/jasmine-tests/
- MySQL: https://github.com/codedokode/pasta/blob/master/db/databases.md
Что почитать
- Мануал по PHP — http://www.php.net/manual/ru/langref.php
- Сайт phptherightway (перевод на русский: http://getjump.me/ru-php-the-right-way/ )
- По PHP: Профессиональное программирование на PHP Джордж Шлосснейгл
- По PHP: Мэтт Зандстра — PHP: Объекты, шаблоны, методики программирования
- JS: learn.javascript.ru
- Про Git: https://git-scm.com/book/ru/v1
- Новости IT на англ. https://news.ycombinator.com/
- какой-то древний, устаревший, но большой и на русском справочник по веб-разработке, посоветованный аноном: https://starcat.dp.ua/doc/wdh/
Оформляй код аккуратно!!! — например пропусти через phpformatter.com . Также, если ты пользуешься IDE вроде PhpStorm, Netbeans, Eclipse, то в них эта опция встроена, подробнее: https://gist.github.com/codedokode/8759492
У ОПа нет аккаунтов и групп вконтакте, в фейсбуке, в твиттере, все "пхп-треды" там поддельные.
Платиновые вопросы
- Почему PHP? Потому что вакансий море, и учить легко.
- Сайт опять упал!!!!! — Не паникуй, а открой http://rghost.ru/6bfCY9lfl и получи личную немного устаревшую оффлайновую копию сайта (можно читать хоть на андроиде без интернета)
- Что надо знать чтобы найти работу - разработчику: PHP, SQL, HTML/CSS, JS, ООП, Git, композер, MVC, фреймворк. Верстальщику - HTML/CSS, JS, jQuery. У нас в треде были люди, которые практически с нуля учились и смогли найти работу.
- Что будут спрашивать на собеседовании если 0 опыта - гонять по теории, по официальному мануалу PHP, давать дурацкие задачки на переворачивание строк, гонять по SQL (транзакции, внешние ключи, напиши запрос), по JS (как сделать анимацию при нажатии кнопки), ну погугли, не ленись
- Можно подробнее про поиск работы, собеседования - нет, ОП писать не будет, но может кто из анонов захочет рассказать. Поищите тред перезвонивших, а также раздел /wrk/
- Сколько времени надо изучать все это? - все зависит от тебя, но не меньше 6-8 месяцев
- Нужен ли ООП, фреймворки, MVC, git, composer? — Да, однозначно. Посмотри любую вакансию.
В прошлом треде >>1268753 (OP) все проверено - зайдите и найдите свой пост и скорее всего на него есть ответ. Если я кого-то пропустил, напомните о себе тут.
---
Код нужно писать не как попало, а аккуратно и по правилам. Почему? Потому, что на неакуратно написанный код не хочется даже смотреть. Если каждый будет оформлять код как хочет, будет бардак.
Если тебе лень выравнивать код руками, закачай его на 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
Можно ли ещё какие либо другие действия сократить с кучи строк до одной команды или ещё как то? Особенно мне не нравится 21-22 строка, но другого решения я на тот момент не нашел.
Заранее спасибо.
https://github.com/deadj/deadj.github.io
deadj.github.io
>Эй макаки! Если я тут с вами говна поем, я таким же пидором как вы стану? Может быть есть срединный путь, например полизать говно поверхностно?
>питонобыдлу опять жопу разрывает
Не надоело? ЖС-тред засрали, ПХП-тред засрали, что следующее?
Я к тому что вдруг по работе потом встречусь с пхп и нихуя не пойму, а мне скажут ты че лах чтоле не понимаешь)) иди нахуй отсюда. Я пока не вдупляю что нужно знать обязательно а что нет. Понятно что все знать невозможно. А насчет макак не мне судить с моим уровнем знаний, я пока даже до макаки не дорос.
Оскорблять кого то не хотел, глупо споря о языках скатываться до оскорблений.
> php перед питоном
Нет.
>булева алгебра итд,
Походу дела освоишь.
Для сайтов на джанго мат. не нужна.
Меня тошнит от рекламы пхпсторма и их тупого юмора. Я уж лучше глаза себе ломать буду.
А арч теперь не ляликс?
Ебусь heroku.com .Уже сил моих нету.
Какая есть альтернатива php+mysql + бесплатный домен
Любитель дегенератских шуточек?
ngrok + отсутствие перебоев в элекросети
Покажи виртуалку с настроенным серваком на debian.
Ели его сделать платным, то только ОП убегать и не будет.
Есть два стула, начать изучать JS, либо PHP, на какой сесть?
Где больше шекелей будут давать?
Конечно. Но тут тебе нужны алгоритмы сортировочные. Самый приметивный - пузырёк. Но в твоём случае лучше алгоритм с вставкой. http://publicstatic.ru/sortirovka-vstavkoj-na-php/
Начинай уже думать глобально. А если у тебя человек 100 или 1000? А если у тебя рост отрицательный?
Не понимаю, толсто это или правда. . . . .
как так получилось, что в переменную нумбер набралось 8, если внутри цикла прохода по массиву все эти составляющие? разве не должно было получиться 8 * (кол-во элементов в массиве)?
Ты скопировал код сравнения роста много раз. Тогда цикл foreach не нужен - его нужно убрать.
Другой подход - вместо копирования однотипных команд сделать цикл, чтобы одни и те же команды выполнялись несколько раз, но каждый раз с разными данными.
Для начала, попробуй стереть все внутри foreach, кроме echo. Ты понимаешь, как работает этот код и что он выведет?
После этого, попробуй сделать в цикле такой код:
если (рост текущего ученика выше анона)
то увеличить number на 1
А после цикла выведи, чему равно number.
Если что-то непонятно - уточняй.
Выучи русский язык, олень ты малолетний. В одной итерации цикла может быть столько условий на сколько хватит ОЗУ+swap.
Переменная нумбер имеет значение 8, потому что 8 рыл выше коротышки анона.
Сразу в го, у пхп с асинком нет будущего, к сожалению.
Если тебе нужна только ассинхроннось, то имеет смысл поковырять РеактПХП или только прототип накидать.
А так лучше Го или Джаву.
Подскажите пожалуйста, мб не туда смотрю, вроде был список сделанных списков студентов.
Я уже спрашивал, но нифига не понял как сделать много гет-параметров, хотел бы подсмотреть как другие люди решали мой вопрос.
Допустим я искал студента по фамилии Иванов и сейчас у меня в адресной строке: index.php?search=Иванов
И я хотел бы чтоб кнопка сортировки (например по баллам) тогда имела внутри ссылку на index.php?search=Иванов&sort_by=grades, а если ничего не искал то index.php?sort_by=grades.
Я в twig нашел как засунуть в href текущий url {{ app.request.query.all }}, но как туда добавлять что-то вообще не понимаю, и не гуглится нихрена, и документацию twig почитал нихрена не вижу, я может вообще не с той стороны подхожу?
Скорее не с той стороны всё-таки.
У тебя есть какой-то набор параметров, по которым происходит выборка из базы (например, тебе нужны 20 студентов с фамилией "иванов", отсортированных по имени). Тогда набор параметров будет представлять собой объект с подобными полями:
{order_by: "name", search: "иванов", page: 1, perpage: 20}
Этот объект можно передавать на фронт с бэка, чтобы знать текущее состояние выборки на фронте и по нему строить другие запросы к бэку (например, изменить страницу с первой на вторую). Его же можно передавать get-параметрами (удобнее всего - в обычном джсоне одним параметром), либо в теле post-запроса, и обрабатывать его на бэке (в соответствии с ним построить запрос к базе). Такой подход гораздо гибче ковыряния в request query (тем более в шаблоне).
вырвать руки или ебать тебя в жопу.
сделай форму к странице, сохрани там все варианты
<form>
<input type=hidden name=search value="ivanov">
<input type=hidden name=order value="grades">
<input type=hidden name=page value="1">
</form>
далее делаешь жабаскрипт при клике на ссылку, которая соберет твои данные, типа
$.post("prettyurl.php",{"search": $("input[name=search").val(), "order": $("input[name=search").val()}, function(data){ alert(data);});
году в 2005м закончили с этой ебаторией и генерацией ссылок для пейджеров из php, генери на фронте все ссылки
зыы. с твоим подходом в любой конторке поржут и начнут готовить доки на увольнение, ибо это даж не говнокод а пиздец
Отмечу, что единственный вопрос из него, который меня беспокоит, это вопрос про дублирование JS и PHP кода, т.к. я мельком изучил React и определился с выбором на чем писать
>Мне нравится 3-ий вариант с дублированием кода, но я не могу понять, почему это плохо - это плата за то чтобы опыт пользователя был максимально комфортным.
>
>В отличие от первых двух вариантов, не нужно иметь отдельно и JS и PHP приложения на сервере, а можно обойтись чем-то одним - либо PHP, либо JS.
>
>И к тому же, всё равно не получится не дублировать код. Допустим в упрощенной HTML версии есть формы (поиск или отправка сообщения), их всё равно нужно будет обработать на сервере так же как и в фронтенд JS приложении. Разве это не так?
>
>Если не существует универсальной архитектуры, то почему бы не применить и такой способ?
Нужно писать приложение на ES6, поскольку, я боюсь, что готового решения, для подхвата отрендеренной страницы и дальнейшей работы как SPA приложения просто не существует. Но это хорошо, потому что если чего-то не существует, то это отличная возможность создать это. Интересно, какой подход к этому у Google, на примере с простой HTML страницы gmail.
Я набросал небольшой код, как это примерно будет работать:
https://codepen.io/anon/pen/ePjNLP?editors=0010
Если сказать в двух словах, то приложение должно иметь роутер, который должен делать две вещи:
1) При иницилиазации приложения определять текущий роут и запустить привязанный к нему компонент (в моем случае запустить у компонента метод run() ).
2) При переходе по роутам, очищать страницу, отрисовывать компонент и запускать его.
И именно, 1-ую задачу ни один знакомый мне роутер не может выполнить. Именно поэтому необходимо написать всё самому.
И у меня есть один не большой вопрос... Сейчас, при создании роутера, мы передаём экземпляр компонента, и каждый раз, когда мы инициализируем соответствующий этому экземпляру роут, вызывается метод run() этого компонента, и если в нём есть подписка на какое-то событие (DOM или RxJS Observable), то при переходе на другой роут эта подписка не отмениться, и, что хуже того, при возвращении на этот же роут, повеситься ещё одна такая же подписка. Я должен написать, например, метод stop() или в ES6 есть какой-то трюк для этого?
Кстати, для рендера можно и React использовать.
Back to the god damn jQuery
Отмечу, что единственный вопрос из него, который меня беспокоит, это вопрос про дублирование JS и PHP кода, т.к. я мельком изучил React и определился с выбором на чем писать
>Мне нравится 3-ий вариант с дублированием кода, но я не могу понять, почему это плохо - это плата за то чтобы опыт пользователя был максимально комфортным.
>
>В отличие от первых двух вариантов, не нужно иметь отдельно и JS и PHP приложения на сервере, а можно обойтись чем-то одним - либо PHP, либо JS.
>
>И к тому же, всё равно не получится не дублировать код. Допустим в упрощенной HTML версии есть формы (поиск или отправка сообщения), их всё равно нужно будет обработать на сервере так же как и в фронтенд JS приложении. Разве это не так?
>
>Если не существует универсальной архитектуры, то почему бы не применить и такой способ?
Нужно писать приложение на ES6, поскольку, я боюсь, что готового решения, для подхвата отрендеренной страницы и дальнейшей работы как SPA приложения просто не существует. Но это хорошо, потому что если чего-то не существует, то это отличная возможность создать это. Интересно, какой подход к этому у Google, на примере с простой HTML страницы gmail.
Я набросал небольшой код, как это примерно будет работать:
https://codepen.io/anon/pen/ePjNLP?editors=0010
Если сказать в двух словах, то приложение должно иметь роутер, который должен делать две вещи:
1) При иницилиазации приложения определять текущий роут и запустить привязанный к нему компонент (в моем случае запустить у компонента метод run() ).
2) При переходе по роутам, очищать страницу, отрисовывать компонент и запускать его.
И именно, 1-ую задачу ни один знакомый мне роутер не может выполнить. Именно поэтому необходимо написать всё самому.
И у меня есть один не большой вопрос... Сейчас, при создании роутера, мы передаём экземпляр компонента, и каждый раз, когда мы инициализируем соответствующий этому экземпляру роут, вызывается метод run() этого компонента, и если в нём есть подписка на какое-то событие (DOM или RxJS Observable), то при переходе на другой роут эта подписка не отмениться, и, что хуже того, при возвращении на этот же роут, повеситься ещё одна такая же подписка. Я должен написать, например, метод stop() или в ES6 есть какой-то трюк для этого?
Кстати, для рендера можно и React использовать.
Back to the god damn jQuery
Берешь фреймворк, назначаешь на роуты компоненты, в компонентах подписываешься на хуки : onInit/onDestroy
Нужно быть менее категоричным. А то складывается ощущение, что ты вчера изучил JS и теперь без него обойтись не можешь. То, что ты предлагаешь - просто перенести генерацию ссылок на JS. Необходимость генерации никуда не исчезает. Более того, если ты прочтешь описание ниже, то увидишь более интересный подход к решению, который позволит и обеспечить обновление без перезагрузки, и работу с отключенным JS (например, поисковые боты), и (почти) не писать JS код.
Также, в твоем коде нет индикатора загрузки и обработки ошибок, советую почитать мой урок про аякс: https://github.com/codedokode/pasta/blob/master/js/ajax.md
Также, в твоем решении не будет работать история в браузере, нельзя отправить ссылку на страницу с определенной сортировкой, нельзя добавить ее в закладки. Таблица будет недоступна для индексирования поисковиками.
>>282306
Списка нет, но можно на гитхабе поискать по student list.
> Я в twig нашел как засунуть в href текущий url {{ app.request.query.all }}
Это для фреймворка Симфони, а не для Твига. В Симфони в шаблон передается глобальная переменная app, которая содержит много всяких полей. Это немного нарушает разделение ответственности в MVC, если view может так спокойно залезть в параметры запроса (хотя и сокращает код).
Я вижу, что у многих вызвает вопросы генерация ссылок, давай разберемся. В протоколе HTTP у нас нет состояния: сервер не "помнит", какие параметры пагинации или поиска ты задавал раньше. Потому ты их должен указывать при генерации ссылки. Да, ссылки будут получаться длинные.
Вот вариант решения: сделать функцию, которая будет принимать на вход текущее значение параметров (сортировка, поиск итд), название колонки и выдавать ссылку для нее:
function generateSortLink($viewParams, $column): string
Это может быть функция, метод, статических метод (паттерн Utility Class), функция-расширение twig. Она определяет по названию колонки и текущей выбранной колонке направление сортировки, собирает параметры и генерирует ссылку, например, с помощью http_build_query.
Что такое $viewParams? Это текущие параметры вывода таблицы, их конечно можно сделать массивом, а можно сделать классом с комментариями:
class TableFilter
{
public $searchPhrase;
public $sortBy;
public $sortDir;
public $page
}
Заметим, что класс получился универсальный и подойдет не только к таблице студентов, но и вообще к любой таблице с фильтром и сортировкой.
Аналогично, для пагинации можно написать похожую функцию:
function generatePagerLink(TableFilter $viewParams, int $page): string
При желании, можно как-то объединить эти функции в одну универсальную, например, такую:
function generateTableLink(TableFilter $currentParams, array $replace): string
Не забудь, что при смене вида сортировки или при поиске мы сбрасываем номер страницы.
Теперь затронем тему аякса и JS. В страницу можно встраивать код на JS, который может сам отправлять запросы на сервер аяксом и вставлять результат на страницу без ее перезагрузки. Если ты разбираешься или интересуешься JS и хочешь сделать обновление таблицы без перезагрузки, то есть довольно интересная библиотека pjax. Она перехватывает клики по ссылкам, запрашивает указанную в ссылке страницу аяксом и вставляет ее в указанную область страницы. Таким образом ты можешь сделать страницу, работающую без JS, а затем в соответствие с принципом progressive enhancement, для пользователей с JS добавить возможность работы без перезагрузки страницы. И это все - почти без написания JS кода.
pjax умеет отправлять формы, потому ты можешь заставить форму поиска работать без перезагрузки страницы при наличии JS.
При этом будет корректно работать кнопка "назад" и обновляться URL в браузере.
Если что-то еще непонятно - задавай вопросы. Это обучающий тред.
Нужно быть менее категоричным. А то складывается ощущение, что ты вчера изучил JS и теперь без него обойтись не можешь. То, что ты предлагаешь - просто перенести генерацию ссылок на JS. Необходимость генерации никуда не исчезает. Более того, если ты прочтешь описание ниже, то увидишь более интересный подход к решению, который позволит и обеспечить обновление без перезагрузки, и работу с отключенным JS (например, поисковые боты), и (почти) не писать JS код.
Также, в твоем коде нет индикатора загрузки и обработки ошибок, советую почитать мой урок про аякс: https://github.com/codedokode/pasta/blob/master/js/ajax.md
Также, в твоем решении не будет работать история в браузере, нельзя отправить ссылку на страницу с определенной сортировкой, нельзя добавить ее в закладки. Таблица будет недоступна для индексирования поисковиками.
>>282306
Списка нет, но можно на гитхабе поискать по student list.
> Я в twig нашел как засунуть в href текущий url {{ app.request.query.all }}
Это для фреймворка Симфони, а не для Твига. В Симфони в шаблон передается глобальная переменная app, которая содержит много всяких полей. Это немного нарушает разделение ответственности в MVC, если view может так спокойно залезть в параметры запроса (хотя и сокращает код).
Я вижу, что у многих вызвает вопросы генерация ссылок, давай разберемся. В протоколе HTTP у нас нет состояния: сервер не "помнит", какие параметры пагинации или поиска ты задавал раньше. Потому ты их должен указывать при генерации ссылки. Да, ссылки будут получаться длинные.
Вот вариант решения: сделать функцию, которая будет принимать на вход текущее значение параметров (сортировка, поиск итд), название колонки и выдавать ссылку для нее:
function generateSortLink($viewParams, $column): string
Это может быть функция, метод, статических метод (паттерн Utility Class), функция-расширение twig. Она определяет по названию колонки и текущей выбранной колонке направление сортировки, собирает параметры и генерирует ссылку, например, с помощью http_build_query.
Что такое $viewParams? Это текущие параметры вывода таблицы, их конечно можно сделать массивом, а можно сделать классом с комментариями:
class TableFilter
{
public $searchPhrase;
public $sortBy;
public $sortDir;
public $page
}
Заметим, что класс получился универсальный и подойдет не только к таблице студентов, но и вообще к любой таблице с фильтром и сортировкой.
Аналогично, для пагинации можно написать похожую функцию:
function generatePagerLink(TableFilter $viewParams, int $page): string
При желании, можно как-то объединить эти функции в одну универсальную, например, такую:
function generateTableLink(TableFilter $currentParams, array $replace): string
Не забудь, что при смене вида сортировки или при поиске мы сбрасываем номер страницы.
Теперь затронем тему аякса и JS. В страницу можно встраивать код на JS, который может сам отправлять запросы на сервер аяксом и вставлять результат на страницу без ее перезагрузки. Если ты разбираешься или интересуешься JS и хочешь сделать обновление таблицы без перезагрузки, то есть довольно интересная библиотека pjax. Она перехватывает клики по ссылкам, запрашивает указанную в ссылке страницу аяксом и вставляет ее в указанную область страницы. Таким образом ты можешь сделать страницу, работающую без JS, а затем в соответствие с принципом progressive enhancement, для пользователей с JS добавить возможность работы без перезагрузки страницы. И это все - почти без написания JS кода.
pjax умеет отправлять формы, потому ты можешь заставить форму поиска работать без перезагрузки страницы при наличии JS.
При этом будет корректно работать кнопка "назад" и обновляться URL в браузере.
Если что-то еще непонятно - задавай вопросы. Это обучающий тред.
Если захочешь использовать pjax или просто аякс в любом виде, прочти пожалуйста сначала урок: https://github.com/codedokode/pasta/blob/master/js/ajax.md
> Мне нравится 3-ий вариант с дублированием кода, но я не могу понять, почему это плохо - это плата за то чтобы опыт пользователя был максимально комфортным.
Потому, что это на практике очень плохо будет работать. Разработчик добавляет новую фичу в JS-версию. Не забудет ли он добавить ее в PHP-версию? Или исправление бага. Плюс, удваиваются затраты времени. Дублирование кода - почти всегда плохо. Если же код не дублировать, то такие ситуации, когда 2 версии кода работают по-разному, сразу исключаются.
Плюс, мессенджер это все же приложение. Пользоваться им с перезагрузками страницы будет не очень комфортно.
Конечно, бывают случаи, когда это оправданно. Например, фейсбук делал легкую HTML версию для слабых телефонов. У Gmail есть легкая версия. У фейсбука это полностью отдельное приложение. Раньше многие сайты делали мобильную версию отдельными контроллерами и шаблонами.
В нашем случае еще и немного ухудшается безопасность, идеальнее было бы расшифровывать сообщения только на клиенте.
Если и делать PHP версию, то максимально простую. Ведь цель - слабые устройства с ограниченным трафиком. Но тогда придется делать ее на отдельном URL (https://messenger/h/), к ней не получится прицепиться из реакт-приложения (да и если она выглядит по-другому, то пользователя не обрадует внезапная смена внешнего вида в процессе загрузки).
> И к тому же, всё равно не получится не дублировать код. Допустим в упрощенной HTML версии есть формы (поиск или отправка сообщения), их всё равно нужно будет обработать на сервере так же как и в фронтенд JS приложении. Разве это не так?
Да, действительно. Обработчик, может быть, придется писать отдельно. Но у меня была мысль, нельзя ли сэкономить на написании шаблона и кода для отображения данных (view). Чтобы и на сервере, и на клиенте страницу рисовал один и тот же код.
Кстати, в классическом HTML надо бы добавить в форму уникальное число - nonce - для защиты от случаев, когда плохая связь и пользователь несколько раз отправляет форму с сообщением.
> Однако, как я уже писал, первые два способа можно улучшить, отказавшись от PHP и писать API на Node.js.
Не вижу большой разницы, на чем писать API. Хотя, у ноды тут может быть плюс. Ты можешь попробовать сделать часть кодаизоморфоной, чтобы она могла работать и на сервере, и на клиенте. Например, модели или еще что-то.
> +Сверх быстрая отрисовка DOM
Ой-ой. "Быстрый" в реакте - это значит "быстрый в сравнении с другими фреймворками, делающими сравнение деревьев DOM", а не быстрее любых JS библиотек.
Но реакт имеет еще плюс в том, что есть React Native - это для написания нативных приложений (в первую очередь мобильных), где ты пишешь код на JS, но без HTML/CSS, вместо них ты используешь нативные для платформы виджеты (кнопки, текстовые блоки и тд).
> -Нужно изучить React, чтобы понять может ли он подхватывать отрендеренную на сервере HTML страницу и дальше работать как SPA приложение
Я погуглил и нашел это: https://reactjs.org/docs/react-dom-server.html - если ты используешь то же самое приложение на сервере, то думаю, что можно:
> If you call ReactDOM.hydrate() on a node that already has this server-rendered markup, React will preserve it and only attach event handlers, allowing you to have a very performant first-load experience.
> 2) PHP (Symfony) + нативное ES6 приложение на фронтенде
И еще там больше работы в сравнении с реакт.
> Неизвестно какой ответ будет от запросов отправленных с упрощенной HTML страницы и будут ли промисы выполняться тоже на серверной части или "подхватяться" на клиентской
Промисы никак не подхватятся. Они работают только внутри процесса ОС (промис это обертка для результата выполнения асинхронной операции). Если ты запустил чтение файла на сервере, оно не продолжится на клиенте (там банально нет этого файла). Если обработчик отправки сообщения на сервере сделан на промисах, надо дождаться их завершения перед генерацией HTML кода. Что касается ответа на отправку формы - он должен быть классическим HTML, чтобы браузер без JS мог его отобразить.
> И ещё мне сейчас пришел 4-ый вариант с вашей подсказкой про socket_create():
Получать запросы в PHP коде и проксировать их в серверное приложение? Можно, но не очень понятно, зачем, если можно поднять сервер на ноде и работать без посредника на PHP.
> что из этого выбрать, чтобы было просто надёжно, т.е. чтобы в дальнейшем не возникало каких-то проблем с подхватом HTML страницы JS кодом
Это есть и в реакт, и в ангулар. Чтобы это реализовать, страницу надо генерировать на сервере из того же шаблона тем же приложением. Из двух я бы выбрал реакт из-за популярности и наличия React Native.
> Если сократить, то вопрос будет простым - может ли React подхватывать HTML страницу и вешать на неё JS?
Да. https://reactjs.org/docs/react-dom-server.html
> Мне нравится 3-ий вариант с дублированием кода, но я не могу понять, почему это плохо - это плата за то чтобы опыт пользователя был максимально комфортным.
Потому, что это на практике очень плохо будет работать. Разработчик добавляет новую фичу в JS-версию. Не забудет ли он добавить ее в PHP-версию? Или исправление бага. Плюс, удваиваются затраты времени. Дублирование кода - почти всегда плохо. Если же код не дублировать, то такие ситуации, когда 2 версии кода работают по-разному, сразу исключаются.
Плюс, мессенджер это все же приложение. Пользоваться им с перезагрузками страницы будет не очень комфортно.
Конечно, бывают случаи, когда это оправданно. Например, фейсбук делал легкую HTML версию для слабых телефонов. У Gmail есть легкая версия. У фейсбука это полностью отдельное приложение. Раньше многие сайты делали мобильную версию отдельными контроллерами и шаблонами.
В нашем случае еще и немного ухудшается безопасность, идеальнее было бы расшифровывать сообщения только на клиенте.
Если и делать PHP версию, то максимально простую. Ведь цель - слабые устройства с ограниченным трафиком. Но тогда придется делать ее на отдельном URL (https://messenger/h/), к ней не получится прицепиться из реакт-приложения (да и если она выглядит по-другому, то пользователя не обрадует внезапная смена внешнего вида в процессе загрузки).
> И к тому же, всё равно не получится не дублировать код. Допустим в упрощенной HTML версии есть формы (поиск или отправка сообщения), их всё равно нужно будет обработать на сервере так же как и в фронтенд JS приложении. Разве это не так?
Да, действительно. Обработчик, может быть, придется писать отдельно. Но у меня была мысль, нельзя ли сэкономить на написании шаблона и кода для отображения данных (view). Чтобы и на сервере, и на клиенте страницу рисовал один и тот же код.
Кстати, в классическом HTML надо бы добавить в форму уникальное число - nonce - для защиты от случаев, когда плохая связь и пользователь несколько раз отправляет форму с сообщением.
> Однако, как я уже писал, первые два способа можно улучшить, отказавшись от PHP и писать API на Node.js.
Не вижу большой разницы, на чем писать API. Хотя, у ноды тут может быть плюс. Ты можешь попробовать сделать часть кодаизоморфоной, чтобы она могла работать и на сервере, и на клиенте. Например, модели или еще что-то.
> +Сверх быстрая отрисовка DOM
Ой-ой. "Быстрый" в реакте - это значит "быстрый в сравнении с другими фреймворками, делающими сравнение деревьев DOM", а не быстрее любых JS библиотек.
Но реакт имеет еще плюс в том, что есть React Native - это для написания нативных приложений (в первую очередь мобильных), где ты пишешь код на JS, но без HTML/CSS, вместо них ты используешь нативные для платформы виджеты (кнопки, текстовые блоки и тд).
> -Нужно изучить React, чтобы понять может ли он подхватывать отрендеренную на сервере HTML страницу и дальше работать как SPA приложение
Я погуглил и нашел это: https://reactjs.org/docs/react-dom-server.html - если ты используешь то же самое приложение на сервере, то думаю, что можно:
> If you call ReactDOM.hydrate() on a node that already has this server-rendered markup, React will preserve it and only attach event handlers, allowing you to have a very performant first-load experience.
> 2) PHP (Symfony) + нативное ES6 приложение на фронтенде
И еще там больше работы в сравнении с реакт.
> Неизвестно какой ответ будет от запросов отправленных с упрощенной HTML страницы и будут ли промисы выполняться тоже на серверной части или "подхватяться" на клиентской
Промисы никак не подхватятся. Они работают только внутри процесса ОС (промис это обертка для результата выполнения асинхронной операции). Если ты запустил чтение файла на сервере, оно не продолжится на клиенте (там банально нет этого файла). Если обработчик отправки сообщения на сервере сделан на промисах, надо дождаться их завершения перед генерацией HTML кода. Что касается ответа на отправку формы - он должен быть классическим HTML, чтобы браузер без JS мог его отобразить.
> И ещё мне сейчас пришел 4-ый вариант с вашей подсказкой про socket_create():
Получать запросы в PHP коде и проксировать их в серверное приложение? Можно, но не очень понятно, зачем, если можно поднять сервер на ноде и работать без посредника на PHP.
> что из этого выбрать, чтобы было просто надёжно, т.е. чтобы в дальнейшем не возникало каких-то проблем с подхватом HTML страницы JS кодом
Это есть и в реакт, и в ангулар. Чтобы это реализовать, страницу надо генерировать на сервере из того же шаблона тем же приложением. Из двух я бы выбрал реакт из-за популярности и наличия React Native.
> Если сократить, то вопрос будет простым - может ли React подхватывать HTML страницу и вешать на неё JS?
Да. https://reactjs.org/docs/react-dom-server.html
> Я набросал небольшой код, как это примерно будет работать:
Что-то он по виду React напоминает. Если хочется попробовать сделать свой аналог реакта, то можно сделать, если нет, то проще использовать уже написанный фреймворк.
> $('.feed ul').
Тут кстати должен быть поиск не по всей странице, а относительно корня компонента.
> Нужно писать приложение на ES6, поскольку, я боюсь, что готового решения, для подхвата отрендеренной страницы и дальнейшей работы как SPA приложения просто не существует
Реакт и ангулар же вроде умеют это.
> И именно, 1-ую задачу ни один знакомый мне роутер не может выполнить. Именно поэтому необходимо написать всё самому.
Не может быть такого. Наверняка есть такая возможность.
> Сейчас, при создании роутера, мы передаём экземпляр компонента, и каждый раз, когда мы инициализируем соответствующий этому экземпляру роут, вызывается метод run() этого компонента, и если в нём есть подписка на какое-то событие (DOM или RxJS Observable), то при переходе на другой роут эта подписка не отмениться
Да, надо делать "жизненный цикл" компонента, предусмотреть в нем метод detach(), и гарантировать его вызов перед удалением компонента из дерева DOM. И, конечно, вызывать detach() у всех дочерних компонентов. А уже в этом методе мы отменяем подписку на события и все остальное.
В Реакте это делается за счет метода componentWillUnmount: https://reactjs.org/docs/state-and-lifecycle.html#adding-lifecycle-methods-to-a-class
>>282689
Спасибо за ответы - у меня теперь не возникает сомнений на чем и как писать.
>Ведь цель - слабые устройства с ограниченным трафиком.
Моя цель изначально была сделать поддержку приложения с отключенным JS, потому что по версии Tor Project это повысит безопасность (https://www.torproject.org/docs/faq.html.en#TBBJavaScriptEnabled).
>On the other hand, we should disable JavaScript by default to better protect against browser vulnerabilities ( not just a theoretical concern!).
Но, за счет того, что простые HTML страницы тоже будут работать, это сыграет и на пользу слабых устройств с ограниченным трафиком.
>Но у меня была мысль, нельзя ли сэкономить на написании шаблона и кода для отображения данных (view). Чтобы и на сервере, и на клиенте страницу рисовал один и тот же код.
Да, я теперь вижу эту точку зрения. Для этого нужно писать серверную часть на Node.js. Это может занять ещё какое-то время.
Спасибо большое за ответы, ещё раз.
* Забыл написать
>В нашем случае еще и немного ухудшается безопасность, идеальнее было бы расшифровывать сообщения только на клиенте.
Я тоже думал об этом, и мне пришла в голову мысль, что обычные чаты шифруются более просто, а для GPG использовать особые "секретные чаты" как в телеграмме, которые будт работать только с включенным JS или в нативных приложениях. Причем можно добавить функцию, чтобы пользователь мог сам загружать свои приватные/публичные ключи. Хранить приватные ключи на сервере, конечно же плохая идея, даже если они зашифрованы паролем.
А, кстати, я вспомнил, есть интересный мессенджер Tox - он работает вообще без серверов, за счет DHT сети (как в торрентах) и прямых соединений между клиентами. И тоже все шифрует. Может еще из него можно какие-то идеи подчерпнуть.
Такие компромиссы не очень хорошие, приложение либо надежно, либо нет. В твоем варианте, те, кто использует секретные чаты, будут выделяться среди пользователей и привлекать внимание.
Это всё из-за аниме.
Помню-помню что вы писали об этом. У меня всё это отмечено и будет изучено когда дойдёт очередь.
>>282922
Тогда возникает ряд проблем связанных с передачей ключей между приложениями, т.е. пользователь может использовать браузерную/десктопную/мобильное приложения и все они как-то должны обмениваться своими приватными ключами.
Или, я только что подумал, у GPG есть возможность шифровать сообщения для разных ключей одновременно, поэтому можно каждый раз при "узнавании"нового аккаунта генерировать новую пару ключей, и делиться публичным между клиентами и контактами. Только у такого метода есть недостаток: может накопиться слишком большое количество таких ключей, и нет возможности проверить пользуется ли ими ещё пользователь.
Или просто хранить приватный ключ зашифрованный паролем на сервере. Но мне такая идея просто не нравится, хоть у меня и нету весомых причин для этого, кроме той, что если пароль от приватного ключа слишком простой, то его можно просто брутфорснуть (но это вина пользователя что он имеет слабый пароль).
>ВОПРОС, стоит ли учить php перед питоном
Если чтобы потом кодить на питоне - нет, конечно. Это примерно как научиться ездить на тракторе, чтобы потом ездить на легковушке: php и сам по себе-то в разы сложнее питона, а если наворачивать что-то кроме кора, то это у тебя растянется на полтора года. Опять же, изучать только кор, в отрыве от домена применения - бесполезно, писать какие-то скрипты в разы проще на удаве, да и приятнее, да и либок навернуто с миллион на каждую тему.
ОП, скинь эталонную (на твой взгляд) реализацию списка студентов. Можешь?
Оп, знаю что занят. Но глянь моих студентов:
https://github.com/Awesome-Kirill/fukingStudent
>>283020
Я к выходным первую версию своего ТестХаба выложу
Ничего сложного, без задней мысли берешь и делаешь
я бы попу выбрал
Работаете над cpa-сетью?
Вкатыватьщик на стажировку ИТТ, постараюсь.
Саблайм, если ты готов каждый день закрывать окно с просьбой дать денег.
kate, gedit - простые редакторы с подсветкой.
vim/emacs если ты любишь нестандартные сочетания клавиш
Netbeans - если хочется IDE на Яве, но бесплатно. Если там есть какие-то косяки, ты получаешь уникальную возможность их исправить.
Он сейчас поломан на ауре.
Почти.
найди старый активационный код, а после добавь сервер активации в блок ( hosts -> 0.0.0.0 )
сервер активации еще надо найти рабочий, они как то долго не живут.
>>283400
симфони дичайший кал, но жабаскриптеры хвалят, типа им просто в пхпшечку запрыгивать и писать лютый говнокод
>>283350
ты удивишься, но так написано 90% прожектов. почти каждый раз случается:
1. да ладно, мне дружбан вася за пиво напишет
2. надо кого на 300 баксов нанять, хотя бы удаленно, вася послал нахуй с обновлением
3. биз прет и мы нанимаем разработчика в штат, но подешевле. какой дурак нанимает разработчика за 500к дерева, когда и за 30 сделают тоже самое.
profit !!
Лайк. рабочий способ
Нахуй существует это говно вообще блядь?
Оно никогда не работает. Не соответстует своей доке. Чтобы чтото там сделать необходимо писать костыли и т.д.
Заставили создать страницу на какомто новом говне - Тридион. Блядь я бы на 3х языках сайт уже переписал пока разбираюсь
Зачем ты присваиваешь результат выполнения функции переменным и пытаешься его вывести, если у тебя весь вывод информации осуществляется в функции? Алсо, ставь пробелы между параметрами функции, после управляющих конструкций и перед кавычками, изучи psr-2 хотя бы в рамках описания уже известных тебе языковых конструкций, если хочешь чтобы твой код можно было нормально прочесть.
>Алсо, ставь пробелы между параметрами функции, после управляющих конструкций и перед кавычками, изучи psr-2 хотя бы в рамках описания уже известных тебе языковых конструкций, если хочешь чтобы твой код можно было нормально прочесть.
>
Благодарочка, исправлюсь. А присваиваю, потому что иначе почему-то ideone не хочет выводить ответ, и output будет пуст
Двачую. Укатываюсь из ПХП, только потому что я хочу работать с сервером, а не адаптивной говноверсткой заниматься
есть проблема , прошу анона помочь.
Есть свой сайт, ПХП поддерживает, скрипты ПХП уже есть свои и все работают, то есть технически все в порядке.
Пытаюсь , заодно и теоритические знания получать, читаю , и на своем же сайте испытываю . Так вот , читаю тут эту темку
https://myrusakov.ru/php-curl-post.html
Создаю 2 файла, пытаюсь выполнить код, что в примере
<?php
$a = $_POST['a'];
$b = $_POST['b'];
echo $a + $b;
?>
и второй
<?php
if( $curl = curl_init() ) {
curl_setopt($curl, CURLOPT_URL, 'http://mysite.ru/receiver.php');
curl_setopt($curl, CURLOPT_RETURNTRANSFER,true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, "a=4&b=7");
$out = curl_exec($curl);
echo $out;
curl_close($curl);
}
?>
Понятно, название сайта свое, он выдает ошибку 301 Moved Permanently. Гуглил как испавить, судя по всему такая ошибка возникает не редко. Догуглился до того что вставил
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
теперь он уже не показывает ошибку 301 ,а показывает пустаю страницу. Если открыть файл receiver.php то цифра ноль и все.
Скажите пожалуйста, как заставить эту хуйню работать. Спасибо
есть проблема , прошу анона помочь.
Есть свой сайт, ПХП поддерживает, скрипты ПХП уже есть свои и все работают, то есть технически все в порядке.
Пытаюсь , заодно и теоритические знания получать, читаю , и на своем же сайте испытываю . Так вот , читаю тут эту темку
https://myrusakov.ru/php-curl-post.html
Создаю 2 файла, пытаюсь выполнить код, что в примере
<?php
$a = $_POST['a'];
$b = $_POST['b'];
echo $a + $b;
?>
и второй
<?php
if( $curl = curl_init() ) {
curl_setopt($curl, CURLOPT_URL, 'http://mysite.ru/receiver.php');
curl_setopt($curl, CURLOPT_RETURNTRANSFER,true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, "a=4&b=7");
$out = curl_exec($curl);
echo $out;
curl_close($curl);
}
?>
Понятно, название сайта свое, он выдает ошибку 301 Moved Permanently. Гуглил как испавить, судя по всему такая ошибка возникает не редко. Догуглился до того что вставил
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
теперь он уже не показывает ошибку 301 ,а показывает пустаю страницу. Если открыть файл receiver.php то цифра ноль и все.
Скажите пожалуйста, как заставить эту хуйню работать. Спасибо
Зато будешь тратить несколько дней на рефакторинг и дебагинг (если конечно это реальный проект, а не манясайт на локалхосте) вместо нажатия пары клавиш.
У меня вот на нынешней работе исключительно бэкенд. Так что я даже задачки опа хз как решать, потому что всякие хтмл и жс вообще не знаю.
Непонятно, как у тебя вообще может вернуться 301 - потому что это не ошибка, а ответ-редирект. Грубо говоря, сервер говорит браузеру "301: иди вон туда ->>>>".
Выставив же CURLOPT_FOLLOWLOCATION ты просто прошёл по адресу.
Вангую, что твой запрос летит просто не на тот скрипт.
Поэтому посмотри заголовки ответа, тебе должен прийти заголовок Location - это скорее всего даст тебе ответ, кто именно тебя редиректит и куда.
NetBeans - годнота на самом деле, но придетс напильником поработать - чтото поднастроить, какие-то плагины накатить
Дано много блогов на WP с установленным плагином, этот плагин имеет API с кучей эндпоинтов.
Есть сайт, с веб сервера которого нужно делать запросы к блогу на эти эндпоинты.
Как обезопаситься да так, чтобы инициация была только со стороны веб сервера, а не вордпресса? То есть тупо в плагине же я не могу хранить user:password которые буду сравнивать с пришедшими с запросом из веб-сервера, как быть?
Сгенерить токен при инсталле плагина, сохранить его, а потом передать на веб-сервер я тоже не могу, потому что инициатор всех действий - веб сервер.
Какие еще есть варианты?
ты либо пойдешь в контору с пхп, либо с питоном. вряд ли там будут оба бекенд языка использоваться.
на жс чуть больше в снг секторе из-за его хайповости, особенно если ты фуллстек нода + реактом
зачем тебе жаба?
беру джангу, пили круды
А не может сервер его футболить из-за отсутствия нужных заголовков, типа наличия версии браузера и прочего ливера? Ну, вроде как защита от ботов такая?
спасибо за ответы.
Ошибку 301 он после проставления CURLOPT_FOLLOWLOCATION уже не выдавал, там просто нихуя не происходила , пустая страница.Интересно как это понимать? В коде вроде ошибок нет, да я его и тупо копировал.
А если CURLOPT_FOLLOWLOCATION, то 301. Как-то так.
>>284087
пробывал разными браузерами одно и то же
Есть задача. Редактировать документ онлайн.
По прямой ссылке обращаться нельзя.
Документы должны хранится на локальном сервере.
Какие варианты решения можете предложить?
P.S Хотелось бы бесплатный вариант на подобии webdav. Можно открывать документ средствами юзера, но что бы он потом сохранялся на сервер.
Тебе в жс тренд.
Так как ты пишешь, обычно не делают. Есть (нестрогое) правило, что если в массиве больше 2-х элементов, его пишут в столбик, а не в строчку.
Ну и да, советую поставить phpstorm, настроить себе code style: psr-2, а потом вызвать автоформатирование проекта - увидишь как правильно.
Давай попробуем начать со статьи https://github.com/codedokode/pasta/blob/master/arch/di.md
Или там недостаточно простой язык?
Для понимания статьи надо знать ООП.
Читай статьи кайнд оф "вопросы к php-разработчику на собеседованиях" на хабре (ну и комментарии, ясен пень).
Ну и отдельно вопросы и мануалы по выбранному фреймворку.
Обычно, классика это внутренности php (типы, наследование, позднее статическое связывание), схема работы интернета (веб-сервер, всё такое), ООП-паттерны (нарисуй синглтон, т.п.) и базы данных (джоины, агрегации).
Ещё раз, убери CURLOPT_FOLLOWLOCATION и скажи, что у тебя возвращается в заголовке Location?
Делаю запрос connfirmation.php?ordernum=123 но нихуя не работает, объясните долбоебу почему.
Connfirmation.php:
<?php
$ordernum=$_GET['ordernum']
require_once 'connection.php';
// подключаемся к серверу
$conn = mysqli_connect($host, $user, $password, $database);
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
$sql ="UPDATE orders SET confirm='YES' WHERE Num='$ordernum'";
if (mysqli_query($conn, $sql)) {
echo "Record updated successfully";
} else {
echo "Error updating record: " . mysqli_error($conn);
}
mysqli_close($link);
?>
Делаю запрос connfirmation.php?ordernum=123 но нихуя не работает, объясните долбоебу почему.
Connfirmation.php:
<?php
$ordernum=$_GET['ordernum']
require_once 'connection.php';
// подключаемся к серверу
$conn = mysqli_connect($host, $user, $password, $database);
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
$sql ="UPDATE orders SET confirm='YES' WHERE Num='$ordernum'";
if (mysqli_query($conn, $sql)) {
echo "Record updated successfully";
} else {
echo "Error updating record: " . mysqli_error($conn);
}
mysqli_close($link);
?>
Что за ошибка возникает или какой ответ?
У тебя так же есть уязвимость к SQL-инъекциям. У нас есть паста как избежать её https://github.com/codedokode/pasta/blob/master/security/sql-injection.md
Благодарю! Потерял
Чувства тебя не обманывают, задрачивание паттернов, особенно в отрыве от практики тебе ничего особенно не даст, более того все без применения это довольно быстро забудется. Лучше почитать действительно важные книги вроде Совершенный код Макконнелла или чистый код Р. Мартина, sicp навернуть в конце концов. Это, конечно, только мое мнение но паттерны штука опциональная, которая изучается уже в процессе, а не нечто фундаментальное и необходимое. От того что начнешь всюду пихать абстрактные фабрики,код лучше и понятней не становится.
А потом такие дауны никуда не могут вкатится годами, потому что тратят все время на бесполезные для веба задачки, а фронт контроллер написать не в состоянии.
у меня небольшой шоп, вообще я вручную по мылу запрашиваю подтверждение о покупке, хотел немного автоматизировать процесс.
ошибок не возникает никаких, ответов тоже никаких, смотрю через консоль в firefox. В логах просто отправка запроса. Спс за ссылку, почитаю на досуге.
ага, лучше быть таким уебком который на хеловорд пишет 4 класса и контроллер, а если надо оправить мыло всунут ДИ, ну так модно жеж.
и я всегда с удовольствием смотрю на жжение ануса у заказчика, когда его модный и хваленый ленд переписывается и код занимает экран понятного кода, а не 20 классов прикрученных к симфони, которые ему писали месяц
>ошибок не возникает никаких, ответов тоже никаких
Возможно, у тебя отключен вывод ошибок в настройках php. Вот первая ссылка из гугла как их включить https://karashchuk.com/PHP/error_reporting-display_errors-display_startup_errors/
В крайнем случае ты можешь после каждой переменой выводить её значение с помощью var_dump().
https://secure.php.net/manual/ru/function.var-dump.php
>смотрю через консоль в firefox
Также, обрати внимание на код ответа (400 - ОК, 500 - Внутренняя ошибка сервера).
Чуствуется запашок проперженного дивана от твоего поста...
1) На практике ситуация диаметрально противоположная. Внезапно оказывается что у заказанного лендоса должен быть магазин, авторизация с ролями, управление заказами и так далее и так далее.
2) Заказчик никода не заглядывает в код. Ему побоку один там экран или 100500.
3) Вовремя ты никогда не напишешь потому, что четкое ТЗ , по крайней мере для мира пыхеров - это что то из области розовых пони.
Мимо
Согласен на 70%. Сразу наворачивать симфони и тридцать классов тоже - ещё одна крайность.
Мудрый разработчик выберет то, что при минимальных трудозатратах принесёт максимум пользы сейчас и в ближайшее время, но при этом будет расширяемо до более сложных вариантов по необходимости - и заранее предупредит заказчика.
Другой мимо
Спор не имеет смысла.
Очевидно, нужны и теория и практика, в комплексе.
Иначе это будет или заучивание бессмысленных концепций, или кодирование без понимания того, что ты делаешь и зачем.
вы забыли про:
4. оплата за ваш труд - 2 миски похлебки и мы подумаем платить вам или нет
5. а в последующем помимо управления заказами надо будет привязать все к битриксу, друпалу, водпрессу, настроить под поисковики и т.д. то чего почти все фреймворки не умеют из коробки
> ошибок не возникает никаких, ответов тоже никаких, смотрю через консоль в firefox.
Из твоего описания трудно понять, о чем речь. Не написано:
- как ты отправляешь запрос? Руками вводишь в адресную строку, отправкой формы, аяксом, как-то еще?
- что возвращается в ответ? Если ты отправляешь аяксом, то надо смотреть в инструментах разработчика на вкладке Network
- есть ли что-то в логах ошибок на сервере?
У тебя код так сделан, что он не может просто ничего не вывести и не дать какой-то ошибки.
Ну и как тебе написал анон, на локальном сервере стоит включить вывод ошибок на экран, опциями display_errors и error_reporting в php.ini.
>>285057
А зачем переписывать код, который уже работает? Денег много лишних?
DI придуман не просто так, у меня, если что, есть урок про него.
Плюсы Симфони, например, в наличии библиотек для нее. Например, готовая библиотека для авторизации/регистрации, библиотека для входа через соцсети и тд. Это вручную писать заново смысла нет.
>>284761
Не очень понятно, чем именно можно тебе помочь. Если ты хотел спросить, что такое API, то вот советы:
- API это набор правилили стандартов для взаимодействия между программами
- тут скорее всего (ты не написал подробностей) API основан на протоколе HTTP
- значит, надо прочесть про HTTP, например, тут: https://github.com/codedokode/pasta/blob/master/network/http.md
- затем надо прочесть документацию по API
- затем, посмотреть, может для работы с API уже есть готовая библиотека?
- если нет, придется писать свой код для отправки HTTP запросов. Можно взять библиотеку вроде Guzzle для этого.
> ошибок не возникает никаких, ответов тоже никаких, смотрю через консоль в firefox.
Из твоего описания трудно понять, о чем речь. Не написано:
- как ты отправляешь запрос? Руками вводишь в адресную строку, отправкой формы, аяксом, как-то еще?
- что возвращается в ответ? Если ты отправляешь аяксом, то надо смотреть в инструментах разработчика на вкладке Network
- есть ли что-то в логах ошибок на сервере?
У тебя код так сделан, что он не может просто ничего не вывести и не дать какой-то ошибки.
Ну и как тебе написал анон, на локальном сервере стоит включить вывод ошибок на экран, опциями display_errors и error_reporting в php.ini.
>>285057
А зачем переписывать код, который уже работает? Денег много лишних?
DI придуман не просто так, у меня, если что, есть урок про него.
Плюсы Симфони, например, в наличии библиотек для нее. Например, готовая библиотека для авторизации/регистрации, библиотека для входа через соцсети и тд. Это вручную писать заново смысла нет.
>>284761
Не очень понятно, чем именно можно тебе помочь. Если ты хотел спросить, что такое API, то вот советы:
- API это набор правилили стандартов для взаимодействия между программами
- тут скорее всего (ты не написал подробностей) API основан на протоколе HTTP
- значит, надо прочесть про HTTP, например, тут: https://github.com/codedokode/pasta/blob/master/network/http.md
- затем надо прочесть документацию по API
- затем, посмотреть, может для работы с API уже есть готовая библиотека?
- если нет, придется писать свой код для отправки HTTP запросов. Можно взять библиотеку вроде Guzzle для этого.
Не, код довольно краток и сокращать дальше уже нечего.
Насчет форматирования - мне кажется, что тесно сгруппированные значения массивов читабельнее. В PSR-1 и 2 (рекомендации по оформлению кода) я не нашел требований к оформлению массивов.
>>283722
Она позволяет избавиться от написания рутинных запросов, что полезно. Когда у тебя десятки сущностей, это быстро надоедает. Плюс, поддерживает связи между сущностями.
Ну и в сущностях не обязательно делать геттеры/сеттеры для всех полей. А смотреть по ситуации. Может, какие-то поля нельзя менять. Или можно менять, но только одновременно. И т.д.
>>283713
Ты по одному продукту делаешь вывод обо всех.
>>283708
Пока что неправильно. У тебя там получаются круглые цифры:
> 12-й месяц выплаты. Долг перед банком :-3576.4368783754.Всего выплачено:60000
А должно быть всего выплачено около 61270.
> if ($open == 0){
> $creditSumm = $creditSumm;
Это можно было не писать, эта строчка ничего не делает.
Функции лучше не выводить результат, а возвращать - тогда тот, кто вызвал, может использовать его как хочет.
Не, код довольно краток и сокращать дальше уже нечего.
Насчет форматирования - мне кажется, что тесно сгруппированные значения массивов читабельнее. В PSR-1 и 2 (рекомендации по оформлению кода) я не нашел требований к оформлению массивов.
>>283722
Она позволяет избавиться от написания рутинных запросов, что полезно. Когда у тебя десятки сущностей, это быстро надоедает. Плюс, поддерживает связи между сущностями.
Ну и в сущностях не обязательно делать геттеры/сеттеры для всех полей. А смотреть по ситуации. Может, какие-то поля нельзя менять. Или можно менять, но только одновременно. И т.д.
>>283713
Ты по одному продукту делаешь вывод обо всех.
>>283708
Пока что неправильно. У тебя там получаются круглые цифры:
> 12-й месяц выплаты. Долг перед банком :-3576.4368783754.Всего выплачено:60000
А должно быть всего выплачено около 61270.
> if ($open == 0){
> $creditSumm = $creditSumm;
Это можно было не писать, эта строчка ничего не делает.
Функции лучше не выводить результат, а возвращать - тогда тот, кто вызвал, может использовать его как хочет.
Ты что-то путаешь. Нейимспейсы и автозагрузка независимы друг от друга и не заменяют друг друга. Почитай урок https://github.com/codedokode/pasta/blob/master/php/autoload.md
>>283382
Ты сначала определяешь функцию, а затем вызываешь:
function something($x, $y) {
...
}
$z = something(100, 500);
echo $z;
На ideone или где-то еще - не важно.
>>283040
Не могу, там куча вариантов. Ищи на гитхабе по словам student list, и выбери то, что выглядит поприличнее.
>Ты по одному продукту делаешь вывод обо всех.
Они все дерьмовые. CMS - это неюзабельная параша.
https://github.com/Awesome-Kirill/fukingStudent/blob/master/composer.json#L2
Название проекта можно убрать или вписать правильное, это поле обязательно только для библиотек.
Ты используешь https://github.com/Awesome-Kirill/autowiringDI , но в нем нет даже общего описания. Я первый раз эту библиотеку вижу. То есть человек, получается, должен читать код, чтобы понять, что это такое и как работает. Думаю, тут нужно дополнить ридми, кратко описав, что это, зачем, как работает с примером кода, что может и что не может. Кратко.
> Created by PhpStorm.
Советую отключить этот бессмысленный комментарий в настройках IDE.
> $this->container["{$id}"];
Красивее сделать явное преобразование к строке, как мне кажется, через strval().
> https://github.com/Awesome-Kirill/autowiringDI/blob/master/src/AutowiringDI.php#L66
> public function make(string $cls){
Нужен комментарий. Название ничего не говорит.
Тут выравнивание кривое из-за смеси табов и пробелов: https://github.com/Awesome-Kirill/autowiringDI/blob/master/src/AutowiringDI.php - надо исправить. Тяжело читать.
https://github.com/Awesome-Kirill/fukingStudent/blob/master/student.sql#L40
> `ege` int(11) NOT NULL,
Нужно добавить UNSIGNED
https://github.com/Awesome-Kirill/fukingStudent/blob/master/src/mylog.log
Это надо добавить в gitignore, и логи лучше вынести в отдельную папку.
Твой роутер правильнее назвать Front Controller.
https://github.com/Awesome-Kirill/fukingStudent/blob/master/src/tmp/404.html#L18
надо экранировать вывод, почитай мою пасту про XSS
https://github.com/Awesome-Kirill/fukingStudent/tree/master/src/tmp
Папке надо дать название получше
https://github.com/Awesome-Kirill/fukingStudent/blob/master/src/View.php
надо убрать лишние пустые строки в коде
> https://github.com/Awesome-Kirill/fukingStudent/blob/master/src/Controller/FormController.php#L36
> $postRequest = $postRequest + ['pass' => hash('sha256', random_int(0, 1200))];
Ох ты наивняша. У тебя ведь, получается, тут всего 1200 вариантов пароля. Хеш может выглядеть внушительно, но в его основе лежит одно из всего лишь 1200 чисел. И подобрать такой пароль элементарно.
Хеш лишь позволяет получить короткий отпечаток для большого объема входных данных. Он не генерирует пароли. Чтобы сгенерировать пароль, надо каждый символ в нем сгенерировать случайно.
Ты, возможно, где-то слышал, что надо хешировать пароли. Это немного не то, что ты сделал, у меня есть урок: https://github.com/codedokode/pasta/blob/master/security/password-hashing.md
Пароли хешируют и солят, чтобы персонал не мог их подглядеть, а также, чтобы при краже БД нельзя было взять эти пароли и попробовать их ввести на том же самом или других сайтах - вдруг пользователь использует тот же пароль. Тут нужен не пароль (который вводит пользователь), а случайный токен, который сохраняется в куки. Хешировать его не требуется (но можно при желании), так как он не подойдет ни к какому другому сайту.
https://github.com/Awesome-Kirill/fukingStudent/blob/master/src/Model/DataBase.php#L23
> } catch (\PDOException $e) {
> echo $e->getMessage();
Непраивльно. Ты выводишь ошибку пользователю (который ничего в ней не поймет), а в лог не пишешь (и разработчик о ней не узнает).
> https://github.com/Awesome-Kirill/fukingStudent/blob/master/src/Model/DataBase.php#L123
> $config = parse_ini_file('./src/config.ini');
Почему у тебя класс базы данных занимается парсингом конфигов? Ты нарушил принцип разделения ответственности, когда каждый класс занимается своим делом. Ну и представь, если тебе захочется, например, усложнить код чтения конфига. Тебе придется копировать это в несколько мест. Неудобно.
https://github.com/Awesome-Kirill/fukingStudent/blob/master/src/Model/InitPDO.php
Непонятно назначение этого класса. Что мешает вместо него создавать PDO напрямую?
Также, ты там сделал логгирование. Ты для каждого catch в коде планируешь копировать код логгирования?
Еще, ты для модели студента используешь массив вместо объекта. Можешь назвать плюсы и минусы представления студента в виде массива или объекта? Почему ты так решил сделать?
Класс валидации сделан не очень удачно - надо вызвать один метод для проверки, потом другой для получения результата. При этом ошибки накапливаются, если например, вызвать метод проверки второй раз, то старые ошибки не очищаются. Вопрос, почему нельзя вернуть результат проверки сразу? Зачем так сделано?
По тестам: не стоит делать проверку кучи условий в одном тесте. Лучше на каждое условие сделать свой тест:
- проверка, что корректное заполнение формы регистрации работает
- проверка, что пробелы в форме обрезаются
- проверка, что при неправильном заполнении выдается ошибка
ит.д. То есть лучше, когда тесты простые и тестируют ровно одно требование. Имя теста должно отражать это требование.
> $I->see('Этот email уже использован');
Это делает тест хрупким. Достаточно чуть поменять формулировку и все, тест провален. Лучше бы тестировать по более надежному признаку, может там есть какой-то класс или атрибут, который менее склонен к изменению.
https://github.com/Awesome-Kirill/fukingStudent/blob/master/tests/acceptance/FirstCest.php#L27
> $I->see('Logout');
Это тоже не очень надежно, вдруг это слово где-то есть в фразе на странице (you can logout later). Стоит хотя бы проверить до теста, что такого слова нет - тогда мы защитимся от этой ошибки.
> $I->amOnPage('/add/');
> $I->dontSeeCookie('isLogin');
Это мне не очень нравится, так как пользователь таких вещей не видит, а мы ведь имитируем его поведение. Также, ты привязываешься к подробностям реализации. То есть ты не проверяешь, что пользователь разлогинен, а проверяешь, что нет куки с определенным именем. И если ее имя поменяется, твой тест станет ошибаться.
Проверять залогиненность логично либо специальным вспомогательным тестовым методом, либо проверкой, что мы не можем зайти на какую-то страницу.
https://github.com/Awesome-Kirill/fukingStudent/blob/master/tests/acceptance.suite.yml
Надо написать в ридми про этот файл, что в нем надо задать параметры соединения. И вообще про тесты, как их запустить.
Это не полный список замечаний, это только что я с первого взгляда увидел. Задавай вопросы, если что
-то непонятно.
https://github.com/Awesome-Kirill/fukingStudent/blob/master/composer.json#L2
Название проекта можно убрать или вписать правильное, это поле обязательно только для библиотек.
Ты используешь https://github.com/Awesome-Kirill/autowiringDI , но в нем нет даже общего описания. Я первый раз эту библиотеку вижу. То есть человек, получается, должен читать код, чтобы понять, что это такое и как работает. Думаю, тут нужно дополнить ридми, кратко описав, что это, зачем, как работает с примером кода, что может и что не может. Кратко.
> Created by PhpStorm.
Советую отключить этот бессмысленный комментарий в настройках IDE.
> $this->container["{$id}"];
Красивее сделать явное преобразование к строке, как мне кажется, через strval().
> https://github.com/Awesome-Kirill/autowiringDI/blob/master/src/AutowiringDI.php#L66
> public function make(string $cls){
Нужен комментарий. Название ничего не говорит.
Тут выравнивание кривое из-за смеси табов и пробелов: https://github.com/Awesome-Kirill/autowiringDI/blob/master/src/AutowiringDI.php - надо исправить. Тяжело читать.
https://github.com/Awesome-Kirill/fukingStudent/blob/master/student.sql#L40
> `ege` int(11) NOT NULL,
Нужно добавить UNSIGNED
https://github.com/Awesome-Kirill/fukingStudent/blob/master/src/mylog.log
Это надо добавить в gitignore, и логи лучше вынести в отдельную папку.
Твой роутер правильнее назвать Front Controller.
https://github.com/Awesome-Kirill/fukingStudent/blob/master/src/tmp/404.html#L18
надо экранировать вывод, почитай мою пасту про XSS
https://github.com/Awesome-Kirill/fukingStudent/tree/master/src/tmp
Папке надо дать название получше
https://github.com/Awesome-Kirill/fukingStudent/blob/master/src/View.php
надо убрать лишние пустые строки в коде
> https://github.com/Awesome-Kirill/fukingStudent/blob/master/src/Controller/FormController.php#L36
> $postRequest = $postRequest + ['pass' => hash('sha256', random_int(0, 1200))];
Ох ты наивняша. У тебя ведь, получается, тут всего 1200 вариантов пароля. Хеш может выглядеть внушительно, но в его основе лежит одно из всего лишь 1200 чисел. И подобрать такой пароль элементарно.
Хеш лишь позволяет получить короткий отпечаток для большого объема входных данных. Он не генерирует пароли. Чтобы сгенерировать пароль, надо каждый символ в нем сгенерировать случайно.
Ты, возможно, где-то слышал, что надо хешировать пароли. Это немного не то, что ты сделал, у меня есть урок: https://github.com/codedokode/pasta/blob/master/security/password-hashing.md
Пароли хешируют и солят, чтобы персонал не мог их подглядеть, а также, чтобы при краже БД нельзя было взять эти пароли и попробовать их ввести на том же самом или других сайтах - вдруг пользователь использует тот же пароль. Тут нужен не пароль (который вводит пользователь), а случайный токен, который сохраняется в куки. Хешировать его не требуется (но можно при желании), так как он не подойдет ни к какому другому сайту.
https://github.com/Awesome-Kirill/fukingStudent/blob/master/src/Model/DataBase.php#L23
> } catch (\PDOException $e) {
> echo $e->getMessage();
Непраивльно. Ты выводишь ошибку пользователю (который ничего в ней не поймет), а в лог не пишешь (и разработчик о ней не узнает).
> https://github.com/Awesome-Kirill/fukingStudent/blob/master/src/Model/DataBase.php#L123
> $config = parse_ini_file('./src/config.ini');
Почему у тебя класс базы данных занимается парсингом конфигов? Ты нарушил принцип разделения ответственности, когда каждый класс занимается своим делом. Ну и представь, если тебе захочется, например, усложнить код чтения конфига. Тебе придется копировать это в несколько мест. Неудобно.
https://github.com/Awesome-Kirill/fukingStudent/blob/master/src/Model/InitPDO.php
Непонятно назначение этого класса. Что мешает вместо него создавать PDO напрямую?
Также, ты там сделал логгирование. Ты для каждого catch в коде планируешь копировать код логгирования?
Еще, ты для модели студента используешь массив вместо объекта. Можешь назвать плюсы и минусы представления студента в виде массива или объекта? Почему ты так решил сделать?
Класс валидации сделан не очень удачно - надо вызвать один метод для проверки, потом другой для получения результата. При этом ошибки накапливаются, если например, вызвать метод проверки второй раз, то старые ошибки не очищаются. Вопрос, почему нельзя вернуть результат проверки сразу? Зачем так сделано?
По тестам: не стоит делать проверку кучи условий в одном тесте. Лучше на каждое условие сделать свой тест:
- проверка, что корректное заполнение формы регистрации работает
- проверка, что пробелы в форме обрезаются
- проверка, что при неправильном заполнении выдается ошибка
ит.д. То есть лучше, когда тесты простые и тестируют ровно одно требование. Имя теста должно отражать это требование.
> $I->see('Этот email уже использован');
Это делает тест хрупким. Достаточно чуть поменять формулировку и все, тест провален. Лучше бы тестировать по более надежному признаку, может там есть какой-то класс или атрибут, который менее склонен к изменению.
https://github.com/Awesome-Kirill/fukingStudent/blob/master/tests/acceptance/FirstCest.php#L27
> $I->see('Logout');
Это тоже не очень надежно, вдруг это слово где-то есть в фразе на странице (you can logout later). Стоит хотя бы проверить до теста, что такого слова нет - тогда мы защитимся от этой ошибки.
> $I->amOnPage('/add/');
> $I->dontSeeCookie('isLogin');
Это мне не очень нравится, так как пользователь таких вещей не видит, а мы ведь имитируем его поведение. Также, ты привязываешься к подробностям реализации. То есть ты не проверяешь, что пользователь разлогинен, а проверяешь, что нет куки с определенным именем. И если ее имя поменяется, твой тест станет ошибаться.
Проверять залогиненность логично либо специальным вспомогательным тестовым методом, либо проверкой, что мы не можем зайти на какую-то страницу.
https://github.com/Awesome-Kirill/fukingStudent/blob/master/tests/acceptance.suite.yml
Надо написать в ридми про этот файл, что в нем надо задать параметры соединения. И вообще про тесты, как их запустить.
Это не полный список замечаний, это только что я с первого взгляда увидел. Задавай вопросы, если что
-то непонятно.
echo join(" ", array_map(function($val){
return $val[array_rand[$val]]
},$poema);
на строку короче
А, и еще момент. Скажите, пожалуйста, где лучше выкладывать код, чтобы не мучаться со скринами? Не могу в гитхаб, не понимаю
начни с того что str_replace принимает массив первым аргументом ( типичная ошибка нуба )
str_replace(["-","(",")"," "],"",$number);
во вторых, синтаксис "{$base}" - пиздец сам по себе.
зы. парсер номерв, это такая уникальная задача.... поищи готовый, уже есть 100500 вариантов
>начни с того что str_replace принимает массив первым аргументом ( типичная ошибка нуба )
О, спасибо. Я до этого сам не додумался, не знал что так можно.
Еще, как я заметил, не обязательно вводить переменную или создавать пустой массив перед использованием.
>во вторых, синтаксис "{$base}" - пиздец сам по себе.
Почему? В каком плане?
>зы. парсер номерв, это такая уникальная задача.... поищи готовый, уже есть 100500 вариантов
Погуглю, спасибо. Мне просто интересно, возможно ли это было сделать без использования str_replace(), а только используя регулярные выражения.
пустая переменная - твой слчай, если ты будешь делать продакшен то у тебя будет вариант с str_replace($this->replace_array,"",$str)
т.е. ты даешь себе же возможность расширить массив заменяемых зняений
"{$base}" = $base вообще следует избегать двойных строк, для них существует отдельная обработка и лучше делать "".$base."" пока не понимаешь как оно работает
нубы которые делают как ты жарятся в отдельном котле
На ideone можно выкладывать. Там заодно и результат выполнения виден. Правда, там не работают mb-функции.
Есть и другие сайты: http://codepad.org/
https://repl.it/languages/php
pastebin
Также, если ты зарегистрирован на гитхабе (бесплатно, без СМС), то там есть отличный удобный сервис для выкладывания кода - gist.github.com. Чтобы им пользоваться, не надо знать git, просто копируешь код и сохраняешь. Попробуй.
Вместо кучи str_replace лучше использовать один strtr() с массивом замен, либо один preg_replace().
Убирать foreach не требуется. Хотя можно 2 foreach объединить в один.
Вместо "{$number}" надо писать просто $number.
>>285675
Тут стоит задача сделать самостоятельно, а не скопировать.
>>285708
> Еще, как я заметил, не обязательно вводить переменную или создавать пустой массив перед использованием.
Обязательно. Если ты сделаешь
echo $a;
то это выдаст warning.
> Мне просто интересно, возможно ли это было сделать без использования str_replace(), а только используя регулярные выражения.
Возможно. Надо просто в регулярку добавить возможность наличия скобок, минусов и пробелов между цифрами.
В дополнение к замечаниям тут: >>285501
В шаблонах надо убрать копипасту. Ты скопировал шапку и подвал в каждый шаблон, этого не должно быть.
Имена шаблонов лучше сделать соответствующими именам контроллеров и экшенов, а не случайными.
https://github.com/Awesome-Kirill/fukingStudent/blob/master/src/Controller/ListController.php#L36
> if (isset($_COOKIE['isLogin']) and $this->authentication->isValidCookie($this->model, $_COOKIE['isLogin'])) {
Это нарушение инкапсуляции. По идее, знать, как называется кука, должен только класс авторизации. Ты же вместо этого копипастишь название куки по всему коду.
Ты используешь let, это отекает большое число старых браузеров. Не очень понятно, в чем выгода. Ты знаешь, какие есть стандарты JS, в чем их различия и осознанно сделал выбор или же не думая скопипастил из какой-то статьи?
https://github.com/Awesome-Kirill/fukingStudent/blob/master/src/tmp/allVue.html#L6
> <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
Зачем ты запрещаешь масштабировать страницу? Этот код придумали люди, которым лень было делать нормальную верстку и проще показалось запретить масштабирование. Я негативно отношусь к таким людям.
> <hr class="container-fluid">
Что за ерунда? Почему hr?
https://github.com/Awesome-Kirill/fukingStudent/blob/master/src/tmp/vue-bootstrap-table.js
12 000 строк - не многовато ли для отображения простой таблицы?
Фреймворки вроде bootstrap лучше класть в отдельную папку, а не сваливать все в кучу. Сторонний код желательно явно отделять от своего.
Весь бутстрап тебе вряд ли нужен. Можно было сделать сборку только из нужных модулей.
При ошибке надо показывать форму с заполненными полями, а не редиректить.
В дополнение к замечаниям тут: >>285501
В шаблонах надо убрать копипасту. Ты скопировал шапку и подвал в каждый шаблон, этого не должно быть.
Имена шаблонов лучше сделать соответствующими именам контроллеров и экшенов, а не случайными.
https://github.com/Awesome-Kirill/fukingStudent/blob/master/src/Controller/ListController.php#L36
> if (isset($_COOKIE['isLogin']) and $this->authentication->isValidCookie($this->model, $_COOKIE['isLogin'])) {
Это нарушение инкапсуляции. По идее, знать, как называется кука, должен только класс авторизации. Ты же вместо этого копипастишь название куки по всему коду.
Ты используешь let, это отекает большое число старых браузеров. Не очень понятно, в чем выгода. Ты знаешь, какие есть стандарты JS, в чем их различия и осознанно сделал выбор или же не думая скопипастил из какой-то статьи?
https://github.com/Awesome-Kirill/fukingStudent/blob/master/src/tmp/allVue.html#L6
> <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
Зачем ты запрещаешь масштабировать страницу? Этот код придумали люди, которым лень было делать нормальную верстку и проще показалось запретить масштабирование. Я негативно отношусь к таким людям.
> <hr class="container-fluid">
Что за ерунда? Почему hr?
https://github.com/Awesome-Kirill/fukingStudent/blob/master/src/tmp/vue-bootstrap-table.js
12 000 строк - не многовато ли для отображения простой таблицы?
Фреймворки вроде bootstrap лучше класть в отдельную папку, а не сваливать все в кучу. Сторонний код желательно явно отделять от своего.
Весь бутстрап тебе вряд ли нужен. Можно было сделать сборку только из нужных модулей.
При ошибке надо показывать форму с заполненными полями, а не редиректить.
> Тогда возникает ряд проблем связанных с передачей ключей между приложениями, т.е. пользователь может использовать браузерную/десктопную/мобильное приложения и все они как-то должны обмениваться своими приватными ключами.
Да. Получается, есть такие решения:
- хранить на сервере ключ, возможно, защищенный паролем. Плохо, так как пароль может быть не очень сильный и атакующий его подберет. Не очень надежно.
- хранить на каждом клиенте свой приватный ключ (возможно, защищенный паролем - в этом случае надо продумать механизм смены пароля). Соответственно, при добавлении нового устройства оно должно как-то (через сервер?) зарегистрироваться и отправить на сервер свой публичный ключ. Сервер передает этот ключ другим устройствам, и они при отправке делают для каждого устройства свою зашифрованную копию сообщения. Это значит, что новое устройство не будет видеть сообщения, отправленные до его регистрации.
Второй вариант мне кажется адекватным. Он же используется в эппловском iMessage.
Желательно показывать список устройств, чтобы пользователь мог его проверить.
Заметь, что отправка сообщения на несколько устройств похожа на отправку сообщения в чат с несколькими пользователями.
Кстати, есть такая интересная штука, как 2FA. Это второй фактор для защиты от случая, когда у пользователя украли пароль. Есть такие протоколы TOTP и HOTP: https://ru.wikipedia.org/wiki/Google_Authenticator . Вместо программы от Гугла можно использовать свободную программу из F-Droid, не требующую доступа в интернет.
Выглядит это так:
Включение аутентификации: пользователь видит на сайте QR-код, сканирует его, приложение выдает цифровой код, пользователь его вводит для подтверждения, и происходит привязка.
Проверка: при логине пользователь запускает приложение на смартфоне и вводит показанный им цифровой код в дополнение к паролю.
Из минусов: технология чувствительна ко времени, если на сервере или смартфоне оно сбито, коды будут не работать.
Из плюсов: приложению не нужен интернет, в отличие от СМС коды не может перехватить сотовый оператор.
> Только у такого метода есть недостаток: может накопиться слишком большое количество таких ключей, и нет возможности проверить пользуется ли ими ещё пользователь.
Можно удалять по истечении периода неактивности. Если с устройства не заходили несколько месяцев, незачем на него слать сообщения.
> Но мне такая идея просто не нравится, хоть у меня и нету весомых причин для этого, кроме той, что если пароль от приватного ключа слишком простой, то его можно просто брутфорснуть (но это вина пользователя что он имеет слабый пароль).
Ключ сам по себе большой, его замучаешься подбирать. А пароль - он намного короче и мы, получается, снижаем степень защиты.
Вообще, конечно, правильнее могло бы быть не изобретать свои протоколы, а взять какой-то сушществующий, благо их много: https://en.wikipedia.org/wiki/Comparison_of_instant_messaging_protocols (да, немного поздно об этом думать).
> Тогда возникает ряд проблем связанных с передачей ключей между приложениями, т.е. пользователь может использовать браузерную/десктопную/мобильное приложения и все они как-то должны обмениваться своими приватными ключами.
Да. Получается, есть такие решения:
- хранить на сервере ключ, возможно, защищенный паролем. Плохо, так как пароль может быть не очень сильный и атакующий его подберет. Не очень надежно.
- хранить на каждом клиенте свой приватный ключ (возможно, защищенный паролем - в этом случае надо продумать механизм смены пароля). Соответственно, при добавлении нового устройства оно должно как-то (через сервер?) зарегистрироваться и отправить на сервер свой публичный ключ. Сервер передает этот ключ другим устройствам, и они при отправке делают для каждого устройства свою зашифрованную копию сообщения. Это значит, что новое устройство не будет видеть сообщения, отправленные до его регистрации.
Второй вариант мне кажется адекватным. Он же используется в эппловском iMessage.
Желательно показывать список устройств, чтобы пользователь мог его проверить.
Заметь, что отправка сообщения на несколько устройств похожа на отправку сообщения в чат с несколькими пользователями.
Кстати, есть такая интересная штука, как 2FA. Это второй фактор для защиты от случая, когда у пользователя украли пароль. Есть такие протоколы TOTP и HOTP: https://ru.wikipedia.org/wiki/Google_Authenticator . Вместо программы от Гугла можно использовать свободную программу из F-Droid, не требующую доступа в интернет.
Выглядит это так:
Включение аутентификации: пользователь видит на сайте QR-код, сканирует его, приложение выдает цифровой код, пользователь его вводит для подтверждения, и происходит привязка.
Проверка: при логине пользователь запускает приложение на смартфоне и вводит показанный им цифровой код в дополнение к паролю.
Из минусов: технология чувствительна ко времени, если на сервере или смартфоне оно сбито, коды будут не работать.
Из плюсов: приложению не нужен интернет, в отличие от СМС коды не может перехватить сотовый оператор.
> Только у такого метода есть недостаток: может накопиться слишком большое количество таких ключей, и нет возможности проверить пользуется ли ими ещё пользователь.
Можно удалять по истечении периода неактивности. Если с устройства не заходили несколько месяцев, незачем на него слать сообщения.
> Но мне такая идея просто не нравится, хоть у меня и нету весомых причин для этого, кроме той, что если пароль от приватного ключа слишком простой, то его можно просто брутфорснуть (но это вина пользователя что он имеет слабый пароль).
Ключ сам по себе большой, его замучаешься подбирать. А пароль - он намного короче и мы, получается, снижаем степень защиты.
Вообще, конечно, правильнее могло бы быть не изобретать свои протоколы, а взять какой-то сушществующий, благо их много: https://en.wikipedia.org/wiki/Comparison_of_instant_messaging_protocols (да, немного поздно об этом думать).
Первое, что мне бросилось в глаза - надпись digital & branding выглядит как-то странно и топорно. Не может хороший шрифт так плохо выглядеть. Ты, кстати, как верстальщик, тоже должен учиться замечать такие вещи.
Для проверки я открыл Developer Tools. В фаерфоксе - есть вкладочка "Шрифты", где написано, какой именно шрифт использован. В хромиуме эту информацию можно поискать на вкладке Computed.
Там видно, что использован шрифт Lato с начертанием normal. А так как у нас элемент em, то браузер сам синтезировал из нормального шрифта косой, механически наклонив буквы. Загадка разгадана.
Для подтверждения я открыл https://fonts.googleapis.com/css?family=Lato:300,400,900 - там нету курсива (кстати, изучи этот файл, там интересная оптимизация сделана).
Тебе надо подключить определения font-face еще для курсивных начертаний Lato.
Далее, почисти кеш (или поставь галочку в devtools) открой вкладку Network и перезагрузи страницу. У тебя там гигантские PNG-картинки с работами, весом под мегабайт в сумме. PNG дает хорошее качество, но совершенно неразумный вес. Попробуй их пережать в JPG, желательно без визуальной потери качества, и посмотреть, будет ли вес меньше. Не советую пользоваться автоматическими конверторами без выбора степени сжатия - они могут слишком сильно сжимать - ее лучше выбрать вручную.
Из бесплатных инструментов ты можешь использовать: imagemagick в командной строке, или Gimp. В последнем есть предпросмотр картинки в выбранном качестве, хотя сделан он немного коряво.
После сжатия ты можешь, если хочешь, использовать дополнительные утилиты для дополнительного уплотнения файла: jpegtran, jpegoptim, mozjpeg.
Из минусов JPEG: в нем нельзя сохранять мелкий текст - он коверкается. Я когда-то для оптимизации даже разделял картинку на JPEG-фон и PNG-текст.
Верстальщик должен разбираться в оптимизации картинок. Потому, советую почитать https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/automating-image-optimization/
Также, есть набор старых, но очень интересных статей по оптимизации картинок: http://chikuyonok.ru/tag/оптимизация/
Я также советую изучить теги picture и img srcset. Они позволяют указать несколько вариантов картинок, которые могут выбираться в зависимости от размера экрана, плотности пикселей, поддержки браузером формата картинки: https://developer.mozilla.org/ru/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images
> <div class="serveicesBlock">
> <div class="img"></div>
Тег .img разве нельзя убрать и заменить на псевдоэлемент :before? Попробуй сделать, или там какая-то проблема? Этот тег смотрится лишним в разметке.
В картинках - плохо, что картинки дублируются. Этот как минимум может вызвать повторную отправку запросов для них. Браузер всегда загружает картинки, указанные в атрибуте img[src], даже если они скрыты и невидимы. Тут лучше бы убрать дублирование, или что-то мешает так сделать?
Далее, надо проверить адекватность стилей по умолчанию. Представь, что к этому сайту решили добавить текстовую страницу, например, "О нас" (или даже подключить CMS и дать возможность менеджерам добавлять страницы самим). Как она будет выглядеть?
Для проверки я взял простой сайт https://motherfuckingwebsite.com/ и через devtools подключил твой CSS. Результат - не впечатляет: текст отцентрирован и плохо читабелен, списки выглядят ужасно. Нужно переделать CSS так, чтобы страница с простыми HTML тегами в нем выглядела нормально и в стиле сайта. То есть чтобы при добавлении новой страницы надо было сделать минимум работы и не надо было искать, как отключить центрирование.
> box-sizing: border-box;
Если добавить префиксы вроде -moz-box-sizing и -webkit-box-sizing, то поддерживаемых браузеров будет чуть больше: https://caniuse.com/#search=box-sizing (тебя наверно путают номера версий, не смотри на них, смотри на год выпуска браузера).
Если ты знаком с Node.JS, то можешь установить autoprefixer для автоматизации процесса.
> .serveicesBlock:nth-child(3) > .img {
Это не очень удачная идея. Если добавить, убрать или переставить блоки, то все картинки перепутаются. Лучше поставить уникальный класс на каждый блок. Не надо так делать, что при правке кода в одном месте ломается что-то в другом.
То же касается портфолио. Если возможно, я советую привязать картинки к кнопкам с помощью CSS классов или data-атрибутов. Так проще все это поддерживать.
CSS код организован так, что адаптивную версию поддерживать не очень удобно: стили для одного элемента при разных размерах окна раскиданы по разным местам кода. Это не требуется исправлять, но когда ты будешь делать сайт большего объема, это будет неудобно. Лучше их либо ставить рядом, либо использовать препроцессоры, где эта проблема решена.
Еще меня беспокоит, что при определенной ширине экрана блоки Consectetur, Tristiquet выстраиваются 3 в один ряд, и один снизу. Было бы красивее по 2 в ряд.
Также, я потестировал сайт в browsershots (а ты потестировал?) и в некоторых браузерах кнопки типов работ (illustration/motion) склеиваются друг с другом, а в некоторых, наоборот, далеко, там всюду разное расстояние. Это плохо:
- http://api.browsershots.org/png/original/a1/a1f0cd30d038c27fa04739dbb02a396e.png
- http://api.browsershots.org/png/original/86/8693a113b4c0c01939393f1d2143e9b5.png
- http://api.browsershots.org/png/original/0c/0c373ab1a4baaeab83f7b28ff643c6ac.png
Также видел склеенные кнопки в одном из IE:
- IE10: https://www.browserstack.com/screenshots/b35082fa437b517d40ea30383c037102943de97e/win7_ie_10.0.jpg
IE10 не такой старый, у тебя явно что-то с версткой. Надо сделать расстояние как на макете. Опять же, ты, как верстальщик, должен обращать внимание на отступы, поля, выравнивание, сетку итд.
Но в общем молодец, у тебя неплохо получается. Советую исправить замечания, почитать теорию по ссылкам, которые я дал, может еще почитать про новшества CSS3 (flexbox, grid итд) и начинающий верстальщик из тебя вполне готов.
Первое, что мне бросилось в глаза - надпись digital & branding выглядит как-то странно и топорно. Не может хороший шрифт так плохо выглядеть. Ты, кстати, как верстальщик, тоже должен учиться замечать такие вещи.
Для проверки я открыл Developer Tools. В фаерфоксе - есть вкладочка "Шрифты", где написано, какой именно шрифт использован. В хромиуме эту информацию можно поискать на вкладке Computed.
Там видно, что использован шрифт Lato с начертанием normal. А так как у нас элемент em, то браузер сам синтезировал из нормального шрифта косой, механически наклонив буквы. Загадка разгадана.
Для подтверждения я открыл https://fonts.googleapis.com/css?family=Lato:300,400,900 - там нету курсива (кстати, изучи этот файл, там интересная оптимизация сделана).
Тебе надо подключить определения font-face еще для курсивных начертаний Lato.
Далее, почисти кеш (или поставь галочку в devtools) открой вкладку Network и перезагрузи страницу. У тебя там гигантские PNG-картинки с работами, весом под мегабайт в сумме. PNG дает хорошее качество, но совершенно неразумный вес. Попробуй их пережать в JPG, желательно без визуальной потери качества, и посмотреть, будет ли вес меньше. Не советую пользоваться автоматическими конверторами без выбора степени сжатия - они могут слишком сильно сжимать - ее лучше выбрать вручную.
Из бесплатных инструментов ты можешь использовать: imagemagick в командной строке, или Gimp. В последнем есть предпросмотр картинки в выбранном качестве, хотя сделан он немного коряво.
После сжатия ты можешь, если хочешь, использовать дополнительные утилиты для дополнительного уплотнения файла: jpegtran, jpegoptim, mozjpeg.
Из минусов JPEG: в нем нельзя сохранять мелкий текст - он коверкается. Я когда-то для оптимизации даже разделял картинку на JPEG-фон и PNG-текст.
Верстальщик должен разбираться в оптимизации картинок. Потому, советую почитать https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/automating-image-optimization/
Также, есть набор старых, но очень интересных статей по оптимизации картинок: http://chikuyonok.ru/tag/оптимизация/
Я также советую изучить теги picture и img srcset. Они позволяют указать несколько вариантов картинок, которые могут выбираться в зависимости от размера экрана, плотности пикселей, поддержки браузером формата картинки: https://developer.mozilla.org/ru/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images
> <div class="serveicesBlock">
> <div class="img"></div>
Тег .img разве нельзя убрать и заменить на псевдоэлемент :before? Попробуй сделать, или там какая-то проблема? Этот тег смотрится лишним в разметке.
В картинках - плохо, что картинки дублируются. Этот как минимум может вызвать повторную отправку запросов для них. Браузер всегда загружает картинки, указанные в атрибуте img[src], даже если они скрыты и невидимы. Тут лучше бы убрать дублирование, или что-то мешает так сделать?
Далее, надо проверить адекватность стилей по умолчанию. Представь, что к этому сайту решили добавить текстовую страницу, например, "О нас" (или даже подключить CMS и дать возможность менеджерам добавлять страницы самим). Как она будет выглядеть?
Для проверки я взял простой сайт https://motherfuckingwebsite.com/ и через devtools подключил твой CSS. Результат - не впечатляет: текст отцентрирован и плохо читабелен, списки выглядят ужасно. Нужно переделать CSS так, чтобы страница с простыми HTML тегами в нем выглядела нормально и в стиле сайта. То есть чтобы при добавлении новой страницы надо было сделать минимум работы и не надо было искать, как отключить центрирование.
> box-sizing: border-box;
Если добавить префиксы вроде -moz-box-sizing и -webkit-box-sizing, то поддерживаемых браузеров будет чуть больше: https://caniuse.com/#search=box-sizing (тебя наверно путают номера версий, не смотри на них, смотри на год выпуска браузера).
Если ты знаком с Node.JS, то можешь установить autoprefixer для автоматизации процесса.
> .serveicesBlock:nth-child(3) > .img {
Это не очень удачная идея. Если добавить, убрать или переставить блоки, то все картинки перепутаются. Лучше поставить уникальный класс на каждый блок. Не надо так делать, что при правке кода в одном месте ломается что-то в другом.
То же касается портфолио. Если возможно, я советую привязать картинки к кнопкам с помощью CSS классов или data-атрибутов. Так проще все это поддерживать.
CSS код организован так, что адаптивную версию поддерживать не очень удобно: стили для одного элемента при разных размерах окна раскиданы по разным местам кода. Это не требуется исправлять, но когда ты будешь делать сайт большего объема, это будет неудобно. Лучше их либо ставить рядом, либо использовать препроцессоры, где эта проблема решена.
Еще меня беспокоит, что при определенной ширине экрана блоки Consectetur, Tristiquet выстраиваются 3 в один ряд, и один снизу. Было бы красивее по 2 в ряд.
Также, я потестировал сайт в browsershots (а ты потестировал?) и в некоторых браузерах кнопки типов работ (illustration/motion) склеиваются друг с другом, а в некоторых, наоборот, далеко, там всюду разное расстояние. Это плохо:
- http://api.browsershots.org/png/original/a1/a1f0cd30d038c27fa04739dbb02a396e.png
- http://api.browsershots.org/png/original/86/8693a113b4c0c01939393f1d2143e9b5.png
- http://api.browsershots.org/png/original/0c/0c373ab1a4baaeab83f7b28ff643c6ac.png
Также видел склеенные кнопки в одном из IE:
- IE10: https://www.browserstack.com/screenshots/b35082fa437b517d40ea30383c037102943de97e/win7_ie_10.0.jpg
IE10 не такой старый, у тебя явно что-то с версткой. Надо сделать расстояние как на макете. Опять же, ты, как верстальщик, должен обращать внимание на отступы, поля, выравнивание, сетку итд.
Но в общем молодец, у тебя неплохо получается. Советую исправить замечания, почитать теорию по ссылкам, которые я дал, может еще почитать про новшества CSS3 (flexbox, grid итд) и начинающий верстальщик из тебя вполне готов.
Задачка на исправление ошибок в тексте и у меня встает следующий вопрос (вот код http://codepad.org/3zrTEE2d): как сделать так, чтобы местах, где требуется просто поставить пробел, код не сжирал последующую букву? Я пытался через $replacement.'$2', но он, сука, выдает мне ебаный еррор Array to string conversion, хотя я вроде не передаю ему никаких массивов, а хочу дать вторую часть кода из массива регексп. Я уже в отчаянии!
И вот еще: http://codepad.org/RWkJyh7k . Это задачка на наебалово в госзакупках. Возможно ли сделать код короче?
Извиняюсь, если сильно напрягаю анона, но просто почему-то немного трудно идут рег. выражения. Я их уже второй день штудирую, пишу-переписываю свой код. И приходится в методичку загядывать
Читал. Как-то поверхностно.
>"/([,|.|!|?|:])(\\S)/u"
Спасибо, но я так уже делал. Это только на знаки препинания. А, например, жи-ши - это уже отдельно делать, или как? Так ведь получается слишком много повторяющегося кода. Я для этого в массив все вариации запихал, чтобы просто дополнять массив новыми правилами. А то не фен-шуй
Андрей Созыкин, ютуб
\t это так табуляция отображается.
function makeThisTextBetter ($text){
$regexp = "/(\\s)([.|,|!|?|:])(\\s)/u";
$result = preg_replace ($regexp, "$2 ", $text);
return $result;
, а сделать первую букву заглавной не удается
О, спасибо большое
Таннебаума читни.
Дальше пока не пишу, потому как очень хочу спать. Однако написал я ее за пару часов. Я молодец? Просто хотелось похвалиться перед кем-то. Под задачкой написано, что она сложна для новичков, однако управился относительно быстро
Есть какие то стандарты, а то я совсем себя неуютно чувствую?
Задача список студентов из шапки. В ней есть ссылки на уроки по отдельным вещам от ОПа.
Мне надо, чтобы вышла строка МАССИВ ПУСТОЙ, КРАСАВЧИК, если в массиве нет ни одной записи.
if ((empty($array)){
echo "Массив пустой, красавчик";
}
почему то не работает. Хелп!
Не работает.
Вар дамп выдает вот это:
array(0) { }
Работает такое условие:
if ($myArray === array()){
echo "заебись";
}
В задачах ОПа максимум арифметика за 7 класс, если у тебя с этим проблеммы, то о сикп пока и думать нечего. Можешь попробовать пройти вводный курс по программированию на хекслете. https://ru.hexlet.io/courses/introduction_to_programming
Не вчитывался, но заметил, что операции остаток от деления и деления с округлением ты не используешь, инклайн ворд переделал, а можно как у ОПа сделать.
банкомат и по кругу - нет
Спасибо. Буду лучше вникать
Собственно проблема у меня скорее с самим пониманием программирования , потому что с арифметикой проблем нет. Для меня это все разновидность магии. А программисты - колдуны ирл все от незнания, да
тебя лично его возможности полностью удовлетворяют?
<?php
class Car{
public $color = "Wite";
public $speed;
public $brand;
public $fuel;
}
$car1 = new Car;
$car1->brand = "Жигули";
$car1->color;
$car1->speed = 70;
$car1->fuel= 10
$car2 = new Car;
$car2->brand = "ГАЗ";
$car2->color = "black";
$car2->speed = 100;
$car2->fuel = 15;
echo $car1->brand;
?>
Точку с запятой поставь, ковбой.
Блять, вот я валет.Нашел пропущенные точку с запятой. Сори!
А все задачи до 162-го поста в этом треде кто, по твоему, проверил? Если на твой вопрос не ответили или не проверили задачу, напомни о ней.
Да, не использовал. Мне этот способ показался проще. Пока на работе подумал ещё, что для вывода тысяч можно проверить длину массива и разбить массив на сегменты по 3 т.е. 0-2 это сотни, дальше проверочное [3] для больших значений , 4-6 сотни и т.д., это всего пару строк кода плюс массив для крупных чисел, плюс подправить баг с числами, допилить склонения и будет всё складно. Т.е. я мыслил таким образом, что в числе 987 654 321, 987 миллионов, 654 тысячи 321. И каждый "миллион/тысяча" будет ключом для второго массива больших чисел, который будет подставляться между малыми. На словах все труднее звучит, но я попробую как вернусь с работы это реализовать
А, ещё забыл один вопрос: почему у меня \n не пашет? Не переводит строку. Приходится <br> использовать
Опечаточники: https://www.ideone.com/XKbY9H
Shift: https://repl.it/repls/RequiredColorlessUnits
Yoda Speak: https://repl.it/repls/SalmonGoldenExpertise
Числа прописью: https://repl.it/repls/TrustyNegativeJavabytecode
Калькулятор: https://repl.it/repls/StingyLargeState
Задание- описать классы для прямоугольника, круга, пирамиды, описать метод для нахождения площади фигуры (не уточняется именно пирамида или все-таки треугольник, поэтому пирамида с равнобедренными треугольниками), а так же отсортировать по убыванию площади объекты и вывести на экран.
Сделал создание рандомных фигур, с рандомными параметрами, вывод нормально работает, но никак не могу сделать сортировку, вот уже несколько часов бьюсь.
Может стоит как-то по другому сделать массив с фигурами? Или просто я слепой, что не могу увидеть как сортировать
в терминале запускай
Платиновый вопрос. Когда ты запускаешь скрипт в PHP-сервере и отображаешь результат в браузере, браузер воспринимает данные как текст в формате HTML, а в HTML перевод строки равносилен пробелу.
Чтобы переносы строк нормально работали и в браузере и в ideone (и в консоли), можно использовать для этого \n, а в начале программы поставить
header("Content-Type: text/plain; charset=utf-8");
Это заставит браузер воспринимать то, что выводит твоя программа, как обычный текст, а не HTML, и уважать переносы строк в нем (так как в языке HTML перенос строки равносилен пробелу).
Иначе перенос строки будет в исходном коде страницы (его можно увидеть нажав Ctrl + U), но на самой странице его не будет.
Или даже можно без массивов, но с картой-массивом мне кажется интереснее
https://ideone.com/7Qw2os
почему в итоге прибавляет 5к, а не 1270
а, уже разобрался
Поясните, пожалуйста... Желательно ссылками и примерами, по возможности
Добро пожаловать в тематику
Думать мало, надо делать тоже, когда садишься и начинаешь конкретно кодить, то проясняются все иллюзии.
Просто пиши, что угодно, главное кодируй и решай проблемы.
Всё, с чем столкнёшься - крайне полезный опыт.
работать то оно будет но кинет нотис
ну и бтв некоторые люди оборачивают ошибки в исключения
так что всё возможно
Нет, они где-то в 7 км от них.
Ctrl+U в хроме на любом сайте и верстка твоя
Суть в том, что я уже пол года работаю на эту зп, и думаю что я могу получать намного больше т.к. даже мои входные знания были очень даже неплохие. Платить больше мне в этой компании вряд ли будут. И я думаю - стоит ли увольнятся и искать новую работу (а я постоянно вижу вакансии где платят больше), или я еще зелёный и мне стоит работать где я работаю?
Думаю спросить поднимут ли мне зп до 55к, если нет, то уволюсь. Или 40 это норм зп для веб разработчика?
Студия занимается созданиями местных сайтов.
Не могу решить что делать, помоги аннован. Просто, я скопил немного денег т.к. живу с родителями, и мог бы пол-года год еще поучиться и найти еще лучше работу, но я не уверен что смогу.
Просто мне показалось, что отвечают только на вопросы с проектами, а на задачки нет, вот я подумал что это не ОП.
Посмотри на опыт западных коллег: там сначала получают оффер, а потом с этим оффером идут к боссу, и торгуются, кто больше заплатит. Таким макаром очень быстро поднимают ЗП, и часто скачут между конторами.
Вообще там собеседования что-то типа спортивной дисциплины - на них ходят даже не ради офферов, а просто чтобы понимать, сколько ты стоишь на рынке, имеешь ли прогресс, или начал закисать и пора шевелиться.
Это у нас пиздец: поговорил с конкурентом - все, предатель, расстрел на месте.
Конечно, если не устраивает ЗП, поговори с боссом. Но такой разговор - сигнал, что ты свое выработал, и тебя пора менять на нового ньюфага, вкалывающего за дошираки. Так что не удивляйся, если через месяц на твое место найдут новенького. Поэтому сперва стоит хотя-бы подстраховаться, и найти запасной аэродром.
Да, есть и адекватные конторы, в этой сфере вообще кадровый голод, и, если босс не дурак (что в РФ редкость), и личных конфликтов нет, выгоднее тебе просто немного поднять ЗП, потому что с тебя все равно имеют намного больше.
Но тут уже опасность для тебя - можно 10 лет отработать в одной конторе, каждый год увеличивая ЗП на 5к, и к концу получая аж 90к(!), а можно за эти же 10 лет сменить несколько контор, каждый раз получая прибавку в 10-20к, и к концу иметь за уже под 200, плюс огромный опыт: сидя в одной конторе, при всем желании стать профи, сгниешь заживо, т.к. узкая специализация и однотипные задачи., уже через год поймешь, что ничего нового тебе не светит, кроме как клепать одно и то же ради денег, не прогресс, а застой, рутина.
По этим причинам в большинстве случаев такой разговор даже не начинают, а просто уходят на новое место, и всё.
Повышение ЗП для работника не выигрышная стратегия, а болото, политика удержания. Зато это выигрышная стратегия для босса - кидая время от времени мелкие подачки, он продолжает грести бабло.
Как ни странно, большинство ведется на это, и потому во многих конторах такие мелкие повышения дают сами, каждый год-полгода: программисты в экстазе, они видят рост (на самом деле его нет), думают что их ценят (ага, щазз), а работодатель вовсю поддерживает эти заблуждения. Но это настолько мягкое, теплое и уютное болото, что выбираются из него в основном по жизненным обстоятельствам.
Как бы то ни было, всегда помни, что твоя ценность, как специалиста, только растет - ты не можешь уйти на более низкую ЗП, т.к. неизбежно растешь.
Но ты можешь расти быстро, а можешь медленно.
И растешь ты только по сравнению со своей прошлой ЗП.
Исходя из всего этого выгоднее как можно чаще менять свою ЗП, чаще меняется ЗП - быстрее растешь, больше профита.
Но и голову тоже нужно включать.
Если ты понимаешь, что на деле ничего из себя не представляешь, стоит прибегнуть к концепции трамплинов: используй первую работу чтобы наработать опыт, а когда поймешь свою реальную стоимость - сможешь выйти на рынок сам, и это будет уже не попытка найти хоть какую-то работу, а выбор наиболее достойного места из нескольких предложений.
Посмотри на опыт западных коллег: там сначала получают оффер, а потом с этим оффером идут к боссу, и торгуются, кто больше заплатит. Таким макаром очень быстро поднимают ЗП, и часто скачут между конторами.
Вообще там собеседования что-то типа спортивной дисциплины - на них ходят даже не ради офферов, а просто чтобы понимать, сколько ты стоишь на рынке, имеешь ли прогресс, или начал закисать и пора шевелиться.
Это у нас пиздец: поговорил с конкурентом - все, предатель, расстрел на месте.
Конечно, если не устраивает ЗП, поговори с боссом. Но такой разговор - сигнал, что ты свое выработал, и тебя пора менять на нового ньюфага, вкалывающего за дошираки. Так что не удивляйся, если через месяц на твое место найдут новенького. Поэтому сперва стоит хотя-бы подстраховаться, и найти запасной аэродром.
Да, есть и адекватные конторы, в этой сфере вообще кадровый голод, и, если босс не дурак (что в РФ редкость), и личных конфликтов нет, выгоднее тебе просто немного поднять ЗП, потому что с тебя все равно имеют намного больше.
Но тут уже опасность для тебя - можно 10 лет отработать в одной конторе, каждый год увеличивая ЗП на 5к, и к концу получая аж 90к(!), а можно за эти же 10 лет сменить несколько контор, каждый раз получая прибавку в 10-20к, и к концу иметь за уже под 200, плюс огромный опыт: сидя в одной конторе, при всем желании стать профи, сгниешь заживо, т.к. узкая специализация и однотипные задачи., уже через год поймешь, что ничего нового тебе не светит, кроме как клепать одно и то же ради денег, не прогресс, а застой, рутина.
По этим причинам в большинстве случаев такой разговор даже не начинают, а просто уходят на новое место, и всё.
Повышение ЗП для работника не выигрышная стратегия, а болото, политика удержания. Зато это выигрышная стратегия для босса - кидая время от времени мелкие подачки, он продолжает грести бабло.
Как ни странно, большинство ведется на это, и потому во многих конторах такие мелкие повышения дают сами, каждый год-полгода: программисты в экстазе, они видят рост (на самом деле его нет), думают что их ценят (ага, щазз), а работодатель вовсю поддерживает эти заблуждения. Но это настолько мягкое, теплое и уютное болото, что выбираются из него в основном по жизненным обстоятельствам.
Как бы то ни было, всегда помни, что твоя ценность, как специалиста, только растет - ты не можешь уйти на более низкую ЗП, т.к. неизбежно растешь.
Но ты можешь расти быстро, а можешь медленно.
И растешь ты только по сравнению со своей прошлой ЗП.
Исходя из всего этого выгоднее как можно чаще менять свою ЗП, чаще меняется ЗП - быстрее растешь, больше профита.
Но и голову тоже нужно включать.
Если ты понимаешь, что на деле ничего из себя не представляешь, стоит прибегнуть к концепции трамплинов: используй первую работу чтобы наработать опыт, а когда поймешь свою реальную стоимость - сможешь выйти на рынок сам, и это будет уже не попытка найти хоть какую-то работу, а выбор наиболее достойного места из нескольких предложений.
Заблуждаешься
Да, каких-то четких рекомендаций тут нет, но в целом архитектура бекенда устоялась.
Всегда есть роутер, есть реквест, а иногда и ответ (мало где, в основном везде свои велосипеды с глюками), есть конфиг (тут пожалуй больше всего велосипедов), есть ядро, есть контроллер, есть кэш, иногда контейнер зависимостей (довольно редко на самом деле), и конечно же какой-нибудь недо-orm.
По большей части современные сайты - это фронт-контроллер, потому что везде маршрутизация и танцы с ЧПУ.
Но некоторые и тут изобретают велосипеды, подключая ядро в каждом (!), каждом, сука, файле, и это пиздец.
Обязательно юзай шаблонизаторы, и лучше twig мир еще ничего не придумал
Шаблонизаторы нужны не столько для удобного натягивания шаблонов, сколько для того, чтобы отделить мух от котлет код от верстки
Плюсы twig - посмотри как аккуратно он обрабатывает ошибки буферизации, и сравни это с битриксом, который от любого чиха путает буферы и рвет верстку нахуй
Юзай composer, собирай свой сайт из готовых кирпичиков. Тем более там есть интерфейсы без реализации - даже если не хочешь где-то юзать чужое, по крайней мере стандартные интерфейсы не дадут наворотить говнокода на ровном месте
И без ООП, конечно, никакой толковой архитектуры не выйдет, как ни крути
А с ООП забываешь про include-ад, и просто юзаешь автозагрузчики
Юзай инверсию зависимостей, и другие умные слова, иначе выходит хуета и боль
Потыкавшись с голым ООП тоже быстро дошел до всей этой шелухи - без неё у тебя будет пиздец в ядре, и код будет очень страшный и ограниченный. С ней можешь творить магию - тебе уже плевать кто как реализован, везде указываешь абстракции.
Очень быстро доходишь до простой истины: сначала описываешь общие абстракции, потом уточняешь их, накладываешь ограничения, потом реализуешь. Если делать иначе - очень быстро упрешься в ограничения, они будут просто везде, и решить их можно только костылями, что полностью уничтожает твою архитектуру: код работает хуй пойми как, и при любом изменении ждешь кучи трудноуловимых ошибок хз где, предсказать поведение кода ты уже не в силах
И конечно стоит подумать о тестах. Подумать, потому что на практике нигде не видел, чтобы их использовали. Зато почти все публичные модули идут с тестами.
Идея заманчивая, но начать её использовать не так просто - кажется, что оверхед будет слишком большой, хотя на деле оно наоборот, экономит время: на тестах ты быстро формализуешь задачу, быстро натыкаешься на баги, и быстро приводишь код в соответствие с задачей, а без тестов ты быстро нахуевертишь гору кода, быстрее тестов, но потом потратишь в десять раз больше времени, ползая по коду, в попытках отловить непонятно откуда взявшиеся странные баги, потому что магия, мать её
Заблуждаешься
Да, каких-то четких рекомендаций тут нет, но в целом архитектура бекенда устоялась.
Всегда есть роутер, есть реквест, а иногда и ответ (мало где, в основном везде свои велосипеды с глюками), есть конфиг (тут пожалуй больше всего велосипедов), есть ядро, есть контроллер, есть кэш, иногда контейнер зависимостей (довольно редко на самом деле), и конечно же какой-нибудь недо-orm.
По большей части современные сайты - это фронт-контроллер, потому что везде маршрутизация и танцы с ЧПУ.
Но некоторые и тут изобретают велосипеды, подключая ядро в каждом (!), каждом, сука, файле, и это пиздец.
Обязательно юзай шаблонизаторы, и лучше twig мир еще ничего не придумал
Шаблонизаторы нужны не столько для удобного натягивания шаблонов, сколько для того, чтобы отделить мух от котлет код от верстки
Плюсы twig - посмотри как аккуратно он обрабатывает ошибки буферизации, и сравни это с битриксом, который от любого чиха путает буферы и рвет верстку нахуй
Юзай composer, собирай свой сайт из готовых кирпичиков. Тем более там есть интерфейсы без реализации - даже если не хочешь где-то юзать чужое, по крайней мере стандартные интерфейсы не дадут наворотить говнокода на ровном месте
И без ООП, конечно, никакой толковой архитектуры не выйдет, как ни крути
А с ООП забываешь про include-ад, и просто юзаешь автозагрузчики
Юзай инверсию зависимостей, и другие умные слова, иначе выходит хуета и боль
Потыкавшись с голым ООП тоже быстро дошел до всей этой шелухи - без неё у тебя будет пиздец в ядре, и код будет очень страшный и ограниченный. С ней можешь творить магию - тебе уже плевать кто как реализован, везде указываешь абстракции.
Очень быстро доходишь до простой истины: сначала описываешь общие абстракции, потом уточняешь их, накладываешь ограничения, потом реализуешь. Если делать иначе - очень быстро упрешься в ограничения, они будут просто везде, и решить их можно только костылями, что полностью уничтожает твою архитектуру: код работает хуй пойми как, и при любом изменении ждешь кучи трудноуловимых ошибок хз где, предсказать поведение кода ты уже не в силах
И конечно стоит подумать о тестах. Подумать, потому что на практике нигде не видел, чтобы их использовали. Зато почти все публичные модули идут с тестами.
Идея заманчивая, но начать её использовать не так просто - кажется, что оверхед будет слишком большой, хотя на деле оно наоборот, экономит время: на тестах ты быстро формализуешь задачу, быстро натыкаешься на баги, и быстро приводишь код в соответствие с задачей, а без тестов ты быстро нахуевертишь гору кода, быстрее тестов, но потом потратишь в десять раз больше времени, ползая по коду, в попытках отловить непонятно откуда взявшиеся странные баги, потому что магия, мать её
Оп, посмотри, пожалуйста, цифры в слова.
>- для данного текущего времени получить ближайшую активную тревогу, которая сработает в будущем. Если таких несколько, можно вернуть любую из них. Это будет использоваться для показа времени ближайшего срабатывания будильника на экране.
>- для данного текущего времени получить активную тревогу, которая срабатывает ровно в это время. Это будет использовано для проигрыша мелодии. Например, если в списке есть тревога на 08:00 в Пн, Ср, Пт и сейчас среда 08:00, то нужно ее вернуть. Если тревог больше одной - можно вернуть любую.
>- для данного текущего времени удалить из списка все одноразовые тревоги, которые больше никогда не сработают.
Это описываются функции, которые должны присутствовать в будильнике помимо добавления, удаления, настройки и поиска ближайшего времени? Или описанное должно содержаться в алгоритме проигрывания мелодии?
Правильно ли я понял, что код проигрывания мелодии не должен иметь доступа к функциям отдельной тревоги, а работает исключительно с функциями будильника?
Заранее спасибо.
Можно сократить код мелодии подобным образом?
- Получить время ближайшей, активной тревоги
- Если дата/время тревоги совпадает с текущим - проиграть
- Удалить сработавшие одноразовые тревоги
- Перейти к началу алгоритма
https://ideone.com/DcsQxM
Открой уже учебник, не самоунижайся.
$array[$id]
Спасибо. Значит исходя из твоего ответа чистый PHP никому не нужен.
Однако мне нравится чистота без каких-либо фреймворков и сторонних библиотек.
Мне трудно представить трудно отслеживаемые баги, так как разработка кода процесс детерминированный.
ООП нужно только для энтерпрайза по моему личному опыту, поэтому предпочитаю ПОП, так как наиболее гибко.
Роутеры, контроллеры и прочее это разве не относится к MVC и MVVC, а если так, то действитетльно ли нужно это?
Алсо спасибо за мудрые рекомендации к последующему обдумыванию.
С чего это не нужен? Крупные проекты пишутся на нативном php. Любой фреймворк - это зависимость. Чем больше проект, тем больше проблем с зависимостями.
Сегодня в моде микросервисная архитектура. Использование шаблонов ООП в этой архитектуре зависит от ситуации. Последний проект, в котором я участвовал, был на микросервисах. У нас только в двух использовались шаблоны. И то, самые простые, типа фабрики.
Прошёл курс опа, знал цсс/хтмл/пхп неблохо, мог бы написать сайт, фронт, бэк, всякие парсеры етц, умею в медиа. Когда пошёл на работу в целом особо нового не узнал, только приёмы которыми пользуются на работе и с 0 почти яву подучил, но не то чтобы силён в ней.
>>287865
Спасибо что расписал, сегодня сказал что я бы хотел больше получать и был послан со словами - не нравится увольняйся. 2 месяца дорабатываю и после НГ увольняюсь.
>яву
java или javascript?
В перзвоним тредах говорят, что декабрь-январь мертвый сезон. Увольняйся сейчас или жди до февраля.
все, исправил, сори
https://github.com/sergnik1995/students-list опчик чекни, пожалуйста, моё решение задачи студентов и скажи что там пофиксить.
Тут используется роутинг на уровне веб-сервера. Если красивые URL не нужны и проект крошечный, то в принципе, почему бы и нет.
А вот "толстые" (большие) контроллеры - это нехорошо.
Ок, спасибо.
Прямо все задания опа сделал, включая тестхаб?
В пьяном угаре.
самый херовый совет который я только видел. с фтронта на бек соскакивали ?
preg_replace - принимает 2 массива, что заменять - регулярка, на что заменять - регулярка
str_replace может просто в тупую принимать 2 массива
str_replace(["a","b"],["z","x"],$str) - заменит a->z, b->x
нубы обычно не читают доку. что не показано на ютубе, того не существует
Минимальный пример кода в студию. Напиши, что он выводит, и что, по-твоему, должен вывести. Тогда я смогу глянуть и за 5-10 секунд понять, в чем дело. А по твоему описанию ничего не понять.
sleep надо убрать.
Также, зачем ты выставил ATTR_PERSISTENT? Попробуй без него. Или тебе надо именно с ним?
Также, включи выброс исключения при ошибке: http://php.net/manual/ru/pdo.setattribute.php ( PDO::ERRMODE_EXCEPTION: )
Также, включи отображение ошибок в php.ini (display_errors = 1), если оно не включено. Но не делай так на продакшене!
Я подозреваю, проблема в том, что ты почему-то не включил вывод ошибок (хотя во всех моих уроках написано, что надо его включать), происходит какая-то ошибка, но так как ты не включил их вывод, ты о ней не знаешь и придумываешь неправильные объяснения происходящему, ставишь sleep, хотя он ни на что не влияет итд.
Также, на будущее: минимальный пример лучше писать без использования класса, просто последовательность команд.
Также, вместо if ($ans == null) надо в примере писать var_dump($ans); Чтобы точно видеть, что возвращается, а не гадать.
У меня такое ощущение, что ты пропустил основы, и сразу берешься за сложные темы, в итоге путаешься. Это конечно не имеет отношения к багу, и это твое личное дело, но по моему это плохая идея, а на собеседовании это легко определить.
Твое объяснение неправильное. PDO работает синхронно, и его методы не возвращают управление, пока не получат ответ от БД или пока не будет обнаружена ошибка. Соответственно, от того, ставишь ты sleep или нет, ровным счетом ничего не зависит. Тем более, что ты его ставишь уже после выполнения взаимодействия с БД.
>ATTR_PERSISTENT
Ну мне нужно минимизировать время, а запросов к базе много. Если есть альтернативы, то я буду не против. А вообще скорее всего перепишу все на prepare, без кривого класса.
>display_errors
Вроде все включено
>PDO::ERRMODE_EXCEPTION:
Он тоже вроде включен по умолчанию, но ошибки через try catch нет
>>288824
Возвращает пустой массив, но если передвинуть на строчку вниз, то вернет все что запрашивал.
>>288822
Хотя возможно это действительно не в pdo вина. Просто это выглядело достаточно странно, когда у меня ПК был под нагрузкой, то возвращался пустой массив, а если внутри if я убирал die, то программа после выполнялась вполне нормально.
Задачка про банкомат - https://ideone.com/yC58nJ
Не могу сделать проверку на достаточное количество купюр в банкомате.
"Лиличка" - https://3v4l.org/9nNiF
Не предсталвяю, как вывести столбцы рядом друг с другом.
А если через for перебирать по каждому символу, и в строчке выводить тип $lines[0][$i]
А если через for перебирать по каждому символу, и в строчке выводить тип $lines[0][$i]
>>PDO::ERRMODE_EXCEPTION:
> Он тоже вроде включен по умолчанию, но ошибки через try catch нет
Нет, неверно. Где это написано? Я написал тебе - по умолчанию ошибки работы с базой данных никак не репортятся. Потому надо ставить эту опцию.
Прочитай внимательно мануал, что стоит по умолчанию: http://php.net/manual/ru/pdo.error-handling.php
Также, try/catch писать не надо. Почитай урок про исключения: https://github.com/codedokode/pasta/blob/master/php/exceptions.md
А жаль, бэк ведь писать интересно.
Лярваэль.
Толсто.
Все MVC фреймворки похожи как близецы
Чекните что и как и критику
Логики нет, складывается впечатление что у тебя в школе по математике были одни двойки.
Problem, Michael ? :tf:
они могут быть не против ждунов
https://www.ideone.com/vORnwM гляньте, пожалуйст. Может программирование - не мое, как у этого анона и я зря стараюсь?>>289373
Что находится в переменной $array?
еще бамп
Аноны, помогите, пожалуйста, с задачкой на навигатор! Во первых, у меня выскакивает ошибка Warning: Use of undefined constant by - assumed 'by' (this will throw an Error in a future version of PHP). Что это за предупреждение такое? Вот кусочек моей функции https://www.ideone.com/SbFo4J. У меня он ищет путь по наименьшему кол-ву прыжков, а я хочу по времени, но не могу сообразить как. Рассуждал по логике, что функция должна прыгать от одной станции к другой в поиске искомой (чего, в принципе, добился). Тип, если цель не по соседству, то запрыгнуть в любую и снова искать, там снова прыгнуть и снова искать. Но как по времени это все провернуть? Заставлять его не убивать себя после найденного маршрута, а искать всевозможные вариации и сравнивать время? Я в замешательстве. Помогите, пожалуйста. Может и правда программирование - не мое?или сначала протрезветь?
Всё работает. Ты криворукий просто.
https://ideone.com/u4b6h9
Спасибо. Вижу, что я ступил.
Вроде все сделал, программа исправно прокладывает маршруты, но есть одно но: почему если я ставлю return вместо exit() скрипт сходит с ума, зацикливается и начинает искать вообще всевозможные пути до искомой точки? Разве return не останавливает выполнение функции и возвращает значение? Не выкладываю код т.к. по мере написания он оброс кучей мусора(я в рабочем скрипте, который написал ранее, дописывал новый код, чтобы не сломать то, что работает и проверял что изменилось), от которого я сейчас планомерно стараюсь избавиться. И мне захотелось, чтобы фукнция отдавала мне массив пройденного пути, а не прописывала путь по мере выполнения т.к. она иногда может прокладывать путь, но не писать как она это сделала.
return прерывает работу текущей функции, поднимая тебя "наверх" в стеке вызовов.
Понял, спасибо. Можешь по задачке подсказать? Я сейчас только понял, что он отображает текстом в принципе неверный маршрут, но сам каким-то образом добирается до точки верно. https://ideone.com/1U7MMZ вот моя функция. Где кусок кода взят в комментарий - это старый код, который ищет по кол-ву прыжков. Я извиняюсь, что расписано так убого, но мне правда нужна помощь.
А не пробовал выводить каждый символ каждого предложения построчно? Ну то есть "кошка любит молоко" выводилось сначала к, потом л, потом м, дальше \n и следующая буква. Лично я таким способом делал но не доделал
можно попробовать конечно, но придётся переписывать саму суть кода. Спасибо
Тольятти опять протёк?
А, понял, дико извиняюсь. Мне почему то показалась, что это стандартная функция
Какие вопросы могут задать?
Это элитный рнр-тред, катись нахуй отсюда со своим ебаным ЖС.
Анон, для начала прочти о том, как следует оформлять код. Когда смотришь на твое решение задачи, вообще отпадает желание в чем-то разбираться. Как минимум:
1. Поставь пробел между операторами (=/>/</==).
2. Поставь фигурные скобки в операторах условия (if/elseif/else).
3. До и после строки, где ты определяешь функцию или класс нужно оставлять один пробел.
4. Фигурные скобки, определяющие начало тела функции либо класса, ставятся на следующей строке.
5. Убери лишние пробелы и табы
Ознакомься с гайдлайнами по оформлению PHP-кода:
1. https://www.php-fig.org/psr/psr-1/
2. https://www.php-fig.org/psr/psr-2/
Помни, анон, код больше читается, нежели пишется. Даже если ты пишешь решение задачки, код которой увидит и забудет небольшое количество анонимусов с двача, все-равно не ленись и пиши его аккуратно!
Начни с React/Redux. Попробуй написать проект, который на основе какого-нибудь публичного API выводит списки, где есть пагинация или постраничная навигация, а при нажатии на какой-либо элемент из списка перенаправляет на более детальную страницу об элементе используй react-router. Вот список открытых API:
https://github.com/toddmotto/public-apis
Если хорошо умеешь в верстку, на grid/flexbox с sass создай структуру проекта, если нет, можно использовать react-bootstrap или material UI.
Для начала, только средствами React компонентов, попробуй написать простой конвертер валют или вывести табы с днями недели и погодой. А затем приступай к более сложному проекту, в котором надо управлять состоянием здесь вступает в игру redux .
Экосистема довольна обширная, и походу дела необходимо будет много нового узнать.
После react/redux vue/vuex дается легко. в процессе ознакомления с js, поглядывай в сторону typescriprt. Насчет Angular ничего сказать не могу.
Какая разница, что у тебя на домашнем компьютере?
>>282306
А почему бы не делать сортировку по баллам дефолтно, если не задан параметр sort_by? Это намного логичнее, чем заниматься подстановкой параметров в ссылки.
>>282527
Посмотри за Flux, его реализовали в React/Redux например.
>>283377
Во-первых, студентам один год дают бесплатно, во-вторых можно всегда взять VSCode и настроить. Мне в компании хотели лицензию выдать, но я имаксер.
>>289947
Лучше всего React/Redux, ибо порог вхождения минимален.
>>289183
Slim/Silex.
>ибо порог вхождения минимален.
Анон, не будь таким снобом.
reactjs + material component
//Функции выравнивания
function padRight($string, $length)
{
$padRight = str_pad($string, $length, " ", STR_PAD_RIGHT);
return $padRight;
}
function padLeft ($string, $length)
{
$padLeft = str_pad($string, $length, " ", STR_PAD_LEFT);
return $padLeft;
}
// Заголовок таблицы
echo padRight('Сотрудник', $col1) .
padLeft('Часы', $col2) .
padLeft('Ставка', $col3) .
padLeft('З/п', $col4) . "\n\n";
Оно выравнивает данные, но не выравнивает шапку. Это пиздец какой-то, очко горит блять
что у тебя в соl1 и т.д. приходит то?
> Во-первых, студентам один год дают бесплатно
Даже не один, можно продлевать лицензию по мере перехода с курса на курс. Например у меня в сумме лицензия с 2014-го по 2019-й, и как только закончится - сразу куплю, оно того стоит. Ещё у них там скидки появляются (друг купил PHPStorm за полцены в день дружбы лол: https://blog.jetbrains.com/blog/2018/07/30/celebrate-this-friendship-day-with-jetbrains-and-unwrap-your-presents/ )
>>289947
А как не быть токсичным, если ты сам себя дауном называешь? И зачем тебе распыляться на два фронта, пиши себе бекенд, в чём проблема? Или работодатели не могут отдельно фронта нанять?
>>290027
Без вёрстки сможешь только туду-списки по туториалам делать. Сейчас в моде styled components (подход когда обеспечения модульности вёрстку кладут рядом с JS кодом), для разработки на фронтенд фреймворке нужно уметь в вёрстку:
- https://www.styled-components.com/
- https://vuejs.org/v2/guide/single-file-components.html
foreach ($hours as $hour){
if ($hour > 40){$hour += 10;}
}
Переменная $hour увеличивается, а при вардампе вне цикла она остается прежняя? И как с этим бороться кроме как тупой перестановкой внутри цикла (это же целая строка!)?
Тут случайно нет ответа на твой вопрос? https://github.com/codedokode/pasta/blob/master/php/strings-utf8.md
Мне не нравится. Что мешает верстку для компонента класть в отдельный CSS файл? Их подход:
- по производительности очень плох
- способствует загромождению шаблонов стилями
- не взаимодействует нормально с devtools
$hour это не элемент массива. Это переменная, в которую копируется значение из текущего элемента массива. От того, что ты её изменишь, в массиве ничего не поменяется. Где ты прочел, что так можно делать?
Мануал: http://php.net/manual/ru/control-structures.foreach.php
Ты даешь вредные советы. Если человек не умеет верстать, то ему надо осваивать основы, а не браться за flexbox. Так как он толком ничего не поймет.
flexbox сложный, запутанный, плохо поддерживаемый. Его лучше избегать, если задачу явно можно решить без него. Если считаешь, что я не прав, открой спецификацию флексбокса и проверь, можешь ли ты по памяти хотя бы приблизительно описать алгоритм расчета ширины/высоты. Я сталкивался с тем, что у криворуких людей, например, в верстке с флексбоксом размеры картинок ужимались в ноль (да, флексбокс может ужимать картинки, ты ведь это знаешь?).
Опять же, прежде чем учить SASS, надо освоить CSS. Так как SASS это препроцессор для CSS.
Кстати, ты, видимо, хорошо разбираешься во фронтенде? Не хочешь глянуть нашу задачу на SPA - она ведь несложная? А что что-то никто ее до сих пор не решил (( https://github.com/codedokode/pasta/blob/master/js/spa.md
Заметь, кстати, это та задача, где SPA нужен и приносит пользу. В отличие от всяких дурацких TODO списков и других типичных задач, которые проще сделать без SPA, на формах и PHP, и где реакт это оверкилл.
То есть, я имею в виду, в любом случае, сначала надо освоить основы верстки (у нас в шапке, кстати, есть задания), а потом уже браться за флексбокс, и тд. Реакт можно начинать изучать и параллельно, но без знания верстки им много не сделаешь.
<?php
error_reporting (-1);
echo "Бросаем кубик\n";
$random= mt_rand(1,6);
echo "Выпало $random "; / Я молодец :) /
?>
> по производительности очень плох
Но это ведь не инлайн стили, там в итоге один css файл собирается. Не вижу причин для проседаний.
> способствует загромождению шаблонов стилями
Стили находятся не в шаблоне, а в компоненте. В случае с Vue - это отдельный .vue файл, в случае с реактом будет просто вёрстка вверху файла. Компоненты обладает высоким cohesion (зацеплением?), из-за чего их очень удобно переиспользовать.
> не взаимодействует нормально с devtools
Там есть соурсмапы, так что всё тоже самое.
Из недостатков отмечу, что не работает emmet синтаксис для написания стилей, так как IDE не видит стили внутри JS кода (но это просто плагин для реакта нормальный не сделали, для Vue сделали).
> Что мешает верстку для компонента класть в отдельный CSS файл?
Тоже хороший вариант. Я хотел акцентировать внимание на том, что вёрстка во фронтенд фреймворках идёт бок-о-бок с JS кодом и её обязательно нужно знать.
>> не взаимодействует нормально с devtools
> Там есть соурсмапы, так что всё тоже самое.
Нет, там будут в HTML-коде CSS-классы вроде x76gdydsv, которые невозможно читать. Плюс, sourcemaps это зло: они часто глючат, требуют усилий по их поддержке, могут быть не той версии, итд. Лишняя возня. Плюс, при попытке отредактировать что-то в devtools они отключаются.
>Хочу кнопки нажимать и смотреть как это работает
"php -a" в консоль и играйся сколько влезет
А ты придумай алгоритм.
VScode
Как обойти? UserAgent-заголовки пробовал подменять - нихуя.
Вот такую хуйню выдает вместо требуемой страницы, короче говоря. На других сайтах тестил - всё норм.
Дебил, иди на хуй.
F
class phone
{
public $names = array(
Pavel' => '12345',
'Rita' => '11223',
'Egor' => '22334',
'Masha' => '33445',
'Lev' => '44553',
'Varya' => '55443');
function getNumberByName(){
echo $names['Pavel'];
}
}
$obj = new phone;
$obj->getNumberByName();
Потому что $names у тебя не переменная, а поле объекта.
Почему, в таком случае, ты обращаешься к нему как к переменной?
php 7 в подлиннике
Хватит издеваться, мне правда интересно. Я сделал простенькую задачку опа про вопросы через ООП, которые надо вводить или выбирать ответ, написал под это функцию создания объекта и прочие прелести и понял, что хуле я как лох вбиваю все сам в переменную и смотрю результат, если моя программа сама может все сделать, только скажи, даже переменную сгенерирует. Хочется оформить все в пользовательский интерфейс. Читаю учебник js и чувствую, что я это уже где-то видел. Хочется уже программами срать а не в алфавит играться
В духе посмотреть входящие, отправленные, отправить новое.
С меня тонна нефти
ты действительно молодец, держи в курсе
https://ideone.com/sY6axO
подскажите что я делаю не так (возможно что все не так)
Так вот, на конкурс записываются люди.
Нужно сделать рассылку по участникам конкурса с новостями, правилами и прочей инфой.
Как бы вы организовали это?
Вариант 1:
Таблица contest_mail, где будет contest_id, text, subject, targeting. В поле targeting будут записываться параметры: возраст, регион, статус на сайте, и в момент отправки писем, получатели по этим параметрам будут отбираться динамически.
Но как не проебаться, и не выбрать одного и того же человека дважды, если слать письма пачками штук по 100? Пока идея такая: SQL запрос с определенной сортировкой и записью последнего выбранного user_id, который дальше подставлять в этот SQL запрос, чтобы выборка начиналась с него.
2 вариант: все то же самое, только сделать дополнительную таблицу: contest_mail_recipient. Куда в момент сохранения параметров рассылки сразу делать записи, кому и какую рассылку следует отправить. Но минус в том, что при каждом сохранении рассылки куча записей будут удаляться/вставляться. Алсо, если после сохранения получателей, набегут еще человек 100 в конкурс, то они как получатели запишутся только при новом сохранении рассылки.
Так вот, какой метод предпочтительнее: динамический или статический?
https://ideone.com/ejM0XM
все сделал, заработало
проверьте пожалуйста все так?
натыкайте носом в косяки
Emails - https://ideone.com/K5xlAn
Опечаточник - https://ideone.com/T9lkRz
Grammar Nazi - https://ideone.com/092o3K
Grammar Nazi Next - https://ideone.com/NU9Zee
Shift - https://ideone.com/L4JUTk
Ideone mb_strtoupper не опознаёт, так что вот результат на пике
Где я не прав?
<?php
error_reporting(-1);
echo "Lets start the game!\n";
$human1 = mt_rand(1,6);
$human2 = mt_rand(1,6);
$robot1 = mt_rand(1,6);
$robot2= mt_rand(1,6);
echo "Human got $human1 and $human2, robot got $robot1 and $robot2\n";
if (($human1 == $human2) || ($robot1 == $robot2)) {
echo "Double! Greatest luck you ever had!";
exit ();
if (($human1 + $human2) > ($robot1 + $robot2)) {
echo "Human got ($human1+$human2), robot got ($robot1+$robot2), Human won!\n";
}
elseif (($human1+$human2) < ($robot1+$robot2)) {
echo "Human got ($human1+$human2), robot got ($robot1+$robot2), Robot won!\n";
}
}
elseif (($human1+$human2) == ($robot1+$robot2)) {
echo "Human got ($human1+$human2), robot got ($robot1+$robot2), Draw!\n";
}
}
?>
Где я не прав?
<?php
error_reporting(-1);
echo "Lets start the game!\n";
$human1 = mt_rand(1,6);
$human2 = mt_rand(1,6);
$robot1 = mt_rand(1,6);
$robot2= mt_rand(1,6);
echo "Human got $human1 and $human2, robot got $robot1 and $robot2\n";
if (($human1 == $human2) || ($robot1 == $robot2)) {
echo "Double! Greatest luck you ever had!";
exit ();
if (($human1 + $human2) > ($robot1 + $robot2)) {
echo "Human got ($human1+$human2), robot got ($robot1+$robot2), Human won!\n";
}
elseif (($human1+$human2) < ($robot1+$robot2)) {
echo "Human got ($human1+$human2), robot got ($robot1+$robot2), Robot won!\n";
}
}
elseif (($human1+$human2) == ($robot1+$robot2)) {
echo "Human got ($human1+$human2), robot got ($robot1+$robot2), Draw!\n";
}
}
?>
3-6 месяцев с нуля, если в день сидеть >4 часов
На данном этапе обучения, тебе нужно сконцентрироваться на понимании самих конструкций, что такое объект, что такое поля, методы. Увидеть как объекты взаимодействуют между собой. Чтобы это понять достаточно командной строки. Затем тебе надо будет решить задачу про компанию Вектор (здесь тоже придется обойтись лишь командной строкой). Только потом приступай к использованию php для написания веб-приложений, тогда ты поймешь, как сделать пользовательский интерфейс при помощи форм, получить от пользователя данные, использовать их и отобразить результат.
>я как лох вбиваю все сам в переменную и смотрю результат, если моя программа сама может все сделать, только скажи, даже переменную сгенерирует
Цитируя Мартина Фаулера:
Всякий раз, когда возникает соблазн что-то распечатать, используя print, или написать отладочное выражение, напишите тест вместо этого.
>Читаю учебник js и чувствую, что я это уже где-то видел
Ошибочное чувство, если ты уже это видел, сможешь объяснить в чем разница между this на php и this на js?
>Объясните мне зачем нужен parent::
https://phpbooktest2.ga/l1/pasta.html Раздел "Наследование Классов".
>что за self (почему не this как в других источниках?)
self - ссылка на текущий класс
this - ссылка на текущий объект
Объекты, инстанцированые от одного класса делят между собой общие поля и методы класса, но могут иметь различные поля и методы объекта.
https://ideone.com/4kTUzx
Как ты запускаешь этот код? В уме?
Хотел написать, чтобы довены не работающие с регулярками, не писали. Но решил что это очевидно...
Анон, подскажи, что не так?
Решил я значит поизучать Yii и воспользовался этим видео.
https://www.youtube.com/watch?v=0E4QKJwZok4
Скачиваю wamp, все слово в слово повторяю и на пункте инициализации библиотеки (запуска из-под консоли init.bat) получается хуита:
Ошибка """php.exe"" не является внутренней или внешней"
Прописал путь до версии ПХП - не помогло.
Что не так?
Плохо зделоли, тупо. Спасибо
Под "все" я имею в виду остальные пути в системе, для Питона или Руби, например. А так для конкретной версии ПХП надо.
Попробуй компуктер перезагрузить
Неделю назад устроился на первую свою проггерскую работу на пхп. 60к в месяц, не веб студия и не хуитрикс (Laravel юзают и Симфони, в основном пишем RESTApi и непосредственно логику всего, что не на с++), связано с документооборотом, у ребят там масштабы типа портала госуслуг - общая система авторизации и куча ништяков, используют последние технологии, кубернетс, свои фронтендеры, свой девопс, свои с++ ники на подсосе у бэкэнда, короче прямо мечта, а не работа.
Они через 2 часа позвонили с собеседования и пригласили к ним работать. Это было второе собеседование в моей жизни, с первого тоже недавно позвонили и пригласили на работу, правда предложили немного больше, но мне на втором тимлид очень понравился, заебатый чувак, поэтому отказался.
Тимлид еще удивлялся, что я понимаю ОПП, паттерны и SOLID, Dependency Container/injection и т.д., и могу запрос SQL с джоином и каунтом написать, и что у меня есть пара небольших проектиков личных.
Посмотрел я тред - ну это пиздец, ребята. Теперь я понимаю почему меня с руками оторвать хотели, если такое, что вы тут творите - норма для начинающих. А дискуссии даунов про ненужность архитектурных подходов - это вообще очень грустно...
Еще добавлю - те, кто планирует вкатываться в самое дно:
1) Веб студий и битрикса стало явно меньше, если учитывать то, что я видел на хедхантере год назад.
2) Вы, скорее всего, так и останетесь на этом уровне навсегда, ибо подходы у крупных фирм и у конвеера на дне - просто невероятно разные.
Еще добавлю забавный факт - на собеседовании я просил 30к, и даже думал, что много прошу, лол блять.
>Теперь я понимаю почему меня с руками оторвать хотели, если такое, что вы тут творите - норма для начинающих.
Тред не читал, что тут творят? Алсо, ООП и паттерны - это сейчас стандарт, по факту это даже фронт энд макаки сейчас знают, а битрикса столько же, сколько и всегда - овер до хуя. Даже слишком до хуя. Хотел бы я, чтоб его было меньше. У меня бывали случаи, что меня разворачивали из-за его __НЕ__ знания (sic!).
>это сейчас стандарт, по факту это даже фронт энд макаки сейчас знают
Как ты ошибаешься...) ООП - это окей, паттерны - ну с натяжкой кто-то что-то там читал, но о SOLID могут сказать (с пониманием) 10% из собеседуемых (на моей практике), о написании запроса с джоином - это вообще для многих непосильная задача и самое частое оправдание - это "ну мы же на орм/active record/eloquent/что угодно пишем", блять.
А вообще нужно не знать, а именно понимать - а понимают оооочень немногие. Заучить цель паттерна и его структуру - это даже не полдела, это просто один шаг к пониманию этого паттерна. На самом деле вопросы про паттерны помогают отсеить людей, которые просто выучили их - ты начинаешь задавать вопросы: "А где еще можно вот этот паттерн использовать?", или "А чем стратегия от стейта отличается?" (это естественно, если он говорит, что знает оба эти паттерна), или "А на своем опыте какие паттерны и где применял?". Фейлятся на этом очень быстро и даже если человек не смог ответить на какой-то вопрос - по тому, как он мыслит и что говорит - можно еще и аутистов отсеить.
Например, если человек честно говорит, что он заучил их, но пока реальной задачи на применение у него не было, но он хоть какой-нибудь самый базовый типа той-же фабрики или декоратора использовал - то это уже сразу большой и жирный плюс. Ищут не робота, который всё знает, ищут человека, который адекватно оценивает окружение и себя и может учиться. Если человек что-то сам делал, и делал это не на дерьме, типа CMS, и у него есть пусть небольшие, но хорошие результаты - то "недостаток опыта" - это вообще похуй. Но когда человек знает всё с книги, но при этом не использовал это или использовал просто потому-что так надо - то это жирный и большой звоночек, что такой человек мне нахуй не нужен, я лучше обучу и помогу тому, кто уже сталкивался с простыми проблемами и уже набил шишки и имеет хотя-бы представление "зачем", а не буду ебать себе мозг с человеком, который лишь знает "как".
Мимо мидло-синьоро ля пехепехо.
>это сейчас стандарт, по факту это даже фронт энд макаки сейчас знают
Как ты ошибаешься...) ООП - это окей, паттерны - ну с натяжкой кто-то что-то там читал, но о SOLID могут сказать (с пониманием) 10% из собеседуемых (на моей практике), о написании запроса с джоином - это вообще для многих непосильная задача и самое частое оправдание - это "ну мы же на орм/active record/eloquent/что угодно пишем", блять.
А вообще нужно не знать, а именно понимать - а понимают оооочень немногие. Заучить цель паттерна и его структуру - это даже не полдела, это просто один шаг к пониманию этого паттерна. На самом деле вопросы про паттерны помогают отсеить людей, которые просто выучили их - ты начинаешь задавать вопросы: "А где еще можно вот этот паттерн использовать?", или "А чем стратегия от стейта отличается?" (это естественно, если он говорит, что знает оба эти паттерна), или "А на своем опыте какие паттерны и где применял?". Фейлятся на этом очень быстро и даже если человек не смог ответить на какой-то вопрос - по тому, как он мыслит и что говорит - можно еще и аутистов отсеить.
Например, если человек честно говорит, что он заучил их, но пока реальной задачи на применение у него не было, но он хоть какой-нибудь самый базовый типа той-же фабрики или декоратора использовал - то это уже сразу большой и жирный плюс. Ищут не робота, который всё знает, ищут человека, который адекватно оценивает окружение и себя и может учиться. Если человек что-то сам делал, и делал это не на дерьме, типа CMS, и у него есть пусть небольшие, но хорошие результаты - то "недостаток опыта" - это вообще похуй. Но когда человек знает всё с книги, но при этом не использовал это или использовал просто потому-что так надо - то это жирный и большой звоночек, что такой человек мне нахуй не нужен, я лучше обучу и помогу тому, кто уже сталкивался с простыми проблемами и уже набил шишки и имеет хотя-бы представление "зачем", а не буду ебать себе мозг с человеком, который лишь знает "как".
Мимо мидло-синьоро ля пехепехо.
У разработчика лендингов в веб студии подгорело?
Но всё чаще грусть тоска меня съедает когда я открываю hh, вакансий жунов жс без опыта почти нет, а если и есть то для этого ты уже должен быть версталой, знать препроцессоры, галпы, вебпаки, адаптивно верстать и всё вот это. Т.е. подразумевается что они больше нацелены на верстальщиков с минимальным знанием жс, которые будут верстать в реакте не забивая себе голову чем-то сложным. Т.е. вакансий нет блять. Но мне постоянно всплывают в рекомендациях вакансии жунов ПХП и требования не такие простыни, как на жс, обычно просят пхп, ларавель и сьюл и ОБУЧАЕМОСТЬ. Ну и я кароч думаю браться за пхп. Цель максимально быстро найти работу за 200-300 баксов в месяц.
Что скажете? Что посоветуете для максимально быстрого вката? Можно начинать учить сразу с фреймворка? С того же ларавеля? Нет времени пол года еще убивать на досканальное изучение ванильного пхп и т.д. Может есть какие-то убер годные курсы на пхп, платина? Помогите плиз. Или мне пиздец. Не хочу идти водителем убера работать.
спасибо, ваше мнение очень важно для нас.
>обычно просят пхп, ларавель и сьюл и ОБУЧАЕМОСТЬ
Пхп - ООП, MVC, паттерны, SOLID. Желательно: spl, генераторы, ссылки.
Laravel - eloquent, middleware, request, policies, doctrine, blade, webpack+npm
SQL - индексы, оптимизация запросов(explain/slow_query_log), джоины, типы данных, ключи, связи
Это чисто база, с которой тебя возьмут на джуна.
Т.е. ты меняешь шило на мыло. В любом случае знать нужно дохуя везде.
Ну реально блять, за 300 баксов пердолить пхп это ебанизм.
У нас дворники в два раза болше имеют. Они метут асфальт метлой.
Уже месяц пытаюсь вкатиться.
За это время выучил/подтянул
JS
C#
NodeJs
Java
jQuery
React
Yii
Linux
Сейчас ещё БД надо и с линуксом углубиться.
Если повезет, возьмут в контору с зп 30к.
>PHP, C#, Java, JS
Ты долбаеб? Тебя никуда не возьмут, если такой аркестр в резюме засунешь, определись конкретно с языком.
>30k
Слишком мало, тебя скорее не возьмут, потому-что ты за еду готов работать, а не потому-что ты тупой.
>Тебя никуда не возьмут, если такой аркестр в резюме засунешь
Почему? PHP и JS почти всегда стеком идут. Да и Java/C# (идентичные на 90%) тоже к вебу подходят
>Слишком мало, тебя скорее не возьмут, потому-что ты за еду готов работать, а не потому-что ты тупой.
Не, я не дурак. Я ж в резюме 40 написал! Это в вакансии 30 предлагают.
Работодатель не дурак. Он понимает, что если ты учишь 3 разных языка - то ты в каждом разбираешься на хуевом уровне.
Потому-что резюме пишутся так:
- Ой, ребят, нам нужно нового проггера нанять, че в требованиях писать?
- Да накидай, чтоб программирование знал, ну там всякие алгоритмы, про язык нпиши
>Программирование - pascal, delphi, php, c++, c#, java, javascript...
Ну на собеседовании тебя про них и не спросят. Просто hr (тупая бабища) понакидала знакомых ключевых слов. Может оказаться, что это вообще не php собеседование.
А как тогда правильно в собеседовании указать?
Типа, я ж только в тегах написал, с чем знаком.
Python же!
В целях повышения удержания пользователей на сайте надо определять, что пользователь хочет закрыть страницу и показать в ему в такой ситуации красивое уникальное предложение, в надежде что он остановится и заинтересуется им. При том желательно избежать ложных срабатываний, или как-то минимизировать негативный эффект от них.
Предложите алгоритм или реализацию.
Предлагаю пытать раскаленным паяльником разработчиков таких фич. Только хочешь вкладку закрыть, так тебе на весь экран прилетает НИУХАДИТИ ПЛИС((9, это выглядит жалко и раздражает, не делойте так.
совсем блять охуели
показываешь красивое уникальное предложение сразу
???
профит
а теперь нахуй путешествуй
Пиши то, чем конкретно будешь заниматься. Т.е. нахуй выкидывай про Java и про C#. То, что ты человек-швейцарский нож сыграет только в минус в итоге. Тимлиду нужен человек, который любит один язык и изучает его, а не распыляется на хуй знает что, причем PHP и Java/C# - очень разные вещи и знать сразу два подобных языка на хорошем уровне - сложно, как минимум потому-что у них абсолютно разные задачи и подходы.
if ($op == ' '){
} elseif...
Я так решал. Если операция первая, то значение пустое и тогда я откладывал номер в результат, оп задавал. Ну и так далее
ну а как ты выполнял само умножение/сложение? до меня это не доходит
не, там логично все как в коде у ОПа, надо просто подумать.
Мне нужно вот это:
echo file_get_contents('.passwd');
Перевести в non alphanumeric вид, типа того:
$___="\\$___";
Заранее спасибо.
Бля, картинка не та приклеилась.
$a=readline("Вы хотите уйти со страницы? Y/N");
$a=strtoupper($a);
if $a='Y' { vigodnoe_predlojenie(); }
else { break; }
Ты просто пишешь if/elseif для каждой операции по типу:
if ($op == '+') {
$result += $number;
} elseif ($op == '-') {
$result -= $number;
} else {
неправильная операция $op;
}
Или что-то другое непонятно? Уточни тогда.
>>292434
Ну ок, не хотите это, поломайте голову над задачками про ООП:
- ООП-Будильник: https://phpclub.tech/pr/res/1232710.html#1263399
- ООП-Гостиница: https://phpclub.tech/pr/res/1082507.html#1097078
>>292321
По SQL не мешало бы нормализацию подучить, про миграции узнать. Паттерны без опыта работы с кодом мало что дадут, так как непонятно, где их применять.
>>292207
Еще лучше спрашивать, "а зачем тут нужна стратегия, если можно if поставить вместо нескольких классов?" - это почти любого выбьет.
Ты просто пишешь if/elseif для каждой операции по типу:
if ($op == '+') {
$result += $number;
} elseif ($op == '-') {
$result -= $number;
} else {
неправильная операция $op;
}
Или что-то другое непонятно? Уточни тогда.
>>292434
Ну ок, не хотите это, поломайте голову над задачками про ООП:
- ООП-Будильник: https://phpclub.tech/pr/res/1232710.html#1263399
- ООП-Гостиница: https://phpclub.tech/pr/res/1082507.html#1097078
>>292321
По SQL не мешало бы нормализацию подучить, про миграции узнать. Паттерны без опыта работы с кодом мало что дадут, так как непонятно, где их применять.
>>292207
Еще лучше спрашивать, "а зачем тут нужна стратегия, если можно if поставить вместо нескольких классов?" - это почти любого выбьет.
Ты просто пишешь if/elseif для каждой операции по типу:
if ($op == '+') {
$result += $number;
} elseif ($op == '-') {
$result -= $number;
} else {
неправильная операция $op;
}
Или что-то другое непонятно? Уточни тогда.
>>292434
Ну ок, не хотите это, поломайте голову над задачками про ООП:
- ООП-Будильник: https://phpclub.tech/pr/res/1232710.html#1263399
- ООП-Гостиница: https://phpclub.tech/pr/res/1082507.html#1097078
>>292321
По SQL не мешало бы нормализацию подучить, про миграции узнать. Паттерны без опыта работы с кодом мало что дадут, так как непонятно, где их применять.
>>292207
Еще лучше спрашивать, "а зачем тут нужна стратегия, если можно if поставить вместо нескольких классов?" - это почти любого выбьет.
Ты просто пишешь if/elseif для каждой операции по типу:
if ($op == '+') {
$result += $number;
} elseif ($op == '-') {
$result -= $number;
} else {
неправильная операция $op;
}
Или что-то другое непонятно? Уточни тогда.
>>292434
Ну ок, не хотите это, поломайте голову над задачками про ООП:
- ООП-Будильник: https://phpclub.tech/pr/res/1232710.html#1263399
- ООП-Гостиница: https://phpclub.tech/pr/res/1082507.html#1097078
>>292321
По SQL не мешало бы нормализацию подучить, про миграции узнать. Паттерны без опыта работы с кодом мало что дадут, так как непонятно, где их применять.
>>292207
Еще лучше спрашивать, "а зачем тут нужна стратегия, если можно if поставить вместо нескольких классов?" - это почти любого выбьет.
Информация есть в мануале http://php.net/manual/ru/features.commandline.webserver.php
Предназначен для dev-окружения (для твоего компа), можно поднять приложение без установки апачей и нгинксов. На продакшене использовать нельзя, так как однопоточный (обрабатывает HTTP-запросы по 1 за раз) и большой нагрузки не потянет.
Немного про него у написано у меня тут: https://github.com/codedokode/pasta/blob/master/soft/web-server.md#веб-сервер
Рест-API ты пишешь на PHP, а запускать можно с любым сервером - хоть с встроенным, хоть с нгинкс.
>>292196
Практически все, что ты описал, изучается в нашем треде.
>>292150
После смены PATH надо либо перезагрузить систему, либо разлогиниться/залогиниться.
>>292117
В случае с бекслешами, проблема в том, что они интерпретируются в 2 местах:
- сначала PHP разбирает код и заменяет \\ на \
- затем эта строка передается движку регулярок и он уже интерпретирует последовательности с бекслешами
Чтобы увидеть, что получит движок регулярок, используй echo:
echo '\\\[ab]'; // выведется \\[ab] что понимается в регулярке как "ищи бекслеш, а далее идет a либо b"
У тебя явно ошибка в регулярке, чтобы написать "искать бекслеш", надо написать 4 бекслеша подряд:
echo '\\\\'; // выведется \\ что воспринимается в регулярке как "ищи 1 бекслеш"
Информация есть в мануале http://php.net/manual/ru/features.commandline.webserver.php
Предназначен для dev-окружения (для твоего компа), можно поднять приложение без установки апачей и нгинксов. На продакшене использовать нельзя, так как однопоточный (обрабатывает HTTP-запросы по 1 за раз) и большой нагрузки не потянет.
Немного про него у написано у меня тут: https://github.com/codedokode/pasta/blob/master/soft/web-server.md#веб-сервер
Рест-API ты пишешь на PHP, а запускать можно с любым сервером - хоть с встроенным, хоть с нгинкс.
>>292196
Практически все, что ты описал, изучается в нашем треде.
>>292150
После смены PATH надо либо перезагрузить систему, либо разлогиниться/залогиниться.
>>292117
В случае с бекслешами, проблема в том, что они интерпретируются в 2 местах:
- сначала PHP разбирает код и заменяет \\ на \
- затем эта строка передается движку регулярок и он уже интерпретирует последовательности с бекслешами
Чтобы увидеть, что получит движок регулярок, используй echo:
echo '\\\[ab]'; // выведется \\[ab] что понимается в регулярке как "ищи бекслеш, а далее идет a либо b"
У тебя явно ошибка в регулярке, чтобы написать "искать бекслеш", надо написать 4 бекслеша подряд:
echo '\\\\'; // выведется \\ что воспринимается в регулярке как "ищи 1 бекслеш"
С таким настроем лучше вообще ничего не писать.
>>291497
Давай начнем с определений, прочти очень внимательно:
- класс объекта - это класс, который был указан при создании объекта в new: $a = new Child; // тут это Child
- "окружающий" класс - это класс, в коде которого использовано слово $this, self, итд (это название я сам придумал, не знаю, как это назвать. Статический контекст?).
- окружающий метод - метод, в котором использовано слово $this, self, итд
Также, пусть у нас есть такая цепочка классов: предок Grandparent (G) -> его наследник Parent (P) -> его наследник Child(C) (т.е. Child extends Parent, Parent extends Grandparent).
$this используется для обращения к обычному полю или обычному методу того же самого объекта. Поле или метод ищутся по цепочке наследников, начиная с класса объекта, и заканчивая самым древним предком (C -> P -> G)
$this->x = 1;
$this->y();
Исключение - приватные методы/поля, они ищутся только в окружающем классе.
В соответствие с приницпом Лисков ты должен обращаться только к полям или методам, которые есть в окружающем классе или его предках. Нельзя обращаться к полям, которые будут добавлены только в наследнике. Так как в момент написания предка ты не знаешь, кто от него будет наследоваться и какие там будут поля.
parent, self, static используются для указания на статическое поле, статический метод, или обычный метод в предке с тем же названием, что и окружающий. Допустим, код ниже написан в классе P и вызывается из объекта класса C:
parent::x() - обычный или статический метод x ищется от предка окружающего класса вглубь (G)
self::x() - статический метод x в окружающем классе или его предках (P -> G)
static::x() - статический метод x ищется от класса объекта к предкам (C -> P -> G)
parent:: обычно используется только для вызова метода с тем же названием в предке.
Примеры обращений к статическим полям:
self::$x = 1;
Опять же, приватные поля/методы ищутся только в окружающем классе.
Не запутал?
С таким настроем лучше вообще ничего не писать.
>>291497
Давай начнем с определений, прочти очень внимательно:
- класс объекта - это класс, который был указан при создании объекта в new: $a = new Child; // тут это Child
- "окружающий" класс - это класс, в коде которого использовано слово $this, self, итд (это название я сам придумал, не знаю, как это назвать. Статический контекст?).
- окружающий метод - метод, в котором использовано слово $this, self, итд
Также, пусть у нас есть такая цепочка классов: предок Grandparent (G) -> его наследник Parent (P) -> его наследник Child(C) (т.е. Child extends Parent, Parent extends Grandparent).
$this используется для обращения к обычному полю или обычному методу того же самого объекта. Поле или метод ищутся по цепочке наследников, начиная с класса объекта, и заканчивая самым древним предком (C -> P -> G)
$this->x = 1;
$this->y();
Исключение - приватные методы/поля, они ищутся только в окружающем классе.
В соответствие с приницпом Лисков ты должен обращаться только к полям или методам, которые есть в окружающем классе или его предках. Нельзя обращаться к полям, которые будут добавлены только в наследнике. Так как в момент написания предка ты не знаешь, кто от него будет наследоваться и какие там будут поля.
parent, self, static используются для указания на статическое поле, статический метод, или обычный метод в предке с тем же названием, что и окружающий. Допустим, код ниже написан в классе P и вызывается из объекта класса C:
parent::x() - обычный или статический метод x ищется от предка окружающего класса вглубь (G)
self::x() - статический метод x в окружающем классе или его предках (P -> G)
static::x() - статический метод x ищется от класса объекта к предкам (C -> P -> G)
parent:: обычно используется только для вызова метода с тем же названием в предке.
Примеры обращений к статическим полям:
self::$x = 1;
Опять же, приватные поля/методы ищутся только в окружающем классе.
Не запутал?
>>291131
Тебе достаточно изучить основы HTML и HTML-формы. Вот урок, где есть пример передачи параметров в скрипт для его запуска и просмотра результатов в браузере: https://github.com/codedokode/pasta/blob/master/soft/web-server.md#передача-аргументов-в-скрипт
Прикрути туда форму (она возьмет значения из полей, подставит их в query string и выполнит запрос на сервер) и будет то, что ты хотел.
Но старайся не смешивать логику программы с логикой ввода/вывода данных. Их надо разнести отдельно.
>>291996
У тебя неправильно стоят фигурные скобки. Должно быть так:
if (условие 1) {
действия в этом случае;
} elseif (условие 2) {
...
} else {
...
}
Либо так (хуже):
if (условие 1){
действия 1;
exit();
}
if (условие 2){
действия 2;
exit();
}
Изучи внимательно, как работает if.
>>291131
Тебе достаточно изучить основы HTML и HTML-формы. Вот урок, где есть пример передачи параметров в скрипт для его запуска и просмотра результатов в браузере: https://github.com/codedokode/pasta/blob/master/soft/web-server.md#передача-аргументов-в-скрипт
Прикрути туда форму (она возьмет значения из полей, подставит их в query string и выполнит запрос на сервер) и будет то, что ты хотел.
Но старайся не смешивать логику программы с логикой ввода/вывода данных. Их надо разнести отдельно.
>>291996
У тебя неправильно стоят фигурные скобки. Должно быть так:
if (условие 1) {
действия в этом случае;
} elseif (условие 2) {
...
} else {
...
}
Либо так (хуже):
if (условие 1){
действия 1;
exit();
}
if (условие 2){
действия 2;
exit();
}
Изучи внимательно, как работает if.
> Emails - https://ideone.com/K5xlAn
Задача была достать email из строки с текстом (где есть email и посторонние слова), а не из массива. Так что пока не то.
>Опечаточник - https://ideone.com/T9lkRz
Ты просто выделяешь все латинские буквы. Но надо искать случаи, когда слово состоит из букв обоих алфавитов, а если слово полностью на русском или полностью на английском, то это нормально.
>Grammar Nazi - https://ideone.com/092o3K
Тут ты скопипастил if 5 раз. А можешь без копипасты (подсказка: используй цикл по массиву правил)?
> "/\s+(а|но)/ui"
это правило сработает на слово "ночь".
> нет пробела после запятой, точки с запятой, восклицательного знака, вопросительного знака, двоеточия
Это правило у тебя не проверяется.
>Grammar Nazi Next - https://ideone.com/NU9Zee
Те же замечания, что к предыдущей задаче.
>Shift - https://ideone.com/L4JUTk
Неплохо, но можешь сделать, чтобы многоточия и другие группы знаков препинания не разбивало бы пробелами?
>>291793
exit тут ненужен. Он был в исходном варианте, чтобы после обнаружения дабла программа завершалась, но у тебя она после этого завершается в любом случае.
В else условие не пишут.
Тут лишняя точка с запятой, смотри внимательно:
else ($anonSum == $compSum); {
Точка с запятой завершает блок if и код интерпретируется так:
if (...) {
...
} else {
//Это воспримется не как условие, а как действие для else
($anonSum == $compSum);
}
// Это не часть if, а просто сгруппированные команды
{
echo "Ничья, Победила дружба!\n";
exit();
}
> Emails - https://ideone.com/K5xlAn
Задача была достать email из строки с текстом (где есть email и посторонние слова), а не из массива. Так что пока не то.
>Опечаточник - https://ideone.com/T9lkRz
Ты просто выделяешь все латинские буквы. Но надо искать случаи, когда слово состоит из букв обоих алфавитов, а если слово полностью на русском или полностью на английском, то это нормально.
>Grammar Nazi - https://ideone.com/092o3K
Тут ты скопипастил if 5 раз. А можешь без копипасты (подсказка: используй цикл по массиву правил)?
> "/\s+(а|но)/ui"
это правило сработает на слово "ночь".
> нет пробела после запятой, точки с запятой, восклицательного знака, вопросительного знака, двоеточия
Это правило у тебя не проверяется.
>Grammar Nazi Next - https://ideone.com/NU9Zee
Те же замечания, что к предыдущей задаче.
>Shift - https://ideone.com/L4JUTk
Неплохо, но можешь сделать, чтобы многоточия и другие группы знаков препинания не разбивало бы пробелами?
>>291793
exit тут ненужен. Он был в исходном варианте, чтобы после обнаружения дабла программа завершалась, но у тебя она после этого завершается в любом случае.
В else условие не пишут.
Тут лишняя точка с запятой, смотри внимательно:
else ($anonSum == $compSum); {
Точка с запятой завершает блок if и код интерпретируется так:
if (...) {
...
} else {
//Это воспримется не как условие, а как действие для else
($anonSum == $compSum);
}
// Это не часть if, а просто сгруппированные команды
{
echo "Ничья, Победила дружба!\n";
exit();
}
Ставим в FF User-Agent Mozilla/5.0 (X11; Arch Linux; Linux x86; rv:52.3.0) Gecko/20100101 Firefox/52.3.0 и заходит на гитхаб - все ок.
Меняем там ОС на винду - Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:52.3.0) Gecko/20100101 Firefox/52.3.0 - появляется сообщение о неподдерживаемом браузере и отключается JS с кучей полезного функционала (по сути писать даже комментарии нельзя).
Браузер при этом один и тот же. С абсолютно одинаковой поддержкой технологий. Просто пользователям Windows на гитхабе не рады.
Это мне напоминает историю, когда Гугл постоянно ломал поддержку Оперы в своих продуктах, и это лечилось заменой User-Agent.
Так почему они банят ФФ 52 под виндой, но не банят под линуксом? Тебе не кажется, что логичнее банить малочисленных линуксоидов?
Не смогу конечно. Как раз сейчас делаю задачу по вектору, жжения в жопе от ООП не ощущаю. Единственное что - создаётся ощущение, что я делаю что-то не так. Пока не буду выкидывать код(т.к. он не дописан), но распишу что он из себя представляет. Надеюсь что Добрый Анон скажет где я проебался.
У меня объект компания, в котором лежит инфа о всех департаментах. От него зависит объект департамент, в котором записан лидер и название департамента . Далее работник, в котором вся инфа о работнике и дофига методов для тестов правильности заполнения, методов установки переменных, метод рассчёта, отладочный метод и прочее. Все, естественно, запривачено, а методы выше защищены, методы департамент и компания абстрактные. Конец. А отдельно живут функции создания объектов, создания разметки, массив с работниками который называется рекруты (я решил дать каждому работнику ещё и имя, хоть и условное, поэтому есть большой массив рекрутов с желаемым департаментом, именем и т.д.), функция распаковки массивка с последующей упаковкой объектов в массив, функция подсчета общих цифр по департаментам и, естественно, небольшой код, который запустит все это дерьмо. И вот когда я начал писать функцию подсчета общего числа работников, зп и прочего, у меня возникло чувство, что я что-то делаю не так. С одной стороны, это можно было запихнуть в объект департамента, а общий итог - в объект компании. С другой стороны департамент и компания - это абстрактные классы, а значит вызвать или создать объект из них я не смогу.
Подскажи, добрый Аноне, правильно ли я делаю?
Забыл еще написать, что у меня дохера комментариев, в которых обозначается что где есть. Ну, что есть, почти над каждой функцией я писал зачем она, а некоторый код, чтобы не выкидывать, я пихал в коммент и помечал что это вообще и откуда оно. Еще одна причина моего не особого желания выкладывать код. Он очень большой, в итоговом варианте вместе с массивом рекрутов и комментариями строк 300
И да, я столкнулся со вполне очевидной проблемой - не могу найти общую сумму т.к. все свойства объектов я сам же и защитил. Ну все, теперь я потерялся
>Доктор, у меня геморой, но я не буду его показывать, потому что я стесняюсь. Вооооот... Я сейчас его нарисую на бумужке!
>"а зачем тут нужна стратегия, если можно if поставить вместо нескольких классов?"
Да вроде этот вопрос обычно обкашливается в любой статье про этот паттерн, нет?
Хотя вообще, да. Норм вопрос. Как раз и солид затронет и в целом мышление человека.
Что посоветует анон?
Пару лет назад постоянно на слуху был yii2, сейчас чето о нем слышу все меньше.
Часто слышу: Symfony и Zend, может задрочить что-то из этого? Еще давно мечтаю, но никак руки не доходили посмотреть на Slim - простой фреймворк, удобный для написания REST-API, стоит на него обратить внимание?
Странно. Те, кто действительно давно работают - в курсе, что Symfony и Laravel - это 2 доминанта. Laravel - для всего, Symfony - для энтерпрайза. Yii2 постепенно умирает, еще с тех пор, как их главный свалил.
>top1 фреймворк PHP в мире
>ЛАРАЕБ ЫЫЫЫЫ РРРРЯЯЯЯЯЯЯЯЯЯЯ
Я лишь констатирую факт рынка, писал я и на Yii2, и на ларе, сейчас на проекте с Silex и Symfony работаю, пилим микросервисы со своим OAuth.
>Те, кто действительно давно работают - в курсе
это те, кто в конфах и тредах давно срется. У меня из-за работы хуй время есть даже разобраться что сейчас топчик.
Начальнику похуй. Клиент платит за то, что я пилю? Збс, а стек сам выбирай, что потребуется - то и юзай. Благо деньжатами не обижает, но времени рил нету. Я относительно недавно выкроил вемечко, чтобы обуздать некоторые свистоперделки седьмой пыхи
Здравствуйте, товарищи программисты. Я начинающий. Не могли бы вы мне помочь понять, что делает эта функция? mysqli_fetch_array()
В гугле как то непонятно.
И почему в конце mysqli стоит буква i?
Не понял бугурта. Ларавел - это упрощенный Симфони, но без платной поддержки для энтерпрайза. А Симфони тем и ценится для большого бизнеса, что они покупают пакет платной поддержки, причем нехуевый такой, сравнимый с майкрософтовским. И при любой проблеме - они пинают саппорт и те фиксят всё, что угодно в кратчайшие сроки, в том числе туда входят и аудиты ПО и много чего еще интересного.
А с Laravel ты получаешь гулькин хуй, документацию и stackoverflow, ну и лишь надежду на то, что твои программисты сами смогут решать проблемы фреймворка и тратить на это время.
По рейтингам Laravel находится в топ 1 по миру. Дальше идет symfony. Yii2 к примеру еле догоняет по рейтингам Codeigniter.
>>292842
>Начальнику похуй. Клиент платит за то, что я пилю? Збс, а стек сам выбирай, что потребуется - то и юзай.
Так если ты макака - то смысл вступать в спор о фреймворках? Для тебя лучшим решением может быть даже CMS. А лучше шли нахуй такого работодателя, повышай квалификацию и найди нормальную работу. У нас в компании разработка начиналась еще с 5.5 версии пыхи. И постепенно шли в ногу со временем. Сейчас осталось немного легаси с 5.6, которое активно выпиливается и переводится на 7.1, плюс есть докер и большие планы на кибернетс. Мой личный совет - вали с этого говна с "заказчиком", иначе можешь там надолго завязнуть.
Ничего. Забудь их нахуй, и если кто-то их будет упоминать не в контексте шутки - шли его тоже нахуй. Для белых людей уже давно есть PDO.
>Я относительно недавно выкроил вемечко, чтобы обуздать некоторые свистоперделки седьмой пыхи
Ты уже должен был по дефолту на ней сидеть. Поддержка 5.6 заканчивается через полтора месяца, лол блять.
Бляха муха, почему всё так сложно? Вроде только разобрался в одном, тут оказывается что это нахуй не надо, надо пользоваться другим. Щас опять пол дня учить как это работает....
Не сложно. Просто процедурный стиль никому нахуй не нужен сейчас, а встроенный в PHP PDO реализует унифицированный интерфейс и из коробки поддерживает основные БД, а с доп модулями - вообще все.
PDO сейчас уже обязателен по дефолту. Функции типа mysql_* уже давно deprecated и в скором времени вообще будут из языка удалены.
Для новичка много чего - от prepared до транзакций (я в курсе, что они есть в SQL). Много чего на самом деле, интерфейс у пдо богатый.
По старому надо было сделать вот это:
while ($row = mysqli_fetch_array($result)) {
$publications[] = new NewsPublication;
}
как это сделать с помощью пдо?
Тебя в гугле забанили?
Достаточно ввести "pdo mysqli fetch array". А вообще. Забей хуй пока на код, иди и читай про ООП, про SQL и про PDO. Зачем ты сразу пытаешься использовать то, что даже не ебешь, как работает?
Ну а вобще, если я смогу делать 20к/мес, это будет просто рай. Считайте я живу с мамкой и папкой, буду въябывать на фрилансе...иии что еще нужно для счастья, если не надо стоять в пробках, общаться с мерзкими людьми в офисах и тому подобное? Это просто предел мечтаний, аноны
Но там ведь все на статических методах ... Хотя в Симфони тоже почему-то до сих пор не могут отказаться от хранения реквеста в контейнере. Трудно из программиста выбить привычку хранить все в глобальных переменных.
Хз, на первой работе 60 получал сначала. 20к мес - это смешно даже для погромца в мухосрани.
>Но там ведь все на статических методах
Что? Фасады - инжектятся, все остальное тоже инжектится, и никакой статики.
>Хотя в Симфони тоже почему-то до сих пор не могут отказаться от хранения реквеста в контейнере.
Не вижу ничего плохого, контейнеры юзаются не только в пыхе, но и в большинстве других языков.
Я про фриланс имею в виду. Мне много не надо....
Вот например два варианта кода в контроллере
if ($request->isValid()) {
...
return new Response($payload, 200);
} else {
return new Response($errors, 400);
}
или же
if ( !$request->isValid()) {
return new Response($errors, 400);
} ...elseif(...){}
else {
return new Response($payload, 200);
}
Есть ли вообще разница?
Нафига после ретурн ставить элс, сам подумой.
if (! $хрень1) {
return
}
if (! $хрень2) {
return
}
if (! $хрень3) {
return
}
А эта чем тебя не устраивает?
Возможно, мне хотелось бы, чтобы анон заценил и ткунл меня носом в говно. Так вот, где публиковать, что читать по этому поводу, есть ли вобще в этом смысл? Краем уха слышал про гитхаб.
Анимешник, го в телегу.
Дебильно и на русском языке
https://www.youtube.com/watch?v=Mg3iNP6miCE&list=PLpY_9m7gHQDhnuePAb3UN1XSih9kFXjG0
Если ты решаешь задачки ОПа, то я думаю стоит выкладывать свои поделки начиная со списка студентов.
Задачки опа я решил давно. С горем пополам правда. Теперь я делаю более практичные вещи, типо вывода нужных элементов из бд на страницу и всё такое.
Скорее всего он имел в виду задачки типа
https://github.com/codedokode/pasta/blob/master/student-list.md
Просто школодаун порвался от того, что ему сказали, что фотошоп - не программирование и решил уйти с чата, мол пока меня не кикнут (ато ему неприятно это слышать) он не вернется - всем было похуй, потом пришла его хохло-шлюха и как и подобает устроила майдан во имя этого ЧСВшного долбоеба.
Срач я вообще не начинал. Просто сказал, что дизайнер != программист и с хохлами не общаюсь. Остальное - бугурт обиженок
>конец 2018
>до сих пор не знать, что в конфах сидят либо какие-то мегауспешные охуенные челы (шанс 1%) либо долбоебы-вниманиебляди (шанс 99%)
хз. Большая пхпшная конфа состоит вроде из адекватов, которые как и положено погромистам предрасположены и устойчивы к хардкорным шутейкам
Каво? А это ты тот обучатель вкатывальщиков? Как там твоя занудная конфа толерантных геев поживает? Вкатываетесь друг в друга? Докер осилил или что ты там не мог обуздать?
>>293763 (Del)
Долбаеб, мы твой гитхаб посмотрели и поржали над твоими дополениями для битрикса. Долбаеб еще что-то там вякает про js...
Лол, но ведь я не работаю с битриксом.
А на гитхабе пара высеров, которым овер год. Среди которых нет битрикса, но зато есть пара годных ботов. Например бот рассылки сообщений по авито с интерфейсом, антикапчей, ЛК и пр. Сомневаюсь, что кто-то из вашей гомо конфы способен написать что-то подобное. Писал я это больше года назад и сейчас бы писал по другому, но что забавно, что меня пытался обоссывать 3х месячный вкатывалищик.
>Двач
>Прекратите флудить!
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
>Двач
>Прекратите флудить!
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
Ты какой-то ебанутый.
>Прекращайте флуд
Вся суть этих конф кстати.
Как только начинается какой-то спор, что нормально впринципе, особенно в тематических чатах, для того они и существуют. Так сразу админа рвет, что его гомосексуальное болото потревожили и блочит несогласных.
Нет, ты просто ебанашка обоссаная.
Конфы для того и нужны что они тематические, а ты пришел яйцами трясти и разводить срач.
мимо сторонний наблюдатель
>Заходишь в конфу PHP
>Начинаешь ныть, как же ты ненавидишь блядский JS, и что JS - это вообще не программирование
>Тебя просят пройти нахуй, ибо конфа про PHP
>Начинаешь агриться на хохла и нести хуйню про порошенко и хохлов в целом
>Получаешь бан
>РРРРРРРЯЯЯЯЯЯЯЯЯЯЯ АДМИН ПОДСОСЫ ГЕИ 3х МЕСЯЧНЫЕ ВКАТЫВАЛЬЩИКИ, БОЛОТО БЛОЧАТ НЕСОГЛАСНЫХ
Ты прям реально какой-то шизик, это уже даже не смешно.
ОП, пора делать перекот.
>Начинаешь ныть, как же ты ненавидишь блядский JS, и что JS - это вообще не программирование
Не говорил такого. Говорил, что фронтенд - это дизайнерство, где программирование используется для дизайнерства. Вообще про жс ничего не говорил толком.
>Тебя просят пройти нахуй, ибо конфа про PHP
Конфа про пхп, а мне начали рассказывать, что я не прав и хтмл - это программирование. А еще кинули 3д модельку и сказали глянь как красиво = программироание
>Начинаешь агриться на хохла и нести хуйню про порошенко и хохлов в целом
Долбоеб? Какол сагрился на меня, спусть пар часов после срача на вышеупомянутую тему, причем с ним я вообще не общался. На что я ответил, что с каклами не общаюсь - оно порвалось и начало пытаться фотожабить мою аву. Я с ним вообще не разговаривал кстати. Сразу сказал - общаться мы с тобой не будем, лол.
Пиздлявая ты макака
Твоя шизофрения прогрессирует, ты уже сам придумываешь прошлое и веришь в него, кажись. Жесть. Любой человек может зайти в конфу, пролистнуть историю и увидеть, что ты пиздишь. Не стыдно?
Так зайди и пролистни. Каково это жить в манямирке?
Нет, рано. Мы обычно еще несколько дней или недельку сидим в бамплимите. Треды тут тонут очень медленно, и много не провереных задач. Так что подождем.
Дочитай фразу, шизик.
Не 1000, а 10% от предыдущей суммы. Первый месяц - 1000р, потом - 1100р, 1210р, и т д
> Первый месяц - 1000р, потом - 1100р, 1210р, и т д
Какой нахуй первый месяц? Ты ёбаная жертва ммм и кэшбери!!! У тебя в условии 10% ГО ДО ВЫХ. Это в месяц менее 100₽, со второго года уже от 11к надо считать и так далее.
Ахахахха ну и галера. Оплата 300кк/пикосекунду два раза в месяц?
Не, програмирование - это не моё
>Че ж стек не написали?
>знание технологий веб-разработки на минимальном уровне и готовность пользоваться гуглом
Стэковерфлоу же.
Исправленное:
emails -https://ideone.com/QSOmHS
Grammar Nazi - https://ideone.com/kcqacc
Grammar Nazi Next - https://ideone.com/3wddIK
Над shift и опечаточником пока думаю.
Новое:
Yoda speak - https://ideone.com/RkU2vP
Числа прописью - https://ideone.com/pbxcf4
Аноны, поясните, пожалуйста, за регулярные выражения
Выражение такого вида:
if(preg_match("~Жепа~", "Жепа")){
echo "zbs";
}
Распечатает zbs, потому что прег матч вернет 1.
Но если я во второй аргумент подставлю Жепа123, то скрип тоже сработает. Как сделать, чтобы он не сработал?
>скрип тоже сработает
>Как сделать, чтобы он не сработал?
Ошибку сделай. Например вместо if напиши hui
Почитай про ^ и $. Регулярка по умолчанию не требует полного совпадения со строкой, достаточно, чтобы она совпадала с кусочком строки.
Есть один сайт, он высоконагруженный поэтому работает на нескольких серверах, балансировка через round-robin dns, то есть пользователь по сути попадает на случайный. База mysql, один мастер пара слейвов. Есть разные штуки которые хотелось бы кешировать в мемкеше, но проблема в том, что когда данные инвалидируются (например обновилась запись в базе) то кеш надо инвалидировать на всех серверах на которых они могли быть добавлены в мемкеш. Как в принципе решается эта проблема?
>, то есть пользователь по сути попадает на случайный. База mysql, один мастер пара слейвов. Есть разные штуки которые хотелось бы кешировать в мемкеше, но проблема в том, что когда данные инвалидируются (например обновилась запись в базе) то кеш надо инвалидировать на всех серверах на которых они могли быть добавлены в мемкеш. Как в принципе решается эта проблема?
много как ! желательно сеньером с опытом ;)
1. кластер мемкешей\редисов отдельный, куда конектятся "несколько серверов", так же все эти сервера могут быть соеденены в мастер-слейв мемкеш кластер ( да, такое практикуется )
2. избегать инвалидности. все сервера с кешем юзают апи, которое при обновлении данных в бд не просто обновляет кеш у себя на сервере, а так же делает все операции на удаленных серверах.
3. мемкеш пхпшный позволяет давать команду группе мемкеш серверов ( почитай доку ). бывают проблемы с проходимостью соединений, решается разными способами
4. сделать отложенное обновление кеша, когда спец тулза раз в минуту обновляет мемкеш везде. очень удобно когда обьем данных в мемкеше измеряется гигабайтами, и изменение одной записи ведет к длинным запросам и выгрузке большого куска данных
5. не юзать round robin, есть более удобные механизмы. определять принадлежность юзверя по куке к примеру, это умеют делать балансеры
6. возможно прокатит выгружать раз в 5 минут измененные данные в кеш с серва с бд. во многих случаях для пользователя не заметны 5-10 минут отставания кеша, более того, когда дело касается каких-либо "топов" или обьявлений, появляется некоторый рандом.
зы. если деления по гео нет - проблема с херовой архитектурой. но так часто бывает.
когда прожект начинает жить на 8-10 серверах каждый разраб начинает жалеть что не придерживается принципа модульности. одну жирную тушу тяжело сапортить, намного проще побить на сервисы типа чат, топ-10 и подобные, тяжелым дать выделенный сервер, легкие поселить на один сервер.
когда чат становится "жирной тушей" начинать делить его на более мелкие части и т.д.
>, то есть пользователь по сути попадает на случайный. База mysql, один мастер пара слейвов. Есть разные штуки которые хотелось бы кешировать в мемкеше, но проблема в том, что когда данные инвалидируются (например обновилась запись в базе) то кеш надо инвалидировать на всех серверах на которых они могли быть добавлены в мемкеш. Как в принципе решается эта проблема?
много как ! желательно сеньером с опытом ;)
1. кластер мемкешей\редисов отдельный, куда конектятся "несколько серверов", так же все эти сервера могут быть соеденены в мастер-слейв мемкеш кластер ( да, такое практикуется )
2. избегать инвалидности. все сервера с кешем юзают апи, которое при обновлении данных в бд не просто обновляет кеш у себя на сервере, а так же делает все операции на удаленных серверах.
3. мемкеш пхпшный позволяет давать команду группе мемкеш серверов ( почитай доку ). бывают проблемы с проходимостью соединений, решается разными способами
4. сделать отложенное обновление кеша, когда спец тулза раз в минуту обновляет мемкеш везде. очень удобно когда обьем данных в мемкеше измеряется гигабайтами, и изменение одной записи ведет к длинным запросам и выгрузке большого куска данных
5. не юзать round robin, есть более удобные механизмы. определять принадлежность юзверя по куке к примеру, это умеют делать балансеры
6. возможно прокатит выгружать раз в 5 минут измененные данные в кеш с серва с бд. во многих случаях для пользователя не заметны 5-10 минут отставания кеша, более того, когда дело касается каких-либо "топов" или обьявлений, появляется некоторый рандом.
зы. если деления по гео нет - проблема с херовой архитектурой. но так часто бывает.
когда прожект начинает жить на 8-10 серверах каждый разраб начинает жалеть что не придерживается принципа модульности. одну жирную тушу тяжело сапортить, намного проще побить на сервисы типа чат, топ-10 и подобные, тяжелым дать выделенный сервер, легкие поселить на один сервер.
когда чат становится "жирной тушей" начинать делить его на более мелкие части и т.д.
Спасибо за такой подробный ответ!
>много как ! желательно сеньером с опытом ;)
Ну, все сеньеры ведь когда-то учились и набирались опыта, вот и я.
> Есть разные штуки которые хотелось бы кешировать в мемкеше, но проблема в том, что когда данные инвалидируются (например обновилась запись в базе) то кеш надо инвалидировать на всех серверах на которых они могли быть добавлены в мемкеш.
Сделать один мемкеш-сервер, а не ставить на каждый сервер по копии. Это довольно бессмысленно. Если мощности 1 сервера не хватит, использовать шардинг по ключу (клиент выбирает сервер мемкеш в зависимости от ключа). Во многих клиентских библиотеках это встроено.
Алсо, я бы смотрел на редис - это как мемкеш, только с кучей наворотов.
> возможно прокатит выгружать раз в 5 минут измененные данные в кеш с серва с бд.
Я могу ошибаться, но полная перестройка кеша - может занимать значительно более 5 минут, если данных много, и запросы для их получения не быстрые.
> одну жирную тушу тяжело сапортить
Вообще, много микросервисов тоже тяжело поддерживать. Так как надо синхронно делать изменения в нескольких сервисах, синхронно их обновлять, итд. В случае, если где-то ошибки, искать их, прыгая между сервисами тоже тяжело.
Все конечно зависит от ситуации, но в моем понимании микросервисы - это скорее вынужденная мера, к которой прибегают, когда других вариантов нет. Если можно обойтись без них, то скорее всего жизнь будет проще. И для разработки не надо будет кучу гигабайт памяти для кучи докеров.
Если у тебя одна база, ты можешь сделать любой запрос и сджойнить любые данные (например, для аналитики). У тебя много микросервисов? Уже не можешь, придется городить какое-нибудь суперхранилище для аналитиков и решать кучу проблем, которых могло бы не быть с самого начала.
Если есть необходимость иметь данные в нескольких ДЦ далеко друг от друга - да, это непростая задача (пользователь может быть в одном регионе, а его данные - в другом, а данные его контактов - в третьем). Я даже не знаю, есть ли тут универсальное решение.
> намного проще побить на сервисы типа чат, топ-10 и подобные
Только проблему географической распределенности это не решает никак.
> emails -https://ideone.com/QSOmHS
Уже лучше, но тут есть небольшой подвох. Ты дампишь весь массив matches, и если в регулярке будут круглые скобки, то там будут кроме email еще попавшие в эти скобки куски email. Надо выделить из массива результатов только email.
> Grammar Nazi - https://ideone.com/kcqacc
Ок, но ты выводишь одно и то же предложение несколько раз. Можно его вывести один раз и показать все ошибки сразу?
Также, ты можешь захотеть почитать мануал по preg_replace.
> "/\s+(а|но)\s/ui"
После "но" может быть не только пробел, но и, например, запятая, и многоточие. Лучше использовать признак границы слова.
> Grammar Nazi Next - https://ideone.com/3wddIK
Та же проблема с "но".
> "/([.?!:,])\s+/u" => "$1 "
Это вставит пробелы в многоточие. А можно ли исправить это?
> Yoda speak - https://ideone.com/RkU2vP
Хорошо, но надо бы сделать первые буквы предложений заглавными.
> Числа прописью - https://ideone.com/pbxcf4
Для числа 999011012 выдает фигню: https://ideone.com/YtpKrI
Сделай более тщательное тестирование. Когда ты делаешь какую-то задачу, ты всегда сам должен ее внимательно протестировать, так как чем раньше обнаружится ошибка, тем дешевле и быстрее ее исправить. Вот подсказка, какие числа стоит брать: 0, 1, 2, 5, 9, 11, 12, 15, 19, 91, 92, 99 и еще добавить к ним сотни. Числа, где есть миллионы, но нет тысяч или единиц
> function word($number, $words)
Надо бы ставить тайп-хинты. Тайп хинты позволяют указать, что аргумент функции должен быть определенного типа (например быть строкой, массивом или целым небольшим числом). Тайп хинт делает код понятнее (так как видно, какого типа переменная) и надежнее (так как PHP не позволит передать что-то неразрешенное и ты сразу увидишь ошибку). Также он позволяет указать тип возвращаемого значения. Используй их везде.
Мануал: http://php.net/manual/ru/functions.arguments.php#functions.arguments.type-declaration
> if ($hundred != 0 && $hundred > 99) {
Первая часть условия бессмысленна.
> if ($tensAndUnits <= 20 && $tensAndUnits > 9)
Лучше переставить условия местами для читаемости. Сначала 9, потом 20
> $resultExp .= " " . $numbers[$hundred];
Можно еще складывать слова в массив, а в конце функции его склеить. ТОгда не надо возиться с удалением лишних пробелов.
> $i = strlen((string)$number);//Считаем количество цифр
Костыльно. Почему бы тебе не воспользоваться функцией десятичного логарифма log10? Для log10(1) = 0, log10(10) = 2, log10(100) = 3 итд.
Твой костыль довольно уязвим. Например, если ему дать число 1.1, он сделает ошибку, то же самое для очень большого числа вроде 1000000000000000000000 (оно отформатируется как 1e20). Не стоит работать с числом как со строкой.
> $threeDigits = intval(floor($number / pow(10, $i - 3)));//Получаем первые 3 цифры
> $firstTwoDigit = intval(floor($number / pow(10, $i - 2)));//Получаем первые 2 цифры
Можно без этой унылой копипасты одинаковых кусков кода?
> $resultExp = preg_replace("/один\sтысяча/u", "одна тысяча", $resultExp);
Костыльно. Давай лучше с самого начала генерировать правильную форму слов.
> emails -https://ideone.com/QSOmHS
Уже лучше, но тут есть небольшой подвох. Ты дампишь весь массив matches, и если в регулярке будут круглые скобки, то там будут кроме email еще попавшие в эти скобки куски email. Надо выделить из массива результатов только email.
> Grammar Nazi - https://ideone.com/kcqacc
Ок, но ты выводишь одно и то же предложение несколько раз. Можно его вывести один раз и показать все ошибки сразу?
Также, ты можешь захотеть почитать мануал по preg_replace.
> "/\s+(а|но)\s/ui"
После "но" может быть не только пробел, но и, например, запятая, и многоточие. Лучше использовать признак границы слова.
> Grammar Nazi Next - https://ideone.com/3wddIK
Та же проблема с "но".
> "/([.?!:,])\s+/u" => "$1 "
Это вставит пробелы в многоточие. А можно ли исправить это?
> Yoda speak - https://ideone.com/RkU2vP
Хорошо, но надо бы сделать первые буквы предложений заглавными.
> Числа прописью - https://ideone.com/pbxcf4
Для числа 999011012 выдает фигню: https://ideone.com/YtpKrI
Сделай более тщательное тестирование. Когда ты делаешь какую-то задачу, ты всегда сам должен ее внимательно протестировать, так как чем раньше обнаружится ошибка, тем дешевле и быстрее ее исправить. Вот подсказка, какие числа стоит брать: 0, 1, 2, 5, 9, 11, 12, 15, 19, 91, 92, 99 и еще добавить к ним сотни. Числа, где есть миллионы, но нет тысяч или единиц
> function word($number, $words)
Надо бы ставить тайп-хинты. Тайп хинты позволяют указать, что аргумент функции должен быть определенного типа (например быть строкой, массивом или целым небольшим числом). Тайп хинт делает код понятнее (так как видно, какого типа переменная) и надежнее (так как PHP не позволит передать что-то неразрешенное и ты сразу увидишь ошибку). Также он позволяет указать тип возвращаемого значения. Используй их везде.
Мануал: http://php.net/manual/ru/functions.arguments.php#functions.arguments.type-declaration
> if ($hundred != 0 && $hundred > 99) {
Первая часть условия бессмысленна.
> if ($tensAndUnits <= 20 && $tensAndUnits > 9)
Лучше переставить условия местами для читаемости. Сначала 9, потом 20
> $resultExp .= " " . $numbers[$hundred];
Можно еще складывать слова в массив, а в конце функции его склеить. ТОгда не надо возиться с удалением лишних пробелов.
> $i = strlen((string)$number);//Считаем количество цифр
Костыльно. Почему бы тебе не воспользоваться функцией десятичного логарифма log10? Для log10(1) = 0, log10(10) = 2, log10(100) = 3 итд.
Твой костыль довольно уязвим. Например, если ему дать число 1.1, он сделает ошибку, то же самое для очень большого числа вроде 1000000000000000000000 (оно отформатируется как 1e20). Не стоит работать с числом как со строкой.
> $threeDigits = intval(floor($number / pow(10, $i - 3)));//Получаем первые 3 цифры
> $firstTwoDigit = intval(floor($number / pow(10, $i - 2)));//Получаем первые 2 цифры
Можно без этой унылой копипасты одинаковых кусков кода?
> $resultExp = preg_replace("/один\sтысяча/u", "одна тысяча", $resultExp);
Костыльно. Давай лучше с самого начала генерировать правильную форму слов.
Исправил:
Числа прописью - https://ideone.com/yhrxPg
Yoda speak - https://ideone.com/HM3Xci (3 пик)
Grammar Nazi - https://ideone.com/V1k3eX
Grammar Nazi Next - https://ideone.com/QaRhUG
Опечаточник - https://ideone.com/JTJWb7
Вопрос: проверял Числа прописью и ввёл число 5909123000, когда хотел получить остаток вместо 909123000 возвращается 614155704. Почему? Я погуглил и PHP_INT_MAX у меня 2млрд, что больше, чем 909 млн? так что не должны же последние биты убираться или что там в подобных случаях делает яп.
По поводу GN: в одну строчку можно было, но там получается бардак, и я пока не смог догадаться не до чего лучше, чем по разному обозначать разные ошибки. Плюс ко всему, некоторые правила срабатывают на новые вставки в текст, пик 2
Закрывающая скобка, идущая обработчику пхп. Скорее всего в файле перемешана логика и отображение, что плохо.
Зачем ставить, когда можно напиздеть? Всегда говорю что у меня мак дома. Никто же не прийдёт ко мне домой и не проверит. Или как ты себе представляешь? Пойдёт HR проверять к тебе что такм у тебя стоит, и если линукса нет - прямо на месте обссыт?
Спасибо.
>но напиздеть? Всегда говорю что у меня мак дома. Никто же не прийдёт ко мне домой и не проверит. Или как ты себе представляешь? Пойдёт HR проверять к тебе что такм у тебя стоит, и если линукса нет - прямо на месте обссыт?
ахахаха, тебе сука дадут мак и посмотрят как ты там lamp настроишь. а после того как ты будешь делать это в течении 2-5 дней с мануалом под рукою, обоссут и выгонят ссаными тряпками.
пиздаболов дохуя, айчар не спалит, а твои коллеги по галере быстро стуканут, нахуй им на галере такой гребец
> lamp
> в конторе занимающейся кодингом
> lamp
> Настраивать 4 дня, когда он ставится за 2 клика
Ты ебанутый? Во первых никто на производстве ламп не юзает (ну разьве что ИП Ероха). Во вторых - мак от винды отличается только парой консольных команд. Ну и утилиты там другие - да. Но по сути VScode и там и там. Gitbach пульный, утилиты тестирования - вообще считай клоны.
*за мат извени
гуггления приводили на разные фреймворки , первый из которых silex я изучал дня 2 пока не вкурил, что он не поддерживается уже год.. потом был pyrocms.com...на гитхабах во всех репозиториях комментарии по getting started в стиле ультра-минимализм. Забивают поиск своим не упершимся в хуй гениальными Rock высерами.
Вот это чудо у кого нибудь получилось оживить https://github.com/formers/former ? - а рейтинг зашкаливает у чувака. У этой Cупер-Хуйни - pyrocms.com половина страниц в демо: 500. Или может я совсем необучаемое быдло. Просто интересно фреймворки кому-нибудь реально облегчали жизнь?
>очередная макака
Исходя из твоего вопроса, ты еще не макака даже, а так.
>php5 или php7?
5.6 еще актуален и какое-то время останется, тк много на нём написано говна, которое требует поддержки, доработки.
ПРИНЦИПИАЛЬНОЙ разницы нет, особенно для новичка. Основные конструкции ничем не отличаются.
Главная фишка пхп 7 это производительность, которая взлетела чуть ли не в два раза, всё остальное это улучшение ооп, новые операторы типа <=>, типизация.
Приобрел свой бесплатный хостинг, учусь по видеоурокам. Там сказали не запариваться по поводу настройки веб сервера и настроить .htaccsess как сказал он. Вот настройки:
RewriteEngine On
RewriteBase /MVC/ /у меня много папок на хостинге, конкретно в этой я учусть делать mvc/
RewriteCond %(REQUEST_FILENAME) !-f
RewriteCond %(REQUEST_FILENAME) !-d
RewriteRule ^(.*)$ index.php
Все ок, все работает, кроме того, что не подгружаются стили. В чем может быть проблема?
Пишет не удалось загрузить таблицу стилей hostname.com/MVC/templates/default.css
Заработало! Я нахуевертил с путями.
Значит костылик запилили .. временный.. Потому как я читал июньские посты нескольких людей что ВСЕ
Как установить вот эту приблуду https://github.com/anomalylabs/button_block-extension в свой проект?
Без Ларавеля она не заработает же..
Я тоже нуб, промудохался с фреймворками и решил пока это поизучать
https://github.com/bradtraversy/php_rest_myblog
Чо это такое, зочем нужно?
В проекте используется подход с конвертацией времени в UTC на стороне Doctrine: https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/cookbook/working-with-datetime.html#handling-different-timezones-with-the-datetime-type
Проблемы начинаются тогда, когда нужно группировать данные по дате. Данные в БД сконвертированы в UTC, но пользователю нужно показать данные, сгруппированые с учётом его таймзоны. Использовать функцию convert_tz у MySQL? В таких приложениях нужно ли просить пользователя указывать свою таймзону где-то у себя в настройках или нам, как разработчикам, нужно самим угадывать его таймзону? Какие вообще стандартные практики при разработке приложений, которыми будут пользоваться люди с разными таймзонами? Было бы круто, если бы ОП добавил урок на эту тему в репозиторий на гитхабе.
А зачем в кавычках?
Зачем платить за курсы, если нет свободных денег?
Да и тем более, большинство информации есть в свободном доступе, просто на курсах все удобно распределено, ну или типа того
Все равно придется самому писать многие вещи и все самому постигать
https://nnm-club.me тут можешь чекнуть курсы, не только от лофтскул
Удачи
https://ru.hexlet.io/?ref=104929
рефссылочка.
Отзывы найдешь в интернете.
Самый адекватный ресурс.
Только начал изучать, у ОПа в учебнике задача с айфоном. Вопрос: можно ли делать, так как у меня? Всё вроде сходиться, по всем примерам. И да, я не заморачивался с переменными, как у ОПа, а просто наебашил матьимачехи.
Влетел ещё с одним, долго голову ломал, всё так?
>>296086
> for ($i=0;$i<9;$i++) {
> $massivWord = $allWords[$i];
Для перебора массива лучше использовать foreach, а то у тебя при изменении списка слов надо считать его длину вручную. А "\n" можно было точно так же вставить в массив.
> echo "$poem";
Кавычки тут не нужны: echo $poem; В кавычки помещается текст (можно с переменными), а если у нас одна переменная, то ей кавычки не нужны.
>>296030
> (($credit/100)3);
Проценты лучше вынести в переменную. Во-первых, будет по названию понятно, что это за число, во-вторых, менять будет проще.
> $realPrice=$realPrice+1000+(($credit/100)3);
> $credit=$credit+1000+(($credit/100)*3);
Тут почти копипаста. Общую часть стоит вынести в отдельную переменную.
> И да, я не заморачивался с переменными
Менять числа неудобно, и непонятно, что они значат.
>>295872
> Данные в БД сконвертированы в UTC, но пользователю нужно показать данные, сгруппированые с учётом его таймзоны.
Да, придется преобразовывать дату в запросе. Стоит глянуть, не повредит ли это производительности запроса.
> В таких приложениях нужно ли просить пользователя указывать свою таймзону где-то у себя в настройках или нам, как разработчикам, нужно самим угадывать его таймзону?
Определять надо часовую зону на компьютере пользователя, конечно, автоматически. Давать менять можно, но я не вижу особого смысла - разница времени на сайте и на компьютере будет скорее сбивать с толку.
Также, желательно писать, в каком часовом поясе время. Ну и протестировать все это тщательно.
Насчет определения. В HTTP-заголовках эта информация не передается. Определить смещение от UTC (на компьютере пользователя) можно кодом на JS (и сохранить в куку), но при первой загрузке страницы время еще неизвестно и потому можно угадывать его по GeoIP.
>>296086
> for ($i=0;$i<9;$i++) {
> $massivWord = $allWords[$i];
Для перебора массива лучше использовать foreach, а то у тебя при изменении списка слов надо считать его длину вручную. А "\n" можно было точно так же вставить в массив.
> echo "$poem";
Кавычки тут не нужны: echo $poem; В кавычки помещается текст (можно с переменными), а если у нас одна переменная, то ей кавычки не нужны.
>>296030
> (($credit/100)3);
Проценты лучше вынести в переменную. Во-первых, будет по названию понятно, что это за число, во-вторых, менять будет проще.
> $realPrice=$realPrice+1000+(($credit/100)3);
> $credit=$credit+1000+(($credit/100)*3);
Тут почти копипаста. Общую часть стоит вынести в отдельную переменную.
> И да, я не заморачивался с переменными
Менять числа неудобно, и непонятно, что они значат.
>>295872
> Данные в БД сконвертированы в UTC, но пользователю нужно показать данные, сгруппированые с учётом его таймзоны.
Да, придется преобразовывать дату в запросе. Стоит глянуть, не повредит ли это производительности запроса.
> В таких приложениях нужно ли просить пользователя указывать свою таймзону где-то у себя в настройках или нам, как разработчикам, нужно самим угадывать его таймзону?
Определять надо часовую зону на компьютере пользователя, конечно, автоматически. Давать менять можно, но я не вижу особого смысла - разница времени на сайте и на компьютере будет скорее сбивать с толку.
Также, желательно писать, в каком часовом поясе время. Ну и протестировать все это тщательно.
Насчет определения. В HTTP-заголовках эта информация не передается. Определить смещение от UTC (на компьютере пользователя) можно кодом на JS (и сохранить в куку), но при первой загрузке страницы время еще неизвестно и потому можно угадывать его по GeoIP.
Обрати внимание, что там есть проблемы:
- в начале каждого контроллера иет копипаста, выставляющая хедеры: header('Access-Control-Allow-Origin: *'); ...
- кстати, изучи, что каждый из них делает, не копируй бездумно
- здесь нет проверки на ошибку декодинга JSON: $data = json_decode(file_get_contents("php://input")); Надо проверять, что в $data не null.
- при ошибке удаления это сообщается текстовым сообщением. Но это неудобно проверять программно тому, кто вызвал API. Надо при ошибке как-то сигнализировать, например, HTTP-кодом ошибки или менять вид JSON на {"error": "Cannot delete"}
Также, изучи основы HTTP (у меня тут есть урок https://github.com/codedokode/pasta/ ). Ну и если ты делаешь REST API, изучи, что это такое.
> $this->id = htmlspecialchars(strip_tags($this->id));
Это бессмысленный набор функций. Автор не знает, как правильно обрабатывать данные от пользователя и сует все функции, про которые слышал.
> public function __construct($db) {
Тут не хватает тайп-хинта
Весь код выложен в публично доступную папку. Надо бы его переделать, чтобы доступны снаружи были только контроллеры в /api/, а не все. Так безопаснее.
> // Print error if something goes wrong
> printf("Error: $s.\n", $stmt->error);
Это непраивльно. При ошибке автор выводит сообщение в HTTP-ответ. То есть приложение, которое будет отправлять запрос к этому API, увидит это сообщение. Но оно ведь не обладает интеллектом и прочесть его не может. А разработчик, наоборот об ошибке не узнает.
Это надо переделать. Ошибки должны писаться в лог, а в HTTP-ответе надо отдавать код ошибки 5xx.
Также, API не документировано. Я советую изучить Swagger и документировать с его помощью.
> // Get Single Post
> public function read_single() {
...
> $stmt->bindParam(1, $this->id);
Сделано дебильно. Почему нельзя передавать id прямо в функцию как аргумент? Зачем вместо очевидного варианта сделана передача через поле? Я скажу, почему. Автор не знает ООП, но пытается изображать ООП-код.
В общем, я бы тебе советовал решить сначала нашу задачу про список студентов. Там есть подробные комментарии, и такие ошибки, как у автора, ты не допустишь.
Также, ты можешь, используя комментарии из задачи про студентов, сделать блог сам - только правильно.
Обрати внимание, что там есть проблемы:
- в начале каждого контроллера иет копипаста, выставляющая хедеры: header('Access-Control-Allow-Origin: *'); ...
- кстати, изучи, что каждый из них делает, не копируй бездумно
- здесь нет проверки на ошибку декодинга JSON: $data = json_decode(file_get_contents("php://input")); Надо проверять, что в $data не null.
- при ошибке удаления это сообщается текстовым сообщением. Но это неудобно проверять программно тому, кто вызвал API. Надо при ошибке как-то сигнализировать, например, HTTP-кодом ошибки или менять вид JSON на {"error": "Cannot delete"}
Также, изучи основы HTTP (у меня тут есть урок https://github.com/codedokode/pasta/ ). Ну и если ты делаешь REST API, изучи, что это такое.
> $this->id = htmlspecialchars(strip_tags($this->id));
Это бессмысленный набор функций. Автор не знает, как правильно обрабатывать данные от пользователя и сует все функции, про которые слышал.
> public function __construct($db) {
Тут не хватает тайп-хинта
Весь код выложен в публично доступную папку. Надо бы его переделать, чтобы доступны снаружи были только контроллеры в /api/, а не все. Так безопаснее.
> // Print error if something goes wrong
> printf("Error: $s.\n", $stmt->error);
Это непраивльно. При ошибке автор выводит сообщение в HTTP-ответ. То есть приложение, которое будет отправлять запрос к этому API, увидит это сообщение. Но оно ведь не обладает интеллектом и прочесть его не может. А разработчик, наоборот об ошибке не узнает.
Это надо переделать. Ошибки должны писаться в лог, а в HTTP-ответе надо отдавать код ошибки 5xx.
Также, API не документировано. Я советую изучить Swagger и документировать с его помощью.
> // Get Single Post
> public function read_single() {
...
> $stmt->bindParam(1, $this->id);
Сделано дебильно. Почему нельзя передавать id прямо в функцию как аргумент? Зачем вместо очевидного варианта сделана передача через поле? Я скажу, почему. Автор не знает ООП, но пытается изображать ООП-код.
В общем, я бы тебе советовал решить сначала нашу задачу про список студентов. Там есть подробные комментарии, и такие ошибки, как у автора, ты не допустишь.
Также, ты можешь, используя комментарии из задачи про студентов, сделать блог сам - только правильно.
Используй PHP7 (зачем старье использовать?), но прочти любую статью про отличия PHP7 от PHP5.
>>295691
> первый из которых silex я изучал дня 2 пока не вкурил, что он не поддерживается уже год
Есть Slim, тоже микрофреймворк.
> Просто интересно фреймворки кому-нибудь реально облегчали жизнь?
Ну все последние проекты, на которых я работал, были на фреймворках. Очевидно, использование готового кода экономит время на разработку. А также позволяет новым разработчикам быстрее понять проект.
Если тебе сложно даются фреймворки, это может быть из-за слабого знания теории. Надо знать ООП, MVC, DI, паттерны работы с БД, шаблонизацию. Пользоваться композером. Ну и читать документацию, а не только уроки Getting started. Если у тебя есть пробелы, то тут есть уроки по этим темам: https://github.com/codedokode/pasta/
>>294952
> Числа прописью - https://ideone.com/yhrxPg
> (int $number = 0, array $words)
Значения по умолчанию помещают в конец списка, иначе это мало смысла имеет (тебе все равно придется указывать $number).
> function word(int $number = 0, array $words)
У функций можно указывать тип возвращаемого значения: function something(): string { ... }
> function digitsToWords(int $number, array $numbers, bool $isFemale){
Не очень логично, что тут передается $numbers. Разве нам понадобится когда-то менять написание цифр? Если нет, то незачем их и передавать, пусть они будут заданы в этой или другой функции.
Код в конце программы тоже стоило завернуть в функцию.
> $i = intval(log10(abs($number))) + 1;//Количество цифр = log10(n) + 1;
Можно было вынести это в отдельную функцию для определения количества цифр в числе.
> $threeDigits = getDigits($number, $i - 3);
> $number = getRemainder($number, $i - 3);
> $resultExp[] = digitsToWords($threeDigits, $numbers, $isFemale);
> $resultExp[] = word($threeDigits, $denomination);
А это нельзя поместить в цикл из 3 шагов, а не копировать 3 раза?
> Я погуглил и PHP_INT_MAX у меня 2млрд, что больше, чем 909 млн?
В PHP есть 2 типа чисел: int и float. Int для целых небольших чисел, float - дял любых, но у него ограничена точность (~8 значащих цифр в 32-битной версии и ~15 в 64-битной). При выходе за пределы int PHP автоматически конвертирует число в float.
Число 5 млрд в 32-битной версии будет сохранено как float, в чем легко убедиться:
echo PHP_INT_MAX ."\n";
echo 5909123001;
echo "\n";
Я сделал похожий код, но удлинил число для 64-битной версии: https://repl.it/repls/BriskVerticalMetadata
Как видишь, девятки округлились при преобразовании в float.
При этом, конечно, 900 млн в 600 млн превратиться не могут - теряются только цифры в конце числа.Дай маленький пример кода, в котором происходит ошибка, и попробуем разобраться (я пробовал подставить 5 млрд на ideone, и там все работает).
Проблема, впрочем, может быть вот тут: $number % pow(10, $i)
Оператор % может работать только с int, и если ему дать число, которое нельзя преобразовать в int, его начинает корежить (по-хорошему, он должен выдавать ошибку, а не портить числа). Ты можешь проверить, попробовав поделить с помощью % большие числа (проверь).
Есть даже баг-репорты по этому поводу: https://www.google.com/search?q=site:bugs.php.net+php+modulо+with+float+&btnG=Поиск
По моему мнению, тут конечно должен выдаваться хотя бы варнинг. Нельзя молча по-тихому корежить числа.
Если ты хочешь аналог % для float, то это fmod(). Но в данной задаче float не годится - нам нужно точное число, а не примерная сумма денег на счету. Для денег вообще не стоит использовать float.
Если ты хочешь работать с числами, которые больше предела int, то надо отказаться от обычных операций и использовать расширение PHP для больших чисел:
- http://php.net/manual/ru/ref.bc.php
- http://php.net/manual/ru/book.gmp.php
(внезапно, мы вернулись к представлению чисел в виде строк).
> Yoda speak - https://ideone.com/HM3Xci (3 пик)
Ок, верно.
Grammar Nazi - https://ideone.com/V1k3eX
> "/(\s+(а|но))[\s,.:?!]/ui"
Здесь можно было использовать \b для определения границы слова, но так тоже можно.
> "[$1]",
Точно не $0 ?
Так, в остальном верно.
Grammar Nazi Next - https://ideone.com/QaRhUG
> "/[,]?\s+(но)/ui" => ", $1",
Здесь он поставит запятую перед "ночь".
В остальном верно.
Опечаточник - https://ideone.com/JTJWb7
Ок, неплохо, но регулярки лучше было не передавать в функцию, а вставить в нее. Так как вряд ли эта функция будет вызываться с другими регулярками.
Используй PHP7 (зачем старье использовать?), но прочти любую статью про отличия PHP7 от PHP5.
>>295691
> первый из которых silex я изучал дня 2 пока не вкурил, что он не поддерживается уже год
Есть Slim, тоже микрофреймворк.
> Просто интересно фреймворки кому-нибудь реально облегчали жизнь?
Ну все последние проекты, на которых я работал, были на фреймворках. Очевидно, использование готового кода экономит время на разработку. А также позволяет новым разработчикам быстрее понять проект.
Если тебе сложно даются фреймворки, это может быть из-за слабого знания теории. Надо знать ООП, MVC, DI, паттерны работы с БД, шаблонизацию. Пользоваться композером. Ну и читать документацию, а не только уроки Getting started. Если у тебя есть пробелы, то тут есть уроки по этим темам: https://github.com/codedokode/pasta/
>>294952
> Числа прописью - https://ideone.com/yhrxPg
> (int $number = 0, array $words)
Значения по умолчанию помещают в конец списка, иначе это мало смысла имеет (тебе все равно придется указывать $number).
> function word(int $number = 0, array $words)
У функций можно указывать тип возвращаемого значения: function something(): string { ... }
> function digitsToWords(int $number, array $numbers, bool $isFemale){
Не очень логично, что тут передается $numbers. Разве нам понадобится когда-то менять написание цифр? Если нет, то незачем их и передавать, пусть они будут заданы в этой или другой функции.
Код в конце программы тоже стоило завернуть в функцию.
> $i = intval(log10(abs($number))) + 1;//Количество цифр = log10(n) + 1;
Можно было вынести это в отдельную функцию для определения количества цифр в числе.
> $threeDigits = getDigits($number, $i - 3);
> $number = getRemainder($number, $i - 3);
> $resultExp[] = digitsToWords($threeDigits, $numbers, $isFemale);
> $resultExp[] = word($threeDigits, $denomination);
А это нельзя поместить в цикл из 3 шагов, а не копировать 3 раза?
> Я погуглил и PHP_INT_MAX у меня 2млрд, что больше, чем 909 млн?
В PHP есть 2 типа чисел: int и float. Int для целых небольших чисел, float - дял любых, но у него ограничена точность (~8 значащих цифр в 32-битной версии и ~15 в 64-битной). При выходе за пределы int PHP автоматически конвертирует число в float.
Число 5 млрд в 32-битной версии будет сохранено как float, в чем легко убедиться:
echo PHP_INT_MAX ."\n";
echo 5909123001;
echo "\n";
Я сделал похожий код, но удлинил число для 64-битной версии: https://repl.it/repls/BriskVerticalMetadata
Как видишь, девятки округлились при преобразовании в float.
При этом, конечно, 900 млн в 600 млн превратиться не могут - теряются только цифры в конце числа.Дай маленький пример кода, в котором происходит ошибка, и попробуем разобраться (я пробовал подставить 5 млрд на ideone, и там все работает).
Проблема, впрочем, может быть вот тут: $number % pow(10, $i)
Оператор % может работать только с int, и если ему дать число, которое нельзя преобразовать в int, его начинает корежить (по-хорошему, он должен выдавать ошибку, а не портить числа). Ты можешь проверить, попробовав поделить с помощью % большие числа (проверь).
Есть даже баг-репорты по этому поводу: https://www.google.com/search?q=site:bugs.php.net+php+modulо+with+float+&btnG=Поиск
По моему мнению, тут конечно должен выдаваться хотя бы варнинг. Нельзя молча по-тихому корежить числа.
Если ты хочешь аналог % для float, то это fmod(). Но в данной задаче float не годится - нам нужно точное число, а не примерная сумма денег на счету. Для денег вообще не стоит использовать float.
Если ты хочешь работать с числами, которые больше предела int, то надо отказаться от обычных операций и использовать расширение PHP для больших чисел:
- http://php.net/manual/ru/ref.bc.php
- http://php.net/manual/ru/book.gmp.php
(внезапно, мы вернулись к представлению чисел в виде строк).
> Yoda speak - https://ideone.com/HM3Xci (3 пик)
Ок, верно.
Grammar Nazi - https://ideone.com/V1k3eX
> "/(\s+(а|но))[\s,.:?!]/ui"
Здесь можно было использовать \b для определения границы слова, но так тоже можно.
> "[$1]",
Точно не $0 ?
Так, в остальном верно.
Grammar Nazi Next - https://ideone.com/QaRhUG
> "/[,]?\s+(но)/ui" => ", $1",
Здесь он поставит запятую перед "ночь".
В остальном верно.
Опечаточник - https://ideone.com/JTJWb7
Ок, неплохо, но регулярки лучше было не передавать в функцию, а вставить в нее. Так как вряд ли эта функция будет вызываться с другими регулярками.
Получилось как то так. https://ideone.com/fG6dOx
Кажется что я обосрался и посчитать все не в теле цикла, а в условии, или нет?
И еще не понял как выводить в эчо обычную строку и переменную приведенную в тип интеджер в одних кавычках, не юзая точку
Как оказалось, работать с ним без серверного языка можно только с того же домена, на котором ты и исполняешь скрипт, то есть чтобы JS получил данные с внешнего домена, нужно чтобы на этом домене было прописано разрешение в заголовке для таких работ, но хуй там. Все костыли что я опробовал не работают, все выдают No 'Access-Control-Allow-Origin' header is present on the requested resource.
И тут меня осенило, я же могу не ебаться с серверами и их арендой, а запустить сервер прямо у себя на пекарне и с помощью животворящего PHP сделать проксирование всего этого дерьма, отсюда вопрос, как это сделать?
Знаю что для начала мне нужно будет прописать в самом коде <?php header('Access-Control-Allow-Origin: *'); ?> чтобы таки разрешить к нему доступ из вне, теперь я не пойму как организовать проксирование.
Например ссылка на API http://site.ru/api.json?token=224&user=1488 я создаю на локальном сервере файл proxy.php и обращаюсь к нему с нужного мне сайта из JavaScript с помощью XMLHttpRequest() например так http://localhost/proxy.php?token=224&user=1488 и он возвращает мне JSON с выше указанного API, подскажите пожалуйста как такой костыль реализовать, это у меня будет как-бы такой локальный JavaScript помощник для парсинга APIда благословит вас аллах
Ну или подскажите как таки наебать ограничение Cross-Origin Read Blocking (CORB) в браузере
> Да, придется преобразовывать дату в запросе. Стоит глянуть, не повредит ли это производительности запроса.
Используется MySQL, на индексы такую группировку c конвертацией таймзоны можно положить? Слышал, что в PostgreSQL есть функциональные индексы, помогут ли они в этой ситуации?
https://ideone.com/phlsVk
Господи, какой же я мудак, всё нашёл, невнимательно пример с выводом функции прочитал, думал она может работать так, как у меня.
Если ты можешь установить PHP, не проще ли написать программу на нем и запустить ее из командной строки? Там она может работать хоть годами, при условии что ты не выключишь компьютер.
При этом никаких ограничений, которые есть в браузере, не будет.
Ты по моему переусложняешь все.
Ну и другой вариант - если ты знаешь JS, ты можешь установить Node.js и запустить JS-скрипт в консоли, без браузера и HTML. И он там тоже может работать хоть годами.
А, еще третий вариант. Ты можешь отключить в браузере проверку этих заголовков - это делается по-разному для разных браузеров. И тогда твой код сможет слать запросы куда угодно.
>5.6 еще актуален и какое-то время останется
Он актуален останется только у долбаебов. Через месяц с хуем заканчивается его поддержка.
не учи долбоебов, еще не хватало чтобы появились на виндах какие пхп скрипты запускающиеся из консоли. брр
>>296453
девочка моя, мне временами попадаются переходные варианты кода работающего на продакшне и там ацкая смесь 4 и 5й версии. проекты более чем успешные и работают, а если работают - не трогай. допиши че просят и оставь. ебланов которые хотят сразу переписать все на 7ку ( 5.4, 5.5, 5.6 ) обычно шлют нахуй, это показатель отсутствия скила
>>296437
Такая ситуация, нужно именно из браузера находясь на любом сайте с помощью JavaScript парсить содержимое json на другом сайте и добавлять его в нужные места на том сайте на котором я нахожусь в данный момент, от сюда и пришло в голову из-за ограничений
в браузерах создать PHP скрипт который бы проксировал все эти запросы и пропуская через себя отдавал с локалхоста в браузер, а благодаря строчке <?php header('Access-Control-Allow-Origin: *'); ?> браузер уже не будет возникать, так понятно? Просто я хуй знает что писать в этом php файле для подобной задачи
Подскажите гуру php, как можно убрать нахуй этот preg_replace и сделать задачку через регулярку? Ответственно заявляю, я парень упёртый и ебался N-ое кол-во часов(что бы не насмехались не буду говорить сколько), но так и смог правильно настроить $regexp.
Хз, если объекту не нужна какая-то инициализация, то можно в принципе. С другой стороны если пишешь на статиках, то фактически не пользуешься ООП и долбишь функциональщиной. Все же ООП это не только и не столько классы, как подход к разработке.
Я иногда конфиг в статик загоняю - удобно.
> ебланов которые хотят сразу переписать все на 7ку ( 5.4, 5.5, 5.6 ) обычно шлют нахуй, это показатель отсутствия скила
Что за ерунду ты несёшь? Желание обновится с 5-го PHP на 7-й абсолютно логично как минимум потому, что для PHP 5 скоро перестанут даже security fix'ы выпускать, молчу про улучшение производительности. Если у вас настолько хрупкая система без CI и тестов, где каждый боится лишний раз код поправить, руководствуясь принципом "работает - не трогай", говорит лишь о вашем непрофессионализме. Либо у вас настолько простая система, где не нужны ни тесты, ни зависимости с composer, ведь они тоже обновляются и редкий пакет будет работать с PHP 5.4<. А если не обновлять - опять дыры в безопасности.
Иногда просто удобно сгруппировать функционал в один класс, если там одного типа функции. Но везде лепить такое не стоит - точно обоссут.
function huy (): MyObject[] {}
Эххх, почему пхп такой конченый...
Во всяких ArrayAccess и SplObjectStorage охуилярд пизданутых подводных багов, которыми пестрят комменты на офф-сайте.
Что за язык блять, ни структур данных, нихуя...
Вот что бывает, когда языки, создававшиеся дурачками для лулзов внезапно становятся основой индустрии. Жабаскрипт в то же болото
>>296556
Это хуево, на самом деле.
Скажу больше - практически никогда не следует использовать статические методы.
Максимум - как дополнительный конструктор.
Статический метод - неявная инъекция зависимости, что приводит к связности кода.
Надо все на объектах хуярить, даже если экземпляр класса будет вообще 1, все равно.
>изучать php5
>шел 2018-й год, все обсуждали смерть пхп как такового
>изучу-ка я засохшее говно мамонта
Еще бы кобол учил
>девочка моя, мне временами попадаются переходные варианты кода работающего на продакшне и там ацкая смесь 4 и 5й версии.
А кто виноват, что ты работаешь в веб студии/на индусском фрилансе/битриксе? У нас обновление версии - это не событие, а стандартная процедура. На легаси 5.6 сейчас осталось очень мало кода, который активно апдейтится.
>ебланов которые хотят сразу переписать все на 7ку ( 5.4, 5.5, 5.6 ) обычно шлют нахуй, это показатель отсутствия скила
Ну да. Лучше остаться на полностью abandoned версии без security fix'ов, без поддержки с хуем во рту. Чем спокойно и без проблем обновиться на более позднюю. Мы сейчас не в 2004, обновление происходит максимально просто и безболезненно, если ты изначально не писал быдлокод.
Чтобы я мог писать конструкции вида HashMap<Vector<String>, double>?
Или так и будем до 2050 на array хуярить?
Короче да. Если интерфейс не содержит объявления возвращаемого типа, дочерний метод может возвращать что хочет.
(А не необъявленное любое значение, как у интерфейса)
это твое желание - обновится. кода может быть много ( 2-3 мб).
ты прикинь, приглашаешь электрика розетку починить, а он тебе говорит - хозяин, все плохо, у тебя алюминий в стенах а надо медь, давай всю проводку по всей квартире переделаем и щиток заменим.
все стены мы конечно разьебеним и ремонт потом понадобится делать.
вот ты такой же электрик. тесты кококо, композер кудахтах тах. 90% проектов это не мелкие магазины написанные на симфони, с дефолтными фичами типа авторизации и коменты через соц сети. куча самопала, велосипеды и прочая дичь которую в репозиториях не найдешь и которая нужна только вот в конкретно этом месте, конкретно этому клиенту.
я посмотрю как ты клиенту скажешь: вай дарагой, давай все все перепишем, а то мне лень разбираться в этом вот говне.
а это его хлеб, который кормит средней руки конторку, и на хую он вертел всяких вась с предложениями ценою в десятки тыс баксов
Вот же язык-ублюдок, а.
При этом если не задать тип в аргументе метода, но задать в дочернем классе - похапе сблевнет ошибку.
То что в возвращаемом значении на это похуй его не ебет
Ты долбаеб? Такое поведение во всех языках с нестрогой типизацией. Ты нахуя хочешь целостность системы разъебать только ради того, чтобы удобнее было?
Не агрись, это очередной неосилятор. Везде ему виноват язык, но никогда не он сам.
Ну так перестань кукарекать например.
>практически никогда не следует использовать статические методы
Тогда зачем добавили эту фичу?
Ну, осиливший ты наш, расскажи как задать тайп-хинт методу на возвращение массива объектов.
Только вот не надо мне тут про нинужно, пиздуй дальше свой говнокод на пыхе писать.
Конкретно в пхп вообще бесполезно спрашивать нахуя там что как сделали. Язык изначально делал ебанько для html-страницы своего кота.
Далее эта параша раскрутилась и туда навесили еще куч говна.
Потом еще и еще, вообще нихуя не парясь о том, чтобы новое говно соответствовало старому говну. (Например, стандартная библиотека целиком состоит из неструктурированного кала, где методы принимают что угодно, выдают что угодно, обрабатывают ошибки как кто хочет, кто-то высрет null, кто-то пустую строку, кто-то исключение. Да там сука даже нотация разная).
Я не ебу зачем, я тебе говорю со своего опыта.
Что если у тебя постоянно в одном классе вызываются статические методы другого класса - то это неявное внедрение зависимости. Что порождает дохуя проблем с тем, что потом ты уже вообще хуй поймешь от чего зависит твой код. Также приводит к спутанности кода.
Все зависимости следует передавать через конструктор.
>array
>тайп-хинт
Тебе сам язык говнокодить мешает, нееет хочу говна поесть. Какой-же ты мерзкий.
array - это все что угодно блять.
Мне же нужно точно знать, что возвращает функция.
"Массив" - ну заебись теперь.
Вот поэтому пхп и говно ебаное, как и js.
В яве все правильно сделано.
inb4: пиздуй в яватред отсюда нахуй
Такие как ты неосиляторы, выплакали миллиардами постов себе статические методы.
Теперь сидят и понять не могут, собственно зачем они их просили, и как они вообще собирались это применять.
Ну я не знаю тонкостей ООП.
Опять же, раньше я без задней тупо использовал классы, в основном, как сборище функций.
Затем я понял, что это приводит к говнокоду.
Затем почитал на тему статических методов и понял, что их и правда стоит применять ОЧЕ редко.
Ну сделай свой простой тип, долбаеб. PHP предоставляет много структур данных из коробки, которыми ты можешь воспользоваться (Например iterator, и тайпхинть там хоть любой объект). Нет, ты будешь нихуя не изучив даже - ныть про то, что язык, который ты знаешь на уровне школьника - говно.
Ну я, кстати, накидал объект-массив, который принимает объекты только заданного в дочернем классе типа и который можно итерировать.
Но это - самый настоящий ебаный говнокод, который должен решаться в нормальном языке двумя символами квадратных кавычек блять возле возвращаемого типа.
Все это говно ускоряет разработку, а значит, удешевляет ее.
Не надо тут недостатки языка за манну небесную выдавать, и, мол, так и было задумано.
Теперешние разрабы пхп может и хотели бы там все по-человечески сделать, но только обратная совместимость по пизде пойдет, вот и живем хуй знает сколько лет с тонной легаси-говнокода в стандартной библиотеке.
>который должен решаться в нормальном языке двумя символами квадратных кавычек блять возле возвращаемого типа
Ты в курсе, что в большинстве не строго типизированных языков такого дерьма нет? В чем претензия конкретно к php?
В том, что не ввели поддержку массивов типов в возвращаемом значении, хотя вроде как движутся в сторону строгой типизации
Ты что написал? Дебилойд, блять. Я же написал ИТЕРАТОР. Сука. Хули ты такой тупорылый то? В php уже есть встроенные типы данных, нахуя ты этот говнокод скинул в пикрилах? Ты можешь сделать такой класс, инстанс которого будет абсолютно идентичен стандартному массиву. Сука, как же ты заебал, ублюдок ты тупорылый. Почему ты такую хуйню творишь то?
Для долбаеба еще раз повторю ключевые слова: iterator, traversable, iteratoragregate, arrayaccess.
Если ты еще раз высрешь хуйню, которая не относится к реальности и показывает тебя со стороны лютого долбаеба, абсолютно не понимающего о чем идет речь - я с тобой больше общаться не буду, это смешно.
Ну во первых строгая типизация ненужна. Ибо говно говном. Уже TypeScript об это споткнулся.. И теперь вместо JS сообщества на нём пишут 3 с половиной аутиста.
Во вторых в 7.2 есть поддержка строгой типизации на массивы. Но подробностей не скажу. Я только описание нововведений читал.
>наследует
>интерфейс
А ты не очень умный, судя по всему. На этом, собственно, можем и закончить эту беседу. Ты так и не перестал быть тупым.
>говорит о типах данных, о том, что ему чего-то не хватает, называет язык говном
>наследует интерфейс
Помогите, пожалуйста, настроить .htaccess на серваке, чтобы всё перенаправлялось на index.php, но чтобы загружались стили, картинки, скрипты и шрифты.
Вот мои настройки. Подгружаются только стили.
RewriteEngine on
RewriteBase /shop
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php
На скринах то, что пишет бровузер.
Если в строке браузера написать путь непосредственно до скрипта или до картинки, то произойдет реидрект на индекс. Если написать путь до css, то он откроет css
Ты ещё спроси чем абстрактный класс от интерфейса отличается
Так-с, это нужно написать вместо моих настроек или вместе с ними? На серваке лежит много сайтов, они находятся в подпапках. Данный сайт находится по адресу site.com/shop. Получается нужно писать именно site.com/shop или так как ты написал?
Я просто ваще не алё в настройке этого файла....
Если ты не разбираешься, так потрудись немного и разберись:
- (англ) https://httpd.apache.org/docs/current/mod/mod_rewrite.html
- http://hostgid.net/baza-znanii/-htaccess/chto-takoe-mod-rewrite.html
- https://habr.com/company/sprinthost/blog/129560/
Прочти сначала и потом возвращайся с вопросами.
>>296828
>Разводит говно о том, что в пхп нет нужного ему функционала типизированных коллекций
>Ему говорят, что он долбаеб и достаточно добавить тайпхинт в объект итератора и подрубить arrayaccess
>Он делает абсолютно не то, прописывая типизацию логикой отдельных классов
>Ему говорят, что он долбаеб и даже конкретнее говорят в чем проблема
>Он не понимает и высирает хуйню про интерфейс
>Пытается оправдаться, но все уже тщетно
Так ты же зеленый, хуйню написал какую-то. Зачем ты в конструкторе этот бред написал? Тебе сказали добавить тайпхинтинг, а не пересоздать свой объект итератора с нуля.
>Ему говорят, что он долбаеб и достаточно добавить тайпхинт в объект итератора
Это как блять? Покажи код
>подрубить arrayaccess
Нахуя мне arrayaccess?
>Ну я не знаю тонкостей ООП.
Инкапсуляция, наследование, полиморфизм. Это даже толсто.
ООП это когда берёшь библиотеку, наследуешся от неё, походя перепиливая под своё приложение и пользуешься.
Вообще, для таких сложных ситуаций есть режим отладки mod_rewrite. Ты можешь выставить в конфиге Апача логгирование, и он будет писать в лог (очень подробно) выполнение каждой строчки в .htaccess.
https://karashchuk.com/Apache/mod_rewrite_debug/
<ifModule> можно не писать, только 2 директивы. После этого перезапусти Апач, попробуй открыть сайт и посмотри логи. Если хостер не позволяет так делать, то придется установить Апач локально или в витруалке.
Ты нарушаешь контракт, который задает интерфейс. Интерфейс говорит, что можно передать любой тип, и ты обязан это соблюдать. Ты можешь только расширить набор типов, но не сузить.
Иначе код, который получает этот интерфейс, сломается. Он ведь не знает про конкретный класс и не знает, что ему надо передать.
>>296690
RFC есть: https://wiki.php.net/rfc/generics
>>296688
вот зачем этот флуд? Ты ведь не знаешь, какой у него код и какая ситуация. Или ты тут хочешь выглядеть умным и сказать, что надо было 5 лет назад писать код правильно? Ну да, хорошо быть богатым, плохо быть бедным.
>>296682
Нельзя. Если очень надо, ты можешь сделать класс для этого, обернув какой-нибудь ArrayObject. Унаследовать и ограничить передаваемые типы нельзя из-за правила Лисков.
Если тебе не нравится, ты можешь выбрать любой другой язык, тебя никто не держит.
Для utility-классов можно. Хотя, конечно, если подумать, правильнее было бы использовать тут функции, когда для них приделают автозагрузку.
>>296747
Хороший вопрос, на самом деле.
Вообще, фич в PHP много, но не все из них стоит использовать. Например, глобальные переменные не стоит использовать в больших приложениях.
Статические методы - это методы, которым не нужен $this, указатель на конкретный объект. Обычно это какие-то простые вспомогательные методы.
Использовать статические методы везде плохо, так как мы, например, не можем в таком случае создать 2 объекта с разными настройками. Или не можем создать объект, сделать с ним что-нибудь и выкинуть. Неудобно тестировать.
класс хинтинг через указание типов и обьектов ? ебанный насос
уважаемый, это не ява, нет жесткой типизации.
если желаете хинты раставлять, юзайте phpdoc, благо phpstorm и другие иде позволяют тянуть хинты из пхпдока.
зы. жабу учи, и не убери нахуй руки от котоламповой пхпшчки
ох лол. singleton - гугли.
это наверное второй по популярности патерн. но у многих нубов проблемы с структурой обьектов.
статические классы появились раньше чем все навороты с екстеншинами и трейтами.
в универе не учат, но зато учат яве... херовой яве... ява очень плохо влияет на пхпшников, если углубится - есть риск вообще не понять прелести языка
>добавить тайпхинтинг, а не пересоздать свой объект итератора с нуля
Это как вообще?
Куда ты там этот тайпхинтиг будешь добавлять, не реализуя интерфейс Iterator?
Че вы мне тут втираете вообще, поехавшие?
Ты или реализуешь один из интерфейсов или идешь нахуй, другого нет. А вы говорите что есть.
>уважаемый, это не ява
Вот и плохо, все языки должны быть как ява.
Чего только стоит ее мощнейшая типизация, широкий набор структур данных из коробки (с дженериками), отличная поддержка рефлексии, многопоточность, качественная стандартная библиотека целиком на ООП, принудительная обработка ошибок через исключения, да там все охуенно.
Что из этого есть в пыхе? Да, нихуя.
После явы любой другой язык кажется неполноценным говном. Хз как называется эта болезнь, но это так
/
@param $myObject link\to\my\object
@return object link\to\another\object
/
function return_object_by_obect($myObject) {
return new anotherObject();
}
и тогда о чудо, у тебя в хинтах появится подсказка что функция как аргумент принимает обьект и даже ссылку на него даст.
а с результатом функции иде даст работать как с нужным обьектом
просто почитай документацию на phpdoc, оно реально работает без тацнев с бубном. если пишешь классы - мастхев.
читаемость кода повышает, сам же лучше будешь читать чужой код + это показывает что разраб не последнее нубло открывшее книгу "пхп за 24 часа"
ява самый убогий из имеющихся юзыков.
его юзают только из-за простого портирования между платформами. но если дело касается каких то низкоуровневых штук ( или высокопроизводительных ) то ява заглатывает, и ничего с этим сделать нельзя.
бонусом, разрабы после явы ни на что не годны ( кроме явы ). но они не жалеют, горды что выбились айти.
зы . этакая макдачка в мире кулинарии
Сука! Больной ублюдок блять! Мразь!
Причем тут твой зассаный пхпдок??
От того, что ты говна в комментах напишешь, у тебя настоящий тайпхинт не появится.
Пиздец блять, с какими дегенератами я сижу в одном тре
ахахаха, от того что ты В ПРАВИЛЬНОМ формате напишешь, IDE типа пхпшторм будет генерировать хинт появится. доку жеж
ну да, варнинг сама пхпшчка не кинет
зы. всегда ржу когда нубас начинает понимать как оно работает, столько удивления на лице, куча эмоций...
Да хуле тут непонятного, манямирок уровня бэ, я этот пхппок юзал на 5-й части.
Сейчас в этом говне (в смысле указывать в пхпдоке возвращаемое значение и типы аргументов) смысла нет.
Хуею с треда, дурачки думают, какие они ебануться умные.
А не для того блять, чтобы к тебя в иде подсветилось.
Например я посылаю GET запрос на http://mysite.ru/proxy.php?user=abu&avatar=makaka.jpg, а proxy.php пересылает его на http://egosite.ru/api.json?user=abu&avatar=makaka.jpg и отдаёт ответ мне, давая пососать CORS-у, помогите осилировать
>Хуею с треда, дурачки думают, какие они ебануться умные.
аахххахаха, нубы думают какие они пиздатые. реально, батькам платят 500к+ просто так, за то что они пхп5 знают хорошо. семерка недавно же вышла, и её знает что нуб что батька одинаково. правда же анон ?
о да шерлок, раскажи им еще как в фреймворках хинты генерятся, это надо быть последним уебаном чтобы не посмотреть как в том же симфони\вии сделали
Я вижу как он хочет обучиться. Так хочет, что кроме негативных высказываний в сторону PHP ничего и написать не мог. Будет адекватно общаться, будет адекватный ответ. А так не вижу смысла винить меня в том, что в меня негатив летит.
Что там такого изменилось с 5.4 на 7.2, что стоить будет десятки тыщ баксов? Депрекейтов было не так уж много, если не единицы. В основном изменения коснулись только PDO и работами с БД.
>В php уже есть встроенные типы данных
Да ладно блять? скаляры и array - вот все, что там есть.
Есть spl-расширение для структур данных и ds-расширение.
Оба сорта говна, которых из коробки нет.
>написать программу на нем и запустить ее из командной строки
Это я и хочу сделать, запустить на фоне скрипт на php который проксировал бы мои запросы к внешнему серверу, но не знаю что туда писать.
>>296437
>установить Node.js и запустить JS-скрипт в консоли
Не могу в Node.js.
>>296437
>отключить в браузере проверку этих заголовков
Опасно, любой пиздюк сможет со своего говносайта получать доступ к моим например кукам.
>И тут меня осенило, я же могу не ебаться с серверами и их арендой, а запустить сервер прямо у себя на пекарне
Поехавший. Если в кратце - затея хуйня.
Купи себе вдс за 3 доллара и не еби мозги
Расширение для браузера. Можно даже тупо скрипт для Greasemonkey и подобной хуйни.
Из расширения ты можешь вырубить cross-origin контроль.
Я придумал унаследоваться от ArrayObject'а и прикрутить ему в конструктор проверку типа элементов передаваемого ему массива.
А сам тип задается в дочернем классе.
Таким образом, у меня происходит реальный контроль типа и я точно знаю, что в MessageArray будут только объекты Message.
Я могу задать тайпхинт возвращаемого значения : MessageArray и в принимающем методе быть уверенным, что в том, что мне прилетело будет то, что надо.
Но теперь другая беда. IDE не ебет, что у меня в этом месседж аррее будут только объекты Message.
При итерации через foreach() показывается какое-то говно, а не содержимое класса Message.
Что делать?
То есть, вопрос чисто про подсветку в IDE.
Точнее, ты можешь задать в настройках расширения область его действия. В том числе /, то бишь, на всех сайтах.
больной ублюдок. у тебя на 2х скринах кода вообще нет, а на оставшемся кода 1 строка.
trow... это так по пхпшному, убей себя об стену.
резюмируя: индус которому платят за обьем кода
ну вообще достаточно много изменилось, взять тот же strict mode.
когда говорят что пхп стал в хуй раз быстрее, подразумевают именно строгий режим. старый говнокод будет работать примерно так же.
и если мы говорим переписать с 5 в 7. то вероятно речь идет о перепиливании под ООП, с классами там, как сейчас модно
>>297048
без статика ты не получишь сингтон. пруф или хуй ? ( я бы посмотрел на реализацию, как же защита от копирования ? )
>>297066
обоже обоже обоже, не вспоминай это говно, даже не произноси в слух. может оно сдохнет само по себе если нубам не рассказывать, а то переодически появляются умники с восклицанием "посмотрите что я нашел, это гениально и решает все проблемы"
Почему их нет в тредах других языков?
Нахуя что-то покупать и ебаться с его настройкой, если можно запустить трёхстрочный код проксирования локально?
ну это, как же...
$a = $b = new myobj();
$a->a = 1; $b->a = 2;
а в сингтоне так не прокатит.
myobj::$a = 1 и как ты его не копируй там всегда будет 1. в этом смысл
Извини братишка, но я правда не ебу как писать расширения для браузера, а те что есть в магазине расширений, отключают эту проверку на всех сайтах, что я думаю не есть хорошо.
Ну хз. Вообще весь мой код который я писал в 2010 работает на 7 версии. Я даже не подозреваю что там можно переписать.
> вероятно речь идет о перепиливании под ООП, с классами там, как сейчас модно
Как-то притянуто за уши. Тем более что это вообще не несёт никаких профитов клиенту. Разьве что местные эстеты будут на код фапать.
>$a = $b = new myobj();
>$a->a = 1; $b->a = 2;
Ну и в чем проблема, ты скопировал ссылку на объект. Объект у тебя 1.
Скрипт для гризманки напишет любой долбоеб. Достаточно знания жс и все. Там все очень просто.
Только в JS треде. Самые токсичные кстати тоже там. Жаэе на VG не настолко токсишные дети сидят. Почему тут поехавшие? Очевидно кто-то кинул ссылку в JS трад и оттуда набежало. Так то мы вообще самые культурные на борде.
Нихуя ты ответочки кидаешь. В предыдущих постах тыкал, тут на "Вы". Сноб с раздвоением личности?
вот этого непонял, поясни плс.
после манипуляций обьекта стало два ( ну да, он имеет одно имя )
а два их потому что у каждого свой набор атрибутов, они не идентичны.
по канону это не синглтон, синглтон всегда существует в одном варианте
Хотя по мне ты нуб, если ты как миниум не уверенный мидол в языке. До тех пор ты нуб.
Спрашиваешь про какие-то более абстрактные глобальные вопросы - никто даже не догоняет о чем вообще речь, видят только то, что написано на экране, а не то, к чему это ведет в глобальном смысле.
Зато кукареков просто миллион. Ну не знаешь ты нихуя - не пизди блядь, сиди и скроль дальше.
Проиграл на всю комнату
Хорошо, что же за такая волшебная команда есть в JS, которая заставит браузер игнорировать Access-Control-Allow-Origin?
Алё /ph??? У нас тут ваш парень язык выучил и начал искать глобальные смыслы! Заберите его нахуй!
>после манипуляций обьекта стало два
Да нихуя, просто ссылки на один и тот же объект стало две.
>ну да, он имеет одно имя
На один объект 2 ссылки
>а два их потому что у каждого свой набор атрибутов, они не идентичны.
С чего ты это взял? Объект 1, объекты сами собой не копируются, если ты не описал для них метод __clone().
Чтобы создать копию объекта, надо вызвать clone.
$copy_of_object = clone $object;
По-дефолту clone копирует свойства объекта по своей маня-схеме, короче это хуйня. Поэтому сделали переопределяемый магический метод __clone(), в котором ты можешь задать, как корректно скопировать объект.
Если просто вызвать $obj1 = $obj2, создастся просто еще одна ссылка на один и тот же объект.
Все даже еще пизже. В любой метод передается объект не по значению, а по ссылке.
Объект - слишком сложная хуйня, чтобы можно было безопасно их копировать.
В яве то же самое.
Весь "Хуесосинг" начался только когда к нам завалился парень, который начал разговор с того, какой у нас язык плохой и какие мы все тут плохие.
Я не совсем понимаю какого ответа он ожидал? Что ему тут жопу поцелуют?
>В яве то же самое.
все встало на свои места :D спс за внимание
для тебя поясню почему попросил столько подробностей:
нет, в пхп совсем не как в яве
обьект не передается по ссылке, каждый раз делая $a = $myobj; ты копируешь обьект.
clone работает весьма криво.
есть вариант с $a = &$myobj; чтобы передать ссылку, но так типа некрасиво.
$a->a = 1;
$b = $a;
$b->a = 2;
echo $a->a выведет 1, что немного необычно для жаберов
даже сделав $b = $a->clone();
b будет содержать копию класса, но не ссылку на a
>>297173
http://sandbox.onlinephpfunctions.com/code/579d44d0b09bc22be0199fff6e980559baff3a0a
а потом эти люди втирают мне, что у меня кода на скриншотах мало и поэтому я даун
обьясни это симфони блядям, и за одно почему их говно жрет по 50-100 метров памяти на запрос. мимокрокодил
http://sandbox.onlinephpfunctions.com/code/3dbe830008b471ece986092e6b5e3cd09e8c1f67
Вот короче полный пример.
По-дефолту clone создат объект по своим ебанутым правилам, как ему виднее.
Чтобы определить, как корректно скопировать объект - нужно переопределить функцию __clone(). Все как и в яве.
Попытка №2.
Хочу получать данные с помощью JS из API с внешнего сайта, мне мешает это сделать CORS, хочу их получать через php скрипт.
Например я посылаю GET запрос на http://mysite.ru/proxy.php?user=abu&avatar=makaka.jpg, а proxy.php пересылает его на http://egosite.ru/api.json?user=abu&avatar=makaka.jpg и отдаёт ответ мне, вот накидал начало скрипта, что и как делать дальше? Помогите пожалуйста, я не ебу http://sandbox.onlinephpfunctions.com/code/5ed07ca56b6cd6904aa7c77973ad498480dffab4
На, должно быть как-то так. На этой хуйне не работает, но на сервере должно работать.
http://sandbox.onlinephpfunctions.com/code/73f97a42dcd93a339a7ef339db7fa0a51bcb5de9
А вообще лучше бы js-скрипт для гризманки написал и не ебал мозги.
Блять, функцию дефолтных параметров забыл.
http://sandbox.onlinephpfunctions.com/code/c51aaed2b0a0dbfc150c135f927dac782187bbce
Ну короче тебе надо просто взять данные из get-запроса юзера, отправить их на другой сайт и выдать юзеру ответ.
Короче вот что получилось http://sandbox.onlinephpfunctions.com/code/f7988df94a5a425a77e934cd9ab048238eafef00
Как обработать ошибку 404? Чтобы он выдавал не Warning, а нужный мне текст?
Не, только get, простейшие запросы к api, а не подскажешь как обработать ошибку в proxy.php и вернуть нужным мне текст, если я например отправлю параметр которого нет и внешний сервер пришлёт мне 404, сейчас proxy.php присылает html код с описанием ошибки мне прямо в js, js от такой хуйни просто ломается
это потому что ты хеловордишь, даже в доке по обьектам на оф сайте можно найти что-то типа
class A { public $foo = 1;}
function go($obj) { $obj->foo = 2;}
function bo($obj) {$obj=new A;}
$e = new A;
go($e);
bo($e);
echo $e->foo - 2, хотя ожидается 1
проблема решается есть сделать так
function bo(&$obj) {$obj=new A;}
это называется - передача обьекта по ссылке.
http://sandbox.onlinephpfunctions.com/code/7b312b4f1167a027f14fd4f218c70e28f9f3dcc9
вот пример если угодно, мы имеем в реале 3 копирования обьекта, 2 раза на new и один раз на передаче в функцию, но эту передачу реализует пхпшчка немного специфично
В смысле блять.
public function bar(A $bar)
{
$bar = new A;
}
Что блять на этом этапе происходит? Какого хуя значения различаются? Откуда еще один объект взялся?
Или тип в метод можно передать объект, по ссылки, взаимодействовать там с ним (и он будет изменен снаружи), но записать в эту ссылку новое значение нельзя?
И тип ссылка внутри метода доступна ридонли?
1. В интерфейсе тайпхинт вернуть Test1.
2. В методе тайпхинт тоже на Test1.
3. Но возвращается потомок Test1 - Test2. Метод работает.
Далее переменная имеет таки тип Test2.
И это заебись, хорошо что так.
Но при этом в потомке наследника интерфейса нельзя переопределить тайпхинт на потомка, хотя по сути это все равно еще будет Test1.
тож самое с атрибутами, попробуй сделать в дочернем классе
getTest($a) - выкинет ворнинг, но не упадет.
фишку добавили в пхп 5.4 и в бете падало в фатал ерор как у тебя на скрине, аноны лютовали потому как много говнокода перестало работать.
выло столько народа, что аж специально добавили E_STRICT который подавлял ошибку.
Банкомат - https://ideone.com/zFMkHm
Калькулятор - https://ideone.com/fEyLF1
Числа прописью - https://ideone.com/i79CX9
>Ты можешь проверить, попробовав поделить с помощью % большие числа (проверь).
Да, я проверил, и в нём проблема
>> "[$1]",
>Точно не $0 ?
Да, $0, ошибся
>> "/[,]?\s+(но)/ui" => ", $1",
>Здесь он поставит запятую перед "ночь".
Добавил в конце \b
>>292640
>>Shift - https://ideone.com/L4JUTk
>Неплохо, но можешь сделать, чтобы многоточия и другие группы знаков препинания не разбивало бы пробелами?
https://ideone.com/SR7U45
(пик 2)
trim($_SERVER['REQUEST_URI'], '/shop')
Вот URI запрос: /shop/product
Функция почему то возвращает roduct
Внимание вопрос: втф? Почему возвращается roduct, а не product?
Я понял, функция вырезает символы, а не строку. Если в запросе написать /shop/op, то функция вернет пустую строку. Хм, как же вырезать /shop/ из начала запроса?
Таков этот тред пидорасов, никто нихуя не умеет, только на словах, приходится ебаться часами или вообще неосилять
лол
какой упоротый нуб
Хватит флудить
>>297414
Неправда. Напиши вопрос, и рано или поздно на него ответят.
>>297401
Лучше всего - регуляркой, так как str_replace вырезает эту подстроку в любом месте, а не только в начале строки.
>>297395
Какой-то круг у тебя кривоватый. Надо было, конечно, коэффициенты подобрать.
> intval(round(cos(deg2rad($angle)) * $radius)
Внутрь round надо было заключить все выражение, а не его часть, так как у тебя из-за умножения целого числа на 2 получается, что шаг будет 2 знакоместа (letterX будет всегда четный).
> foreach ($row as $letter){
> echo $letter;
Можно использовать implode.
>>297394
> Банкомат - https://ideone.com/zFMkHm
> examination (
Имя функции принято начинать с глагола, делатьЧтоТо().
> checkATM(
Название не отражает, что делает функция. Что значит "проверить банкомат"? Проверить на что? Надо было назвать функцию "есть ли купюры". Также, для выдачи и не требуется, чтобы все купюры были на месте - если нам нужно выдать 5000, то достаточно одной 5000-ной купюры.
> return (($sumInATM - $sum) >= 0) ? true : false;
Оператор >= возвращает true/false, потому можно просто писать return $sumInATM >= $sum
> //Проверяет, может ли банкомат выдасть купюры, и если не может, выводит причину
Это плохо, что функция часть результата возвращает, а часть выводит. Было бы логично и причину тоже возвращать. Можно сделать 2 варианта:
- возвращать массив из 2 элементов (bool + string)
- возвращать текст ошибки либо null, если ошибки нет
> function integer
Название не говорит о сути функции.
> for($i = 3; $i >= 0; $i--){
Здесь лучше не вписывать 3, а вычислять ее из размера массива. А еще лучше - отсортировать массив по убыванию номинала и использовать foreach вместо тяжелочитаемых индексов.
Плохо, что номиналы купюр в коде прописаны 2 раза и неудобно их менять.
> if($moneyATM[$keys[$i]] >= $paper[$keys[$i]]){
Тут можно использовать min/max
> function currency()
Тут в функции нет проверки в конце, что мы всю сумму выдали. Может быть такое, что денег достаточно, но купюр для выдачи требуемой суммы нет (например: есть 5000-е, а надо выдать 1500).
Вот пример, где программа дает неверный ответ: https://ideone.com/aq9u1O
Анончик, постарайся сам определять крайние случаи и протестировать программу на разных комбинациях входных данных. Такие ошибки, когда ты будешь работать, ты должен отлавливать сам.
То есть ты можешь сделать, например, массив входных данных с вручную посчитанными ответами и прогнать программу по ним, сверяя полученный ей результат с правильным ответом. Постарайся включить сложные случаи, когда не хватает некоторых купюр, или когда нет нужной комбинации купюр.
> Калькулятор - https://ideone.com/fEyLF1
> $number = "";
> $op = $char;
Это повторяется 2 раза, можно было не копипастить.
Если в выражении нет операций, выдается 0: https://repl.it/repls/CoarseAlarmedProcedurallanguage
А так, верно.
> Числа прописью - https://ideone.com/i79CX9
> {//Возвращает первые цифры для переданного числа
Комментарий обычно пишут над функцией, а не справа от скобки.
>(floor($number % pow(10, $i))
floor не имеет смысла, так как % возвращает int
> $firstDigits = getFirstDigits($number, ($amountOfDigits % 3 != 0) ? $amountOfDigits - $amountOfDigits % 3 : $amountOfDigits - 3);
Тяжело читать такое длинное выражение, надо было вынести аргумент в переменную.
Код в конце программы стоило бы завернуть в функцию, чтобы можно было, например, вызвать ее несколько раз для нескольких разных чисел и увидеть результаты.
> if(preg_match("/^[^.?!]/u", $fixedString[$i]) && preg_match($pattern, $fixedString[$i + 1])
Здесь есть риск что элемента $i + 1 не существует и будет ошибка. Было бы лучше ставить пробел не после, а перед текущим предложением, при условии, что оно не состоит из одного знака препинания. Или так нельзя?
Хватит флудить
>>297414
Неправда. Напиши вопрос, и рано или поздно на него ответят.
>>297401
Лучше всего - регуляркой, так как str_replace вырезает эту подстроку в любом месте, а не только в начале строки.
>>297395
Какой-то круг у тебя кривоватый. Надо было, конечно, коэффициенты подобрать.
> intval(round(cos(deg2rad($angle)) * $radius)
Внутрь round надо было заключить все выражение, а не его часть, так как у тебя из-за умножения целого числа на 2 получается, что шаг будет 2 знакоместа (letterX будет всегда четный).
> foreach ($row as $letter){
> echo $letter;
Можно использовать implode.
>>297394
> Банкомат - https://ideone.com/zFMkHm
> examination (
Имя функции принято начинать с глагола, делатьЧтоТо().
> checkATM(
Название не отражает, что делает функция. Что значит "проверить банкомат"? Проверить на что? Надо было назвать функцию "есть ли купюры". Также, для выдачи и не требуется, чтобы все купюры были на месте - если нам нужно выдать 5000, то достаточно одной 5000-ной купюры.
> return (($sumInATM - $sum) >= 0) ? true : false;
Оператор >= возвращает true/false, потому можно просто писать return $sumInATM >= $sum
> //Проверяет, может ли банкомат выдасть купюры, и если не может, выводит причину
Это плохо, что функция часть результата возвращает, а часть выводит. Было бы логично и причину тоже возвращать. Можно сделать 2 варианта:
- возвращать массив из 2 элементов (bool + string)
- возвращать текст ошибки либо null, если ошибки нет
> function integer
Название не говорит о сути функции.
> for($i = 3; $i >= 0; $i--){
Здесь лучше не вписывать 3, а вычислять ее из размера массива. А еще лучше - отсортировать массив по убыванию номинала и использовать foreach вместо тяжелочитаемых индексов.
Плохо, что номиналы купюр в коде прописаны 2 раза и неудобно их менять.
> if($moneyATM[$keys[$i]] >= $paper[$keys[$i]]){
Тут можно использовать min/max
> function currency()
Тут в функции нет проверки в конце, что мы всю сумму выдали. Может быть такое, что денег достаточно, но купюр для выдачи требуемой суммы нет (например: есть 5000-е, а надо выдать 1500).
Вот пример, где программа дает неверный ответ: https://ideone.com/aq9u1O
Анончик, постарайся сам определять крайние случаи и протестировать программу на разных комбинациях входных данных. Такие ошибки, когда ты будешь работать, ты должен отлавливать сам.
То есть ты можешь сделать, например, массив входных данных с вручную посчитанными ответами и прогнать программу по ним, сверяя полученный ей результат с правильным ответом. Постарайся включить сложные случаи, когда не хватает некоторых купюр, или когда нет нужной комбинации купюр.
> Калькулятор - https://ideone.com/fEyLF1
> $number = "";
> $op = $char;
Это повторяется 2 раза, можно было не копипастить.
Если в выражении нет операций, выдается 0: https://repl.it/repls/CoarseAlarmedProcedurallanguage
А так, верно.
> Числа прописью - https://ideone.com/i79CX9
> {//Возвращает первые цифры для переданного числа
Комментарий обычно пишут над функцией, а не справа от скобки.
>(floor($number % pow(10, $i))
floor не имеет смысла, так как % возвращает int
> $firstDigits = getFirstDigits($number, ($amountOfDigits % 3 != 0) ? $amountOfDigits - $amountOfDigits % 3 : $amountOfDigits - 3);
Тяжело читать такое длинное выражение, надо было вынести аргумент в переменную.
Код в конце программы стоило бы завернуть в функцию, чтобы можно было, например, вызвать ее несколько раз для нескольких разных чисел и увидеть результаты.
> if(preg_match("/^[^.?!]/u", $fixedString[$i]) && preg_match($pattern, $fixedString[$i + 1])
Здесь есть риск что элемента $i + 1 не существует и будет ошибка. Было бы лучше ставить пробел не после, а перед текущим предложением, при условии, что оно не состоит из одного знака препинания. Или так нельзя?
Вообще, если ты интересуешься наследованием в ООП, то тебе стоит почитать про принцип Лисков (там, где это описано простыми словами), а заодно можешь глянуть ковариантность/контрвариантность: https://ru.wikipedia.org/wiki/Ковариантность_и_контравариантность_(программирование) - но там может оказаться сложновато разобраться. Английская версия статьи поподробнее.
Принцип Лисков говорит, что в код, работающий с базовым классом, можно передать объект класса-наследника, и ничего не должно сломаться; наследника можно использовать вместо предка.
Потому:
- типы аргументов можно расширять, но не сужать (=они контрвариантны)
- типы возвращаемых значений можно сужать, но не расширять (=они ковариантны)
То, что сейчас типы возв. значений не ковариантны - это баг, и он обсуждается тут:
- https://bugs.php.net/bug.php?id=72442
Увы, нужен RFC, голосование и желающий исправить проблему.
>>297298
Добавление аргумента нарушает совместимость и принцип Лисков.
>>297235
Создается новый объект и указатель на него записывается в локальную переменную $bar внутри функции. На переменные снаружи функции это не влияет.
> Или тип в метод можно передать объект, по ссылки, взаимодействовать там с ним (и он будет изменен снаружи), но записать в эту ссылку новое значение нельзя?
У тебя нет передачи по ссылке. Она обозначается символом &. Переменная $bar в функцию передается по значению (копируется). Мануал про ссылки: http://php.net/manual/ru/language.references.php
Некоторые учебники пишут, что объекты передаются по ссылке, это некорректное утверждение. Хотя метод передачи похож на передачу по ссылке, но это не она.
Для простоты представь, что объект создается где-то в памяти, а в переменную сохраняется его уникальный номер (указатель). Новые объекты создаются только операторами new/clone, а остальные операторы (знак равенства) просто копируют номер объекта:
$a = new A; // Создали объект #1
$b = $a; // В $b скопировался указатель на объект #1, она указывает на тот же объект
$b = new A; // Cоздали объект #2 и записали указатель в $b
$c = clone $b; // создали объект #3 и записали указатель в $c
func($a); // Передали в функцию номер объекта из $a (#1)
У тебя при вызове функции в $bar передается номер какого-то объекта, и в копии переменной внутри функции он заменяется на другой номер.
Вообще, если ты интересуешься наследованием в ООП, то тебе стоит почитать про принцип Лисков (там, где это описано простыми словами), а заодно можешь глянуть ковариантность/контрвариантность: https://ru.wikipedia.org/wiki/Ковариантность_и_контравариантность_(программирование) - но там может оказаться сложновато разобраться. Английская версия статьи поподробнее.
Принцип Лисков говорит, что в код, работающий с базовым классом, можно передать объект класса-наследника, и ничего не должно сломаться; наследника можно использовать вместо предка.
Потому:
- типы аргументов можно расширять, но не сужать (=они контрвариантны)
- типы возвращаемых значений можно сужать, но не расширять (=они ковариантны)
То, что сейчас типы возв. значений не ковариантны - это баг, и он обсуждается тут:
- https://bugs.php.net/bug.php?id=72442
Увы, нужен RFC, голосование и желающий исправить проблему.
>>297298
Добавление аргумента нарушает совместимость и принцип Лисков.
>>297235
Создается новый объект и указатель на него записывается в локальную переменную $bar внутри функции. На переменные снаружи функции это не влияет.
> Или тип в метод можно передать объект, по ссылки, взаимодействовать там с ним (и он будет изменен снаружи), но записать в эту ссылку новое значение нельзя?
У тебя нет передачи по ссылке. Она обозначается символом &. Переменная $bar в функцию передается по значению (копируется). Мануал про ссылки: http://php.net/manual/ru/language.references.php
Некоторые учебники пишут, что объекты передаются по ссылке, это некорректное утверждение. Хотя метод передачи похож на передачу по ссылке, но это не она.
Для простоты представь, что объект создается где-то в памяти, а в переменную сохраняется его уникальный номер (указатель). Новые объекты создаются только операторами new/clone, а остальные операторы (знак равенства) просто копируют номер объекта:
$a = new A; // Создали объект #1
$b = $a; // В $b скопировался указатель на объект #1, она указывает на тот же объект
$b = new A; // Cоздали объект #2 и записали указатель в $b
$c = clone $b; // создали объект #3 и записали указатель в $c
func($a); // Передали в функцию номер объекта из $a (#1)
У тебя при вызове функции в $bar передается номер какого-то объекта, и в копии переменной внутри функции он заменяется на другой номер.
Надо в такой ситуации выдавать ошибку 404 с помощью header(). А в идеале еще и HTTP-заголовки полученные передавать.
>>297226
https://ru.wikipedia.org/wiki/HTTP#Методы
Точное определение метода смотри в RFC (англ): https://tools.ietf.org/html/rfc2616#section-9.6
>>297205
в коде ошибки!
Во-первых, изучи мой или любой другой урок по составлению URL и сделай экранирование спецсимволов в GET-параметрах: https://github.com/codedokode/pasta/blob/master/network/urls.md
Во-вторых, прочти мануал по file_get_contents и узнай, как получить код ответа и заголовки ответа, которые желательно передать в неизменном виде клиенту.
А, в мануале это не написано (баг, надо бы зарепортить). Ну держи тогда ссылку с информацией: http://php.net/manual/ru/reserved.variables.httpresponseheader.php
Чтобы отключить warning, придется влепить @. Это очень плохая идея, использовать оператор, и прежде чем его использовать, надо изучить, нет ли других вариантов.
А кстати, ты библиотку Guzzle у удобным ООП-интерфейсом не хочешь использовать? Хотя, для твоей задачи наверно она не требуется.
> Хочу получать данные с помощью JS из API с внешнего сайта, мне мешает это сделать CORS, хочу их получать через php скрипт.
Тебе нужно именно из браузера, со страницы сайта их отправлять? Не проще написать PHP скрипт и из него слать? Или расширение на JS?
Надо в такой ситуации выдавать ошибку 404 с помощью header(). А в идеале еще и HTTP-заголовки полученные передавать.
>>297226
https://ru.wikipedia.org/wiki/HTTP#Методы
Точное определение метода смотри в RFC (англ): https://tools.ietf.org/html/rfc2616#section-9.6
>>297205
в коде ошибки!
Во-первых, изучи мой или любой другой урок по составлению URL и сделай экранирование спецсимволов в GET-параметрах: https://github.com/codedokode/pasta/blob/master/network/urls.md
Во-вторых, прочти мануал по file_get_contents и узнай, как получить код ответа и заголовки ответа, которые желательно передать в неизменном виде клиенту.
А, в мануале это не написано (баг, надо бы зарепортить). Ну держи тогда ссылку с информацией: http://php.net/manual/ru/reserved.variables.httpresponseheader.php
Чтобы отключить warning, придется влепить @. Это очень плохая идея, использовать оператор, и прежде чем его использовать, надо изучить, нет ли других вариантов.
А кстати, ты библиотку Guzzle у удобным ООП-интерфейсом не хочешь использовать? Хотя, для твоей задачи наверно она не требуется.
> Хочу получать данные с помощью JS из API с внешнего сайта, мне мешает это сделать CORS, хочу их получать через php скрипт.
Тебе нужно именно из браузера, со страницы сайта их отправлять? Не проще написать PHP скрипт и из него слать? Или расширение на JS?
> обьект не передается по ссылке, каждый раз делая $a = $myobj; ты копируешь обьект.
Неверно. Ты копируешь "указатель" (можно считать, порядковый номер)
> clone работает весьма криво
Нормально он работает.
>>297169
> В любой метод передается объект не по значению, а по ссылке.
Это неточно. Передача по ссылке явно указывается символом &. Если его нет - переменная передается по значению, но для объекта это будет не сам объект, а его "номер" или "указатель".
Объекты в PHP передаются точно так же, как в Java, C#, JS.
> Объект 1, объекты сами собой не копируются, если ты не описал для них метод __clone().
Оператор clone работает, даже если этого метода нет.
>>297167
В расширении можно запрашивать любые URL в обход CORS, как я помню. Описание: https://developer.chrome.com/extensions/xhr
>>297163
Объекты создаются только через new/clone, потому там один объект, просто указатель на него записан в две переменных.
Так проще тогда и код скачивания засунуть в PHP, а не городить схемы с проксированием, как мне кажется. Или писать на ноде, где есть JS, но нет ограничений.
>>297089
Проблема с ArrayObject в том, что данные в него можно передать не только через конструктор, но и через методы. А ставя в них ограничения, ты нарушаешь принцип Лисков.
Потому ArrayObject надо оборачивать:
class MessagesList implements ArrayAccess, ...
{
private $list;
...
$list = new ArrayObject(...);
...
}
Твоя задача решается дженериками, которых в PHP нету. Как безвыходный вариант, можно использовать идею с абстрактным методом (можно сделать не getType(), а supports(object $x)), но тогда придется отказаться от тайп-хинтов.
> То есть, вопрос чисто про подсветку в IDE.
Используй doc-комментарий @var: https://intellij-support.jetbrains.com/hc/en-us/community/posts/207025175-Using-to-phpdoc-to-specify-that-a-variable-represents-an-object-class
>>297070
Переменным надо давать осмысленные имена. Да, это не очень просто, но никто не обещал, что будет легко.
> [а-яё0-9a-z,.?!:;]+
Ты хотел написать "любой символ, кроме пробела"? Тогда надо использовать \\S
> $hui = preg_replace($regexp,"$1$3$5",$hui);
> $hui = preg_replace($regexp,"$1$3$5",$hui);
Почему повторяется 2 раза? Нужен как минимум комментарий.
> $l++;
> if (($letter==".")|($letter=="?")|($letter=="!")) {
> $letters[$l]=mb_strtoupper($letters[$l]);
Здесь есть риск, что элемента $l + 1 может не существовать. Лучше сделать переменную "предыдущий символ", и проверять ее.
А еще лучше - использовать preg_replace_callback.
Расстановку пробелов - нельзя ли было сделать там же, где и удаление пробелов?
Так проще тогда и код скачивания засунуть в PHP, а не городить схемы с проксированием, как мне кажется. Или писать на ноде, где есть JS, но нет ограничений.
>>297089
Проблема с ArrayObject в том, что данные в него можно передать не только через конструктор, но и через методы. А ставя в них ограничения, ты нарушаешь принцип Лисков.
Потому ArrayObject надо оборачивать:
class MessagesList implements ArrayAccess, ...
{
private $list;
...
$list = new ArrayObject(...);
...
}
Твоя задача решается дженериками, которых в PHP нету. Как безвыходный вариант, можно использовать идею с абстрактным методом (можно сделать не getType(), а supports(object $x)), но тогда придется отказаться от тайп-хинтов.
> То есть, вопрос чисто про подсветку в IDE.
Используй doc-комментарий @var: https://intellij-support.jetbrains.com/hc/en-us/community/posts/207025175-Using-to-phpdoc-to-specify-that-a-variable-represents-an-object-class
>>297070
Переменным надо давать осмысленные имена. Да, это не очень просто, но никто не обещал, что будет легко.
> [а-яё0-9a-z,.?!:;]+
Ты хотел написать "любой символ, кроме пробела"? Тогда надо использовать \\S
> $hui = preg_replace($regexp,"$1$3$5",$hui);
> $hui = preg_replace($regexp,"$1$3$5",$hui);
Почему повторяется 2 раза? Нужен как минимум комментарий.
> $l++;
> if (($letter==".")|($letter=="?")|($letter=="!")) {
> $letters[$l]=mb_strtoupper($letters[$l]);
Здесь есть риск, что элемента $l + 1 может не существовать. Лучше сделать переменную "предыдущий символ", и проверять ее.
А еще лучше - использовать preg_replace_callback.
Расстановку пробелов - нельзя ли было сделать там же, где и удаление пробелов?
Значит, не отвечай и не разводи флуд. PHP защищать не требуется, кому не нравится, может использовать любой другой язык.
>>296561
https://repl.it/@underbottom/repeat4
> str_replace("зде","сде",$changedText);
Это сломает слово "везде".
> ="/([^,а-я])(а|но)\\s/u";
Это сработает на слово "ночь".
https://repl.it/@underbottom/repeat3
> \\+
Внутри квадр. скобок спецсимволов всего 4: ] ^ - \ и плюс можно не экранировать. А вот минус - желательно.
> while ($count!=0) {
> $count--;
Можно было через implode/array_column вывести без цикла.
А так, решено верно.
https://repl.it/@underbottom/repeat2
Ок, верно.
https://repl.it/@underbottom/repeat1
> $number[0]=str_replace("7","8",$number);
Обращение к строке как к массиву не всегда работает. Например, если в начале будет стоять символ, кодирующийся несколькими байтами, то этот код приведет к появлению невалидной последовательности байт. Подробнее: https://github.com/codedokode/pasta/blob/master/php/strings-utf8.md
Лучше не использовать такое, так как трудно с ходу понять, правильный код или нет.
Также, программа не находит явные ошибки, например: 84951a234567 она считает правильным номером, как и 7 234 5678901. Проверь внимательно список номеров, и убедись, что все неправильные номера помечаются как неправильные.
https://repl.it/@underbottom/exam-after-chapter
Твоя программа срабатывает на все латинские символы (пример https://repl.it/repls/DifferentOccasionalPatch ). Но надо, чтобы она срабатывала на слова, состоящие из смеси двух алфавитов.
> $changedText=str_replace("y","у",$changedText);
> $changedText=str_replace("k","к",$changedText);
Лучше использовать strtr() и массив замен. Причем замену надо делать только в проблемных словах. Потому можно разбить текст на отдельные слова и проверять по одному, либо колдовать с preg_replace_callback.
Значит, не отвечай и не разводи флуд. PHP защищать не требуется, кому не нравится, может использовать любой другой язык.
>>296561
https://repl.it/@underbottom/repeat4
> str_replace("зде","сде",$changedText);
Это сломает слово "везде".
> ="/([^,а-я])(а|но)\\s/u";
Это сработает на слово "ночь".
https://repl.it/@underbottom/repeat3
> \\+
Внутри квадр. скобок спецсимволов всего 4: ] ^ - \ и плюс можно не экранировать. А вот минус - желательно.
> while ($count!=0) {
> $count--;
Можно было через implode/array_column вывести без цикла.
А так, решено верно.
https://repl.it/@underbottom/repeat2
Ок, верно.
https://repl.it/@underbottom/repeat1
> $number[0]=str_replace("7","8",$number);
Обращение к строке как к массиву не всегда работает. Например, если в начале будет стоять символ, кодирующийся несколькими байтами, то этот код приведет к появлению невалидной последовательности байт. Подробнее: https://github.com/codedokode/pasta/blob/master/php/strings-utf8.md
Лучше не использовать такое, так как трудно с ходу понять, правильный код или нет.
Также, программа не находит явные ошибки, например: 84951a234567 она считает правильным номером, как и 7 234 5678901. Проверь внимательно список номеров, и убедись, что все неправильные номера помечаются как неправильные.
https://repl.it/@underbottom/exam-after-chapter
Твоя программа срабатывает на все латинские символы (пример https://repl.it/repls/DifferentOccasionalPatch ). Но надо, чтобы она срабатывала на слова, состоящие из смеси двух алфавитов.
> $changedText=str_replace("y","у",$changedText);
> $changedText=str_replace("k","к",$changedText);
Лучше использовать strtr() и массив замен. Причем замену надо делать только в проблемных словах. Потому можно разбить текст на отдельные слова и проверять по одному, либо колдовать с preg_replace_callback.
Если хочешь поучиться ООП, у нас есть задачки, там ты статическими методами не решишь их:
- ООП-Будильник: https://phpclub.tech/pr/res/1232710.html#1263399
- ООП-Гостиница: https://phpclub.tech/pr/res/1082507.html#1097078
>>296548
Не надо копипастить куски регулярки. Ты можешь поместить выражение в круглые скобки и задать число повторов: (....){x}
Квантификаторы (+, звездочка, ?, {}) применяются к символу перед ними, но если поставить их после круглых скобок то они уже применяются ко всему выражению в скобках.
> ^(\\+|8)[\\s-()]*(7)?
Тут проблема: не гарантируется, что после + будет семерка. Надо перенести семерку внутрь скобок.
>>296428
https://ideone.com/phlsVk
> $homo=countPercent(40000,1.04,500,"Homocredit");
У тебя функция ничего не возвращает (в ней нет return), и в переменную запишется null. Сохранять и выводить его нет смысла.
Тут было бы логичнее возвращать параметры кредита в виде массива, и в месте вызова функции уже выводить их.
А то иначе твою функцию нельзя вызвать и что-то программно сделать с результатами (например, определить наименьшую цену).
Давай добавим такой пункт в условие: выведи в конце самый дешевый кредит, и сколько месяцев займет его выплата.
> if ($amountDebt >= 5000) {
> $amountDebt -= 5000;
5000 надо вынести в переменную для читаемость и простоты изменения.
Также, if можно заменить на min/max.
Если хочешь поучиться ООП, у нас есть задачки, там ты статическими методами не решишь их:
- ООП-Будильник: https://phpclub.tech/pr/res/1232710.html#1263399
- ООП-Гостиница: https://phpclub.tech/pr/res/1082507.html#1097078
>>296548
Не надо копипастить куски регулярки. Ты можешь поместить выражение в круглые скобки и задать число повторов: (....){x}
Квантификаторы (+, звездочка, ?, {}) применяются к символу перед ними, но если поставить их после круглых скобок то они уже применяются ко всему выражению в скобках.
> ^(\\+|8)[\\s-()]*(7)?
Тут проблема: не гарантируется, что после + будет семерка. Надо перенести семерку внутрь скобок.
>>296428
https://ideone.com/phlsVk
> $homo=countPercent(40000,1.04,500,"Homocredit");
У тебя функция ничего не возвращает (в ней нет return), и в переменную запишется null. Сохранять и выводить его нет смысла.
Тут было бы логичнее возвращать параметры кредита в виде массива, и в месте вызова функции уже выводить их.
А то иначе твою функцию нельзя вызвать и что-то программно сделать с результатами (например, определить наименьшую цену).
Давай добавим такой пункт в условие: выведи в конце самый дешевый кредит, и сколько месяцев займет его выплата.
> if ($amountDebt >= 5000) {
> $amountDebt -= 5000;
5000 надо вынести в переменную для читаемость и простоты изменения.
Также, if можно заменить на min/max.
Думаю, индексы использоваться не будут, так как в MySQL они используются, только если к значению поля не применяются функции. Проверить можно командой EXPLAIN.
> Слышал, что в PostgreSQL есть функциональные индексы, помогут ли они в этой ситуации?
Нет, они рассчитаны на ситуацию, когда ты применяешь функцию к значению поля: f(time). А у тебя есть еще неизвестный в момент создания индекса параметр - таймзона: f(time, tz)
В WHERE индексы можно использовать, если правильно постаивть преобразование:
WHERE time BETWEEN CONVERT... AND CONVERT...
>>296300
> И еще не понял как выводить в эчо обычную строку и переменную приведенную в тип интеджер в одних кавычках, не юзая точку
Это эхо же (произносится [ˈekəʊ] или [ˈɛkoʊ]): https://en.wiktionary.org/wiki/echo#English
echo "Текст $variable текст";
Если тебе надо что-то сделать с переменной, то это надо делать до echo. Выражения внутри кавычек писать нельзя.
Для округления лучше использовать round - он мощнее.
> $deposit<= 1000000;
При достижении ровно миллиона цикл продолжать не надо.
10 процентов лучше бы вынести в переменную для понятности и простоты изменения.
О, спасибо за подробный ответ!
>типы возвращаемых значений можно сужать, но не расширять (=они ковариантны)
Вот тут не понел. Как это - сужать типы возвращаемых значений?
Лол. Анон, все что ты описал, ему предлагали много постов назад.
И библиотека нормальная для запросов и экранирование параметров там было и жс-расширение.
Но беда в том, что чел совсем нюфаг и не осиливает
>Проблема с ArrayObject в том, что данные в него можно передать не только через конструктор, но и через методы.
Фигасе, о том, что туда данные можно и через методы передать я и забыл.
Таким образом может существовать объект, в котором будут данные другого типа.
>А ставя в них ограничения, ты нарушаешь принцип Лисков.
Это да. Даже не думал об этом. Код, работающий с ArrayObject, будет ожидать, что сможет нормально работать и с его потомком, а это не так.
Короче не нужно в потомке ломать обратную совместимость с базовым классом.
>Потому ArrayObject надо оборачивать:
То бишь, самому реализовать все нужные интерфейсы?
>Устанавливать пока что ничего не требуется, разве что редактор кода вроде Sublime Text 3, Notepad++, Visual Studio Code, Netbeans PHP или PhpStorm (с ним будет удобнее).
Котаны, подскажите нубу. Что из этих редакторов имеет возможности визуал студио для шарпа визуал студио. Т.е. сам дописывает названия операций, подсказывает функции из подключенных файлов. Ну вы понели. А то после шарпа как-то не привычно все руками набирать
Так по идее тогда любые доп-проверки аргументов метода нарушают принцип Лисков?
Типа вся необходимая информация о допустимых типах аргументов должна быть описана в их тайп-хинтах.
И если в метод передали то, что ему подоходит по тайпхинтам, значит он должен идеально работать.
Но это все же слишком идеальный манямир, так не получится писать.
>str_replace вырезает эту подстроку в любом месте, а не только в начале строки.
Если надо только по краям строки обрезать, то лучше использовать trim().
Вообще, похоже, что он роутер собирает. В сети куча гайдов, но надо сюда припереться с такими нубскими вопросами.
>Лучше всего - регуляркой
Регулярки лучше вообще не втыкать пока не возникнет такой ситуации, когда без них никак, тк они довольно медленные.
>Как это - сужать типы возвращаемых значений?
Если функция работает с какими-то свойствами объекта, то и в потомке этого объекта эти свойства будут присутствовать - их не выкинешь из класса.
Думаю, он это имел ввиду.
Кажется netbeans умеет
Если проблемы нет с оперативой (хотя бы 8гб имеется), то phpstorm это лучшее что есть. Он умеет всё что ты перечислил и гораздо больше.
if(!defined("MIRROR")){die("Hacking attempt!");}
if(!@mysql_connect("127.0.0.1", "en_gmb", "S8aHq4aN")){
die("Error connect!!!");
}
if(!@mysql_select_db("en_gmb")){
die(mysql_error());
}
}else{
if(!defined("MIRROR")){die("Hacking attempt!");}
if(!@mysql_connect("localhost", "gmb", "S8aHq4aN")){
die("Error connect!!!");
ПАМАХИТЕ!!!!!!
на елсо выдает ошибку, пхпмайадмин, ишрался с рутами и локалхостами нихуя не помогло. ЧЯДНТ???
>ПАМАХИТЕ!!!!!!
Это что вообще за кусок говна и для чего он нужен?
По-нормальному установить соединение с бд религия не позволяет?
PDO использовать? Отлавливать исключения? Не городить говно из else if ?
Здесь сужать - значит указывать наследника типа. Если метод в классе-родителе возвращает A, то метод в наследнике в теории может возвращать B (B extends A). Но по факту в PHP это пока не работает.
крч дали сайт сиди грызи его без какой-либо инфы, развернул xampp пытаюсь локально запустить, перерыл все файлы сайта нашел это это вроде как часть кода отвечающая за конетк к бд, и как бы тут локальная версия встает, базы в пхпмайдмин импортировал, я вообще хз че тут не так.
Попробуй убрать @ и либо смотреть логи, либо, если ты запускаешь не на продакшене, включить display_errors. Должно вывестись какое-то сообщение об ошибке.
пароля нет, логин менял я даже в пхп создал учетку с таким же именем как в коде вообще нихуя
>мои задачи игнорят
Я свои вообще не выкладывал. Иди дальше просто - ОПу деньги не платят, чтобы он лабы наши проверял.
Выхлоп скрипта соответствует условию? Понял как работать с регулярками и языком? Катись дальше значит.
неа( просто ошибка соединения
>5.6
Говорят, что с 5.4 надо было скатываться. Хотя я толком не знаю - через PDO пишу.
Вообще глянь:
С какой ошибкой валится, на каком моменте? Поотключай подавление ошибок и измени строки на выводе ошибок - будешь знать хоть где отваливается.
версия поддерживает некоторые страницы работаю а вот при запуске идекса вылазет эта залупа
Мне не зашла эта годнота - слишком много внимания мелочам уделяется.
Да и в пизду эту вёрстку - я у мамы погроммист.
if(!defined("MIRROR")){die("Hacking attempt!");}
if(!@mysql_connect("127.0.0.1", "en_gmb", "S8aHq4aN")){
die("Error en_gmb connect!!!");
}
if(!@mysql_select_db("en_gmb")){
die(mysql_error());
}
}else{
if(!defined("MIRROR")){die("Hacking attempt!");}
if(!@mysql_connect("localhost", "gmb", "S8aHq4aN")){
die("Error gmb connect!!!");
Вот этот скрипт скопипасти и запусти. Результат выложи.
if(!defined("MIRROR")){die("Hacking attempt!");}
if(!@mysql_connect("127.0.0.1", "en_gmb", "S8aHq4aN")){
die("Error en_gmb connect!!!");
}
if(!@mysql_select_db("en_gmb")){
die(mysql_error());
}
}else{
if(!defined("MIRROR")){die("Hacking attempt!");}
if(!@mysql_connect("127.0.0.1", "gmb", "S8aHq4aN")){
die("Error gmb connect!!!");
Теперь через этот попробуй.
>>293208
>>287151
Это не специально, просто видимо, я пока не успел до них дойти.
Опечаточники: https://www.ideone.com/XKbY9H
Можно было упростить себе жизнь, и просто определять язык по первой букве или по тому, букв какого алфавита больше. Так как в задаче по сути требуется просто искать слова, состоящие из букв 2 алфавитов, и точности определения языка не требуется.
> return 0;
> } else {
> return false;
Не очень удачный выбор, так как false и 0 легко спутать, если использовать == вместо ===. Лучше было выбрать варианты 0, 1, 2 или -1, 0, 1. Или строки 'ru', 'en', null. Или даже завести константы с понятными именами (вроде LANG_RUSSIAN).
> preg_replace("/{$word}/ui", $fixedWord, $text);
Лучше было использовать str_replace, а то если в слове есть спецсимволы, то они будут интерпретированы как часть регулярки.
А так, в остальном верно.
Shift: https://repl.it/repls/RequiredColorlessUnits
?> в конце программы ставить не стоит. Он не требуется, и пользы никакой не приносит.
Решено верно.
Yoda Speak: https://repl.it/repls/SalmonGoldenExpertise
Верно.
Числа прописью: https://repl.it/repls/TrustyNegativeJavabytecode
> if ($lastDigit == 0) {
> return $word5;
Это можно было не писать, там ведь в конце в else это значение возвращается.
> if (($ten = floor($tensAndUnits / 10) * 10) != 0)
Не очень хорошая идея совмещать if и присваивание, ухудшает читабельность.
А так, верно.
Калькулятор: https://repl.it/repls/StingyLargeState
Тут тоже все верно.
>>293208
>>287151
Это не специально, просто видимо, я пока не успел до них дойти.
Опечаточники: https://www.ideone.com/XKbY9H
Можно было упростить себе жизнь, и просто определять язык по первой букве или по тому, букв какого алфавита больше. Так как в задаче по сути требуется просто искать слова, состоящие из букв 2 алфавитов, и точности определения языка не требуется.
> return 0;
> } else {
> return false;
Не очень удачный выбор, так как false и 0 легко спутать, если использовать == вместо ===. Лучше было выбрать варианты 0, 1, 2 или -1, 0, 1. Или строки 'ru', 'en', null. Или даже завести константы с понятными именами (вроде LANG_RUSSIAN).
> preg_replace("/{$word}/ui", $fixedWord, $text);
Лучше было использовать str_replace, а то если в слове есть спецсимволы, то они будут интерпретированы как часть регулярки.
А так, в остальном верно.
Shift: https://repl.it/repls/RequiredColorlessUnits
?> в конце программы ставить не стоит. Он не требуется, и пользы никакой не приносит.
Решено верно.
Yoda Speak: https://repl.it/repls/SalmonGoldenExpertise
Верно.
Числа прописью: https://repl.it/repls/TrustyNegativeJavabytecode
> if ($lastDigit == 0) {
> return $word5;
Это можно было не писать, там ведь в конце в else это значение возвращается.
> if (($ten = floor($tensAndUnits / 10) * 10) != 0)
Не очень хорошая идея совмещать if и присваивание, ухудшает читабельность.
А так, верно.
Калькулятор: https://repl.it/repls/StingyLargeState
Тут тоже все верно.
Подача и детализация.
Хотя могу и придираться - мне легче говнокод вордпресса, который перемешан с хтмл, разобрать, чем по мишеням из CSS стрелять - какие-то совершенно ебанутые конструкции там. Излишне это, лучше формы учили бы править - учили на реальных задачах, а не на выдуманных.
вот и я хз
Ок, понял, спасибо
>Дан текст, который по идее должен быть номером телефона в виде 8-(911)-506 56 56 (т.е. человек может ввести не только цифры, но и скобки, минусы, может что-то еще). Но в реальности, пользователь может вместо номера написать что угодно. Напиши скрипт для проверки правильности введенного номера («8(911)-506 56 56» — правильный номер, «8-911-50-656-56» — правильный, «89115065656» — правильный, «02» — неправильный, «89115065656 позвать Люду» — неправильный).
ссылка на саму базу телефонов - https://regex101.com/r/qF7vT8/3
Что я накрутил - ([\s\-()]\+7|8)([\s\-()][0-9]){10}$. Не ищет номер с пробелом между + и 7. Очевидным решение будет написать \s* между ними и тогда всё заработает, но сомневаюсь, что это правильное решение.
Буду очень благодарен.
Идея такая: в браузеер на странице поле 100х100. По нему можно клавишами гонять "игрока" (квадратик другого цвета). Рандомно в квадратах поля возникают ресурсы (для добавления в "инвентарь" достаточно вступить в тот же квадрат) и "мобы" - квадраты другого цвета, которые можно атаковать.
Пикрелейтед.
^([\s\-()](\+[\s\-()]7|8))([\s\-()]*[0-9]){10}$
Я видимо изобрёл велосипед, но это работает, но такое ощущение, что можно проще.
Просто интересно. ОП сказал:
>Ты можешь поместить выражение в круглые скобки и задать число повторов: (....){x}
Я так и не допер как. Либо у всех плохо с регуляркой и я вздохну спокойно, либо я безнадёжен.
https://repl.it/@underbottom/povtorenie1 - (исправление пробелов и заглавные буквы) было тяжело, но я разобрался, как работает preg_replace_callback. Видимо на первых порах тяжело вычленять и усваивать инфу из мануала(либо я тупой). Я очень перемудрил с регуляркой и поэтому приходилось 2 раза прогонять, что бы успловия подошли. Сейчас вроде лаконично. Подтянул знания по регулярке и теперь понимаю более-менее, что к чему.
https://repl.it/@underbottom/repeat4 - поправил недочёты.
https://repl.it/@underbottom/repeat3 - Исправил. Я перемудрил.
https://repl.it/@underbottom/value-credit - долго думал, как реализовать вычисления наименьшей цены. Оказалось min сравнивая массивы берёт только валью нулевой строки.(пытался ставить миллион дней результат не поменялся).
https://repl.it/@underbottom/ExcitingUnimportantExperiments - переделал регулярку, уверен, что нужно не так. Но вроде работает.
https://repl.it/@underbottom/repeat1 - переделал регулярку и способ решения.
https://repl.it/@underbottom/exam-after-chapter - опять перемудрил. Исправил.
https://repl.it/@underbottom/yodashuffler
Ок, вопросы:
- ты знаешь, что такое квантификаторы и можешь вспомнить пару примеров?
- ты знаешь, что значат фигурные скобки в регулярке?
- ты знаешь, что значат круглые скобки?
Если нет, поищи ответы, например, тут в мануале: http://php.net/manual/ru/reference.pcre.pattern.syntax.php
Если что-то непонятно, задавай уточняющие вопросы.
Теперь возьмем такую задачу: найдите в тексте последовательность 1 или более чисел, разделенную запятыми. Пример текста: "в 1923, 1934, 1935 годах". Программа должна найти "1923, 1934, 1935".
Как ее решить регуляркой? Попробуем пойти "снизу вверх", от простого к сложному.
Напишем выражение для того, чтобы найти любое число. Число - это 1 или более любых цифр. Напиши это выражение, если не догадался, то ответ: "Любая цифра" в регулярке записывается как \d или [0-9]. "1 или более" повторение задается добавлением после нее квантификатора "плюс". Получается, ...
Теперь, имея выражение для поиска одного числа, напишем выражение для поиска нескольких чисел. Его можно записать так:
число (пробелы , пробелы число) *
Здесь использованы круглые скобки, чтобы квантификатор звездочка применялся к выражению в скобках, а не к одному символу перед ним.
То есть мы ищем число, за которым может идти 0 или более последовательностей из ( пробелов, запятой и еще одного числа).
"Число" - это выражение, которое мы составили выше. "пробелы" - 0 или более пробелов - это \s*. Собрав все вместе, получим ответ.
Попробуй решить эту задачку.
Ок, вопросы:
- ты знаешь, что такое квантификаторы и можешь вспомнить пару примеров?
- ты знаешь, что значат фигурные скобки в регулярке?
- ты знаешь, что значат круглые скобки?
Если нет, поищи ответы, например, тут в мануале: http://php.net/manual/ru/reference.pcre.pattern.syntax.php
Если что-то непонятно, задавай уточняющие вопросы.
Теперь возьмем такую задачу: найдите в тексте последовательность 1 или более чисел, разделенную запятыми. Пример текста: "в 1923, 1934, 1935 годах". Программа должна найти "1923, 1934, 1935".
Как ее решить регуляркой? Попробуем пойти "снизу вверх", от простого к сложному.
Напишем выражение для того, чтобы найти любое число. Число - это 1 или более любых цифр. Напиши это выражение, если не догадался, то ответ: "Любая цифра" в регулярке записывается как \d или [0-9]. "1 или более" повторение задается добавлением после нее квантификатора "плюс". Получается, ...
Теперь, имея выражение для поиска одного числа, напишем выражение для поиска нескольких чисел. Его можно записать так:
число (пробелы , пробелы число) *
Здесь использованы круглые скобки, чтобы квантификатор звездочка применялся к выражению в скобках, а не к одному символу перед ним.
То есть мы ищем число, за которым может идти 0 или более последовательностей из ( пробелов, запятой и еще одного числа).
"Число" - это выражение, которое мы составили выше. "пробелы" - 0 или более пробелов - это \s*. Собрав все вместе, получим ответ.
Попробуй решить эту задачку.
CSS: The missing manual
В теории - могут как нарушать, так и не нарушать. Идея в том, чтобы обеспечивать совместимость кода, работающего с базовым классом, с наследниками.
Но здесь другая ситуация. У нас нет кода, заточенного на работу с базовым классом и потому не требуется совместимости. У нас задача - создавать контейнеры для разных типов данных (имитировать generic types). И потому мы можем от принципа Лисков отступить.
1) Напишу, как я понимаю это. Квантификаторы - условия задаваемые выражению внутри скобок. Например: ^[0-9] - строка начинается с цифры, [\d]$ - строка заканчивается на цифру, [0-9]? - может встретиться цифра.
2) Фигурные скобки. Внутри них задаётся число повторений от n до m. Например, {3,5} - от 3 до 5 или {0,} - от 0 до бесконечности.
3) Круглые скобки - объединяют набор символов и квантификаторов в один элемент(тупая формулировка наверное). Например: (\S+[.?!]) - найдёт последнее слово в предложении с знаком препинания. Так же ими можно манипулировать с текстом. допустим:
preg_replace("/(\S+[.?!])\s([\S])/", "$1$2",$text); - уберёт пробел между концом предложения и началом следующего.
задачка. Число находим вот так [\d]+. Найти число с запятой [\d]+(\,\s).
Ты тут не смотрел пример кода? https://github.com/codedokode/pasta/blob/master/arch/mvc.md
ну и это можно глянуть: https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md
Классы добавляются по мере необходимости. Надо загружать/сохранять сущности в БД - делаем класс, надо генерировать URL - делаем класс, и тд. Если не нужен - то не делаем.
Также, ты можешь показать кусочек кода (не слишком много), я бы мог подсказать, чем он плох или хорош.
> Открыл один видеоролик, в котором мужик то ли блог делает, то ли еще какую залупу, так у него там для вывода какой-то хуеты 5 или 6 файлов, куча классов ебаных.
Наверно ролик рассчитан на тех, кто изучил теорию про эти классы?
Ты удивишься, но твои мысли верны - незачем писать избыточный код, я до ооп еще не дошел, но мне это очевидно. Однако, есть же определенные зарекомендовавшие себя методики - и почему бы их не придерживаться. Я как ньюфаг отдаленно понимаю зачем нужон MVC.
> public function __construct(PDO $pdo) { ... }
>(PDO $pdo)
Тут у нас что именно передаётся? Просто коннект к БД?
Для одного коннекта надо целый класс пилить? Чёт писанины много получается.
мимовкатывальщик
>У нас нет кода, заточенного на работу с базовым классом
Так любой код, работающий с ArrayObject, будет ожидать, что сможет работать и с его потомком. Даже если сейчас такого нет, может появится в будущем. И вовсе не факт, что это я его напишу.
Может у кого-то будет годная библиотека для работы с ArrayObject, а тут этот чел смотрит: "Опа, что это тут у нас? Да это же потомок ArrayObject! Я смогу с ним работать с помощью той либы, что работаю с обычным ArrayObject'ами."
Передает объект, а ему: "Соси хуй, быдло".
Нехорошо так делать, теперь я это понял.
Раз я не могу обеспечить совместимость с базовым классом, то и нехуй от него наследоваться. Лучше самому реализовать нужные интерфейсы.
Теоретически тут может помочь закрытое наследование. Типа когда класс фактически наследуется от базового, но все его унаследованные методы становятся закрытыми, вне зависимости от настроек в базовом.
Тогда внешний код не будет знать, что класс является потомком какого-то другого.
Вроде в плюсах есть что-то такое.
Но звучит как-то бредово, не даром такой хуйни нигде почти нет.
>и потому не требуется совместимости. У нас задача - создавать контейнеры для разных типов данных (имитировать generic types).
Очень рад, что ты понимаешь, что я пытаюсь сделать, не то что здешние школьники.
>И потому мы можем от принципа Лисков отступить.
Ну вот хуй знает, ты меня прям с этим принципом озадачил.
П - проектирование приложения.
Все учат классы половчее пилить, но никто не учит как оно должно взаимодействовать изнутри и как это распланировать ещё до всякого кода. Опытные - умею, а новички ебутся.
Самого заебало.
Рад, что ты меня понимаешь, анончик. Седня постараюсь продумать все и составить пошаговый план, а завтра уже начну свою пятую или шестую попытку написать студентов.
>>298105
>Ты тут не смотрел пример кода? https://github.com/codedokode/pasta/blob/master/arch/mvc.md
>ну и это можно глянуть: https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md
Я кучу раз уже читал твои статьи.
>Наверно ролик рассчитан на тех, кто изучил теорию про эти классы?
Я до просмотра этого ролика, посмотрел серию видосов от этого же автора по ООП. Ниче охуеть нового не узнал. От того, что я в сотый раз услышу "объект - это экземпляр класса" или еще раз послушаю про инкапсуляцию полиморфизм наследование, ничего не изменится. Я вроде бы все это понимаю в теории, но полноценно использовать на реальном проекте не получается. Наверное, плохо стараюсь. Единственное, что я не понимаю, это исключения, всякие try catch. твой урок по ним уже читал. Как будто после каждого пука их вставляют.
Подскажите плз, как отнять от одной даты другую, если одна получена в базе данных через функцию now(), а вторая -- date("Y-m-d H:i:s")?
По итогу они имеют один и тот же вид, но date_diff не работает
>Попробую последний раз сделать список студентов. Если не получится, то хуй знает че делать. На псевдоООП почти сделал студентов и половину файлообменника.
Ну охуеть теперь, написал полторы строки кода и чего-то ждёт.
Чтобы реально догнать, для чего нужно городить все эти тонны абстракций и какую роль играют паттерны - надо реально на своем опыте столкнуться с проблемами, которые они решают.
Чтобы ты, глядя на свой код, подумал: "Аааах блять, а вот если бы я сделал так-то и так-то, сейчас все нормально было бы". И потом в следующем проекте сделать уже правильно.
Этого из книжек не почерпнешь. Ты просто не поймёшь какие проблемы решает тот или иной подход, да и какие проблемы вообще бывают.
Чужие шишки не болят.
Короче набивай потихоньку свои 10к часов.
https://www.youtube.com/watch?v=OaDhY_y8WTo
Зачем и почему он пытается искать PDO в этих неймспейсах? Он что, теперь вообще каждый класс будет искать там, даже встроенные? Что за наркомания?
Мне теперь ещё одного наследника этого PDO описывать, чтобы положить в конструктор? Нельзя по-нормальному зделоть, чтобы сразу работало, без сотен строк костылей?
Спасибо.
Строка:
class DataBase extends \PDO
Выдаёт:
Fatal error: Uncaught exception 'Exception' with message 'Unable to open Core/Lib/PDO.php.' in C:\OSPanel\domains\mvc.loc\core\lib\Helpers.php:15 Stack trace: #0 [internal function]: Helpers::ClassLoader('Core\\Lib\\PDO') #1 C:\OSPanel\domains\mvc.loc\core\lib\DataBase.php(39): spl_autoload_call('Core\\Lib\\PDO') #2 C:\OSPanel\domains\mvc.loc\index.php(25): Core\Lib\DataBase->__construct('conf/db.ini') #3 {main} thrown in C:\OSPanel\domains\mvc.loc\core\lib\Helpers.php on line 15
Всё понял - в каждой ссылке на класс надо указывать, а у меня там понаписано.
Алсо, у меня теоретический вопрос:
Делаю микрофреймворк для изучения MVC и не понимаю как там должна работать обработка полученных данных.
Вот я через контроллер вызвал модель и выдал всё это на шаблон. Например форму заполнения. Как теперь мне поступить с полученными данными? Просто вызвать нужный метод модели?
Понимаю, что вопрос нубский, но хотелось бы делать "как надо", а не "как получится".
PDO это встроенный в PHP класс (точнее, не в PHP, а в расширение pdo). Его описывать не требуется,он уже есть.
Он представляет соединение с БД. Разве не логично, что мы передаем соединение с БД в класс, которому надо работать с базой данных? Как иначе-то?
>>298129
Я предполагал, что ты не используешь наследование от ArrayObject, а делегирование (хранишь ArrayObject в приватном поле), или даже вообще не используешь его.
> Так любой код, работающий с ArrayObject, будет ожидать, что сможет работать и с его потомком.
Тем не менее, мы намеренно отказываемся от соблюдения принципа Лисков тут, чтобы реализовать имитацию generic types. А если мы не используем наследование от ArrayObject, то такой проблемы вообще нет.
> Лучше самому реализовать нужные интерфейсы.
Можно и так.
>>298131
1) почитайте мой урок по MVC
2) решите задачки про ООП-гостиницу или ООП-будильник
3) почитайте мой урок по DI, паттернам работы с БД
4) решите задачку про студентов
5) поизучайте фреймворки и подумайте, зачем там использованы такие-то классы и применен такой-то подход
Вот так примерно у вас и появится представление (может быть).
PDO это встроенный в PHP класс (точнее, не в PHP, а в расширение pdo). Его описывать не требуется,он уже есть.
Он представляет соединение с БД. Разве не логично, что мы передаем соединение с БД в класс, которому надо работать с базой данных? Как иначе-то?
>>298129
Я предполагал, что ты не используешь наследование от ArrayObject, а делегирование (хранишь ArrayObject в приватном поле), или даже вообще не используешь его.
> Так любой код, работающий с ArrayObject, будет ожидать, что сможет работать и с его потомком.
Тем не менее, мы намеренно отказываемся от соблюдения принципа Лисков тут, чтобы реализовать имитацию generic types. А если мы не используем наследование от ArrayObject, то такой проблемы вообще нет.
> Лучше самому реализовать нужные интерфейсы.
Можно и так.
>>298131
1) почитайте мой урок по MVC
2) решите задачки про ООП-гостиницу или ООП-будильник
3) почитайте мой урок по DI, паттернам работы с БД
4) решите задачку про студентов
5) поизучайте фреймворки и подумайте, зачем там использованы такие-то классы и применен такой-то подход
Вот так примерно у вас и появится представление (может быть).
> Я вроде бы все это понимаю в теории, но полноценно использовать на реальном проекте не получается.
Ну так не используй, пиши обычные классы без наследования и полиморфизма (а инкапсуляцию используй). Если ты решал задачи на ООП вроде ООП-гостиницы или ООП-будильника, то с пониманием инкапсуляции проблемы быть не должно.
Я, наоборот, не понимаю, чего тут сложного. Нам надо как-то представить Студента в коде - делаем для него класс. Надо сохранять/загружать их из БД - делаем для этого класс StudentTableDataGateway (описан в уроке про работу с БД). И, может, нам понадобится еще класс с вспомогательными методами для генерации URL. Вот и все, задача про студентов решена. Какой еще полиморфизм? Оставь его авторам учебников по ООП или разбери компонент Form в Symfony, чтобы увидеть его использование.
Кстати, сейчас наверно рановато, но позже я бы советовал разобрать код Symfony Forms, чтобы изучить пример сложного ООП кода, где есть и инкапсуляция, и наследование, и полиморфизм, и некоторые паттерны. А насчет авторов с ютуба - я их код не видел, может он сам по себе неправильный, кто знает.
> Единственное, что я не понимаю, это исключения, всякие try catch.
Если функция или метод не может выполнить свою задачу или дать точный, актуальный ответ - она выбрасывает исключение. Пример: функция расчет цены после скидки выбрасывает исключение, если ей передать скидку меньше 0% или больше 100%. Заодно можно выкинуть исключение при передаче отрицательной цены:
function calcPriceAfterDiscount(float $price, int $discount = 0): float
{
if ($discount < 0 || $discount > 100) {
throw new \InvalidArgumentException("Discount must be between 0 and 100, $discount given");
}
if ($price < 0) {
throw ....;
}
return ...
}
Разве это сложно? И, кстати, а что бы ты делал, если функции переданы неправильные значения аргументов?
Ловить исключения нужно гораздо реже, обычно вообще не требуется. Если вдруг это нужно, то можно использовать свой класс исключений, чтобы ловить только такой тип исключений и никакие другие. Пример с этой функцией выше. Допустим, мы принимаем данные для расчета из формы и при ошибке хотим отобразить понятный текст. Мы заменяем в примере выше станждартное исключение \InvalidArgumentException на свой класс CalcPriceException, который надо описать. А затем пишем код:
$price = floatval($_GET['price'] ?? 0);
$discount = intval($_GET['discount'] ?? 0);
try {
$result = calcPriceAfterDiscount($price, $discount);
echo "Результат: $result\n";
} catch (CalcPriceException $e) {
echo "Ошибка: {$e->getMessage()}\n";
exit(0);
}
Но, как я написал выше, ловить исключения требуется редко.
> Я вроде бы все это понимаю в теории, но полноценно использовать на реальном проекте не получается.
Ну так не используй, пиши обычные классы без наследования и полиморфизма (а инкапсуляцию используй). Если ты решал задачи на ООП вроде ООП-гостиницы или ООП-будильника, то с пониманием инкапсуляции проблемы быть не должно.
Я, наоборот, не понимаю, чего тут сложного. Нам надо как-то представить Студента в коде - делаем для него класс. Надо сохранять/загружать их из БД - делаем для этого класс StudentTableDataGateway (описан в уроке про работу с БД). И, может, нам понадобится еще класс с вспомогательными методами для генерации URL. Вот и все, задача про студентов решена. Какой еще полиморфизм? Оставь его авторам учебников по ООП или разбери компонент Form в Symfony, чтобы увидеть его использование.
Кстати, сейчас наверно рановато, но позже я бы советовал разобрать код Symfony Forms, чтобы изучить пример сложного ООП кода, где есть и инкапсуляция, и наследование, и полиморфизм, и некоторые паттерны. А насчет авторов с ютуба - я их код не видел, может он сам по себе неправильный, кто знает.
> Единственное, что я не понимаю, это исключения, всякие try catch.
Если функция или метод не может выполнить свою задачу или дать точный, актуальный ответ - она выбрасывает исключение. Пример: функция расчет цены после скидки выбрасывает исключение, если ей передать скидку меньше 0% или больше 100%. Заодно можно выкинуть исключение при передаче отрицательной цены:
function calcPriceAfterDiscount(float $price, int $discount = 0): float
{
if ($discount < 0 || $discount > 100) {
throw new \InvalidArgumentException("Discount must be between 0 and 100, $discount given");
}
if ($price < 0) {
throw ....;
}
return ...
}
Разве это сложно? И, кстати, а что бы ты делал, если функции переданы неправильные значения аргументов?
Ловить исключения нужно гораздо реже, обычно вообще не требуется. Если вдруг это нужно, то можно использовать свой класс исключений, чтобы ловить только такой тип исключений и никакие другие. Пример с этой функцией выше. Допустим, мы принимаем данные для расчета из формы и при ошибке хотим отобразить понятный текст. Мы заменяем в примере выше станждартное исключение \InvalidArgumentException на свой класс CalcPriceException, который надо описать. А затем пишем код:
$price = floatval($_GET['price'] ?? 0);
$discount = intval($_GET['discount'] ?? 0);
try {
$result = calcPriceAfterDiscount($price, $discount);
echo "Результат: $result\n";
} catch (CalcPriceException $e) {
echo "Ошибка: {$e->getMessage()}\n";
exit(0);
}
Но, как я написал выше, ловить исключения требуется редко.
А ты мануал точно читал? В мануале написано:
> date_diff — Псевдоним DateTime::diff()
Переходим к классу DateTime:
> public DateInterval DateTime::diff ( DateTimeInterface $datetime2 [, bool $absolute = FALSE ] )
Эта функция работает с объектами, реализующими DateTimeInterface, а не строками.
>>298363
А зачем наследоваться от PDO? Что тебя в нем не устраивает?
> Зачем и почему он пытается искать PDO в этих неймспейсах?
Ты урок или мануал по нейсмпейсами точно прочел? Там описано черным по белому, как работают неймспейсы.
Неймспейс это просто часть полного имени класса. То есть, сокращенное имя это SomeClass, а полное - SomeNamespace\SomeClass.
Если в начале файла стоит конструкция namespace X, то по умочанию все имена классов относятся к этому неймспейсу, то есть если ты пишешь new Y\Z(), то имеется в виду класс X\Y\Z.
PDO находится к корневом нейсмпейсе и его полное имя PDO, но в коде перед ним надо кое-что писать, чтобы PHP не подумал, что он в текущем неймспейсе. Перечитай мануал внимательно, в частности про ключевое слово namespace.
Вот это, например:
- http://php.net/manual/ru/language.namespaces.fallback.php
- http://php.net/manual/ru/language.namespaces.importing.php
Или мой урок по неймспейсам.
> Мне теперь ещё одного наследника этого PDO описывать, чтобы положить в конструктор? Нельзя по-нормальному зделоть, чтобы сразу работало, без сотен строк костылей?
Надо перечитать внимательно мануал.
А ты мануал точно читал? В мануале написано:
> date_diff — Псевдоним DateTime::diff()
Переходим к классу DateTime:
> public DateInterval DateTime::diff ( DateTimeInterface $datetime2 [, bool $absolute = FALSE ] )
Эта функция работает с объектами, реализующими DateTimeInterface, а не строками.
>>298363
А зачем наследоваться от PDO? Что тебя в нем не устраивает?
> Зачем и почему он пытается искать PDO в этих неймспейсах?
Ты урок или мануал по нейсмпейсами точно прочел? Там описано черным по белому, как работают неймспейсы.
Неймспейс это просто часть полного имени класса. То есть, сокращенное имя это SomeClass, а полное - SomeNamespace\SomeClass.
Если в начале файла стоит конструкция namespace X, то по умочанию все имена классов относятся к этому неймспейсу, то есть если ты пишешь new Y\Z(), то имеется в виду класс X\Y\Z.
PDO находится к корневом нейсмпейсе и его полное имя PDO, но в коде перед ним надо кое-что писать, чтобы PHP не подумал, что он в текущем неймспейсе. Перечитай мануал внимательно, в частности про ключевое слово namespace.
Вот это, например:
- http://php.net/manual/ru/language.namespaces.fallback.php
- http://php.net/manual/ru/language.namespaces.importing.php
Или мой урок по неймспейсам.
> Мне теперь ещё одного наследника этого PDO описывать, чтобы положить в конструктор? Нельзя по-нормальному зделоть, чтобы сразу работало, без сотен строк костылей?
Надо перечитать внимательно мануал.
Зачем вообще наследоваться от PDO?
>>298406
В шаблон ты передаешь данные для отображения. Если это форма - то информацию в форме и список ошибок. Они могут быть представлены в виде массива или объекта. И в шаблоне ты выводишь данные из них. Не забудь также прочесть про XSS уязвимость (у меня есть урок) и защититься от нее.
Работа с формами тоже описана у меня в отдельном уроке. Если у нас для формы написан отдельный класс, и мы хотим максимум ООП, то это может выглядеть так (допустим, речь о редактировании товара):
$data = new Product;
$form = new ProductForm($product);
if (метод запроса POST) {
// Разбирает пришедший запрос и проверяет на CSRF
$form->parseRequest($_POST);
$errors = $form->validate();
if (!$errors) {
сохраняем $product в БД;
редиректим;
return;
}
вызываем шаблон, передавая ему $data, $form, $errors.
Если мы хотим поменьше ООП, то можно, например, не делать ProductForm:
$data = new Product;
$this->parseRequest()
if (метод запроса POST) {
// Разбирает пришедший запрос и проверяет на CSRF
$this->parseRequest($data, $_POST);
$errors = $productValidator->validate($product);
if (!$errors) {
сохраняем $product в БД;
редиректим;
return;
}
....
Не забудь про защиту от CSRF при работе с формами.
Также, я дополнил урок по формам, советую перечитать: https://github.com/codedokode/pasta/blob/master/forms.md
Зачем вообще наследоваться от PDO?
>>298406
В шаблон ты передаешь данные для отображения. Если это форма - то информацию в форме и список ошибок. Они могут быть представлены в виде массива или объекта. И в шаблоне ты выводишь данные из них. Не забудь также прочесть про XSS уязвимость (у меня есть урок) и защититься от нее.
Работа с формами тоже описана у меня в отдельном уроке. Если у нас для формы написан отдельный класс, и мы хотим максимум ООП, то это может выглядеть так (допустим, речь о редактировании товара):
$data = new Product;
$form = new ProductForm($product);
if (метод запроса POST) {
// Разбирает пришедший запрос и проверяет на CSRF
$form->parseRequest($_POST);
$errors = $form->validate();
if (!$errors) {
сохраняем $product в БД;
редиректим;
return;
}
вызываем шаблон, передавая ему $data, $form, $errors.
Если мы хотим поменьше ООП, то можно, например, не делать ProductForm:
$data = new Product;
$this->parseRequest()
if (метод запроса POST) {
// Разбирает пришедший запрос и проверяет на CSRF
$this->parseRequest($data, $_POST);
$errors = $productValidator->validate($product);
if (!$errors) {
сохраняем $product в БД;
редиректим;
return;
}
....
Не забудь про защиту от CSRF при работе с формами.
Также, я дополнил урок по формам, советую перечитать: https://github.com/codedokode/pasta/blob/master/forms.md
Ещё подскажите, как лучше находить решения для поставленных задач. Я переношу на лист бумаги и вроде получше. Кто как справляется?
>MVC
Хуйня. Трех компонентов недостаточно для полноценного описания.
Постепенно будут возникать куски кода, которые к моделям не отнесешь, но они повторяются в разных контроллерах.
Поэтому нужен еще один компонент
Ок, кто поумнее, по крайней мере подумает о переходе с php на ruby.
Иди нахер со своими срачами и "Руби хороший, дрочу на руби." 5 пишу на руби, язык как язык. Вот только на PHP фриланса в 20 раз больше. Я даже не преувеличиваю, а скорее преуменьшаю. А для рубиста работу найти капец сложно. Так что нет. Руби -это как C++, вроде и элитно, а в тоже время - говно без задач.
Я не срача ради, а для тех, кто пытается вкатиться. Конечно они начинают с php. Так вот, если php им не заходит, то пусть попробуют что-нибудь другое.
Я не против. Создай тред и гайд как наш самый лучший в мире ОП. Создай тред где ты будешь помогать к ньюфагам и к тебе подтянутся. А так у рубистов весьма токсичное сообщество. А каждый раз что я ндваче в рубитреде что-то спрашивал - получал ответы которые выставляли меня тупым. Согласись не очень мотивирует?
потому что не надо сидеть в треде рубистов, а смотреть то, что говорят о языке и сообществе его основатели и погуглить что там с рельсами в 2к18, также есть конфа в телеге
>потому что не надо сидеть в треде рубистов, а смотреть то, что говорят о языке...
Чел, ТЫ ТО НАМ ТОГДА ЗАЧЕМ?
Ну-ка ткни меня где ты писал зачем ты тут? А то, пока я не вижу.
Щас бы переходить с говна на засохшую мочу
Аноны, что не так?
Здарова, я тоже новенький. Я вот че понял. По сути знания самого языка, самого синтаксиса не так важны, как знания алогоритмов, умения гуглить решение твоей задачи, т.к. почти все решения уже есть в интернетах. Обоссыте если не прав.
>По сути знания самого языка, самого синтаксиса не так важны, как знания алогоритмов
А на каком языке ты собираешься эти алгоритмы описывать, если знания синтаксиса не важны? Его вообще не знать, а понимать надо. Подсознательно.
прекрасно тогда.
хелп....
Вот ошибка
Fatal error: Uncaught PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '-6' at line 1
LIMIT/OFFSET отрицательные наверно. Сдампь, какой запрос получается и проверь.
Также, твой код надо срочно переделать - в нем, похоже, завелась SQL инъекция: https://github.com/codedokode/pasta/blob/master/security/sql-injection.md
Я только учусь на своем тестовом хостинге. Дампил, получается нормальный запрос. Я хз че ему не нравится. Только что узнал о плейсхолдерах, сейчас буду читать.
Спасибо за инфу по инъекциям, почитаю.
Ну ты пишешь, выводится нормальный запрос, а в сообщении об ошибке явно написано:
> near '-6'
То есть в запросе есть где-то число -6. Как-то ты не так дампишь.
SELECT id, name, price, is_new FROM product WHERE status = 1 AND category_id = 1 ORDER BY id LIMIT 6 OFFSET 6
Вот дамп запроса. Числа положительные
Почему сайт ideone нормально жрет дробилку строк типа \n, а когда запускаю тот же код на своем серве (использую WAMP) нихуя не так?
Дело в том, что в пакете в WAMP идет пхп версии 5, а на ideone уже 7 или что?
Вроде от операционки зависит, или сервера.
Если в браузере то добавь в начало скрипта:
header('Content-Type:text/plain');
Если в консоли не работает попробуй
echo 'my string' . PHP_EOL;
>при попытке открыть работу в браузере
Подробнее. Что ты открываешь в браущере? Какой сайт? Причём тут шторм? Ты ставил Опенсервер? Каким образом открываешь? Телепатов среди нас нет.
Да, опиши пожалуйста последовательность действий, что ты вводил в адресную строку раньше, что делаешь сейчас, в какой папке код и тд.
>лучше
Всмысле лучше? Это сборка PHP + Апач. Вопрос впринципе некоректен. Это как если бы ты спросил чем вилка лучше другой вилки.
Потому что несколько раз видел срачи на тему, что лучше ставить. Решил уточнить.
Со стороны уроков в инете, все преподаватели сидящие на винде савят OS. Кто на маке - XAMPP либо свою сборочку. Но по сути ты будешь писать код и разницы не заметишь.
Ты был прав. Там и правда где то затесался минус, но где - я не понимаю до сих пор.
Почему дампы выводятся дважды, причем показывают они разную информацию?
ничто не лучше, а срачи только от тупости.
опенсервер и xampp это оболочки, которые устанавливают и настраивают окружение для вебдевелопера.
однохуйственно херовые, НО
если ты нуб и не можешь настроить апач, пхп и мускл - они достаточно сильно помогают. простой дроч и разбор мануалов может отбить желание вообще разбираться, молодой анон хочет кодить, а не разбираться в непонятных логах и конфигах.
с другой стороны они предоставляют минимум рабочих инструментов. какой редис или мемкеш под винду, aspel ? хуй, все придется ставить руками. т.е. для продвинутого разработчика нужно много больше инструментов, которые данные оболочки не предоставляют -> придется ковырять конфиги и логи, разбираться почему падает или не работает, смотреть логи.
Зы. часто бывает проблема что прожект не стартует или багает потому что пхп или апач настроены на проде специфично, и нубас начинает срать кирпичами, кричать что винда говно, надо ставить бубунту и там все из коробки. это тоже от тупости, такие крики - звоночек для ПМа что он работает с неадекватным нубом, не желающим разбираться ( а разработка не для таких человеков )
Могут быть проблемы с лимитом\смещением?
Игрался с этим:
>LIMIT 6 OFFSET 6
Цифры менялись в ошибке?
игрался. Цифра не менялась, т.к. лимил это константа. Константа задана как 6. В ошибке она почему то минус шесть.
Молодец. Но картинку ты забыл - держи.
Лучше не бегать от проблем в этом случае - больше узнаешь.
Сам я в этой всей хуйне не шарю, просто лабу надо сдать
не актуально
Удобно устроился. Вместо дебаггера постишь на харкач, чтобы анон таои косяки фиксил. Не юзай нано, поставь нормальную IDE с подсветкой, дебаггером и прочими улучшайзерами.
>У Bootstrap 3 есть неприятная особенность: он ставит для всех элементов box-sizing: border-box; что может быть неудобно. Если это мешает, можно использовать 2 версию.
А чем это плохо? Ведь зачастую, box-sizing: border-box; задает расчет ширины бокса по бордеру и паддингу, позволяя избегать float drop.
По дефолту в браузере box-sizing: content-box. Теперь представь, что ты пишешь какой-то виджет, который будет использоваться на других сайтах, и неизвестно какой там content-box. Из-за таких умников тебе придется в нем явно прописывать box-sizing каждому элементу DOM.
Также, в случае картинок, где в атрибутах прописаны width/height, box-sizing при наличии padding/border приводит к искажению размеров картинки.
В общем, как давно уже писали, использовать звездочку - это зло.
Но люди думать не хотят, они хотят скопировать бездумно кусок кода из статьи про то, как верстать в 20182019 и чувтсвовать себя на острие прогресса.
Что тебе и криворуким авторам бутстрапа мешает ставить box-sizing только там, где он нужен?
>Что тебе и криворуким авторам бутстрапа мешает ставить box-sizing только там, где он нужен?
Ok, учту. Спасибо за совет
просто убей себя.
1. try - catch - не пхпшная конструкция, ты просто не понимаешь что внутри. надо обрабатывать ошибки а не делать на отьебись
2. name - 40, password - 100, email - 150. рукалицо. сделай 255 везде и не еби мозг
3. $db->query, руки сломать за пробелы лишние
4. mysqli, ты нуб, и кроме как мускл ничего не будешь использовать. не нужна тебе поддержка этого всего, выкинь книжку в которой прочитал эти примеры. есть люди которые пишут книги, а есть те которые пишут код
тупость и лень - 99%.
все точно так же как и с другими языками, учишь + ебошишь. вариантов особо нет
по мне единственный подводный камень: java.
не стоит много читать по ней если уж выбрал пхп. не стоит сильно глубоко копать javascript, вообще из фронта на пхп не переходят, из явы тоже не переходят.
с пхп на яву и фронт - легко
if ($db->query(...)){
echo $db->errorCode()
}
это явно короче чем эта ебень с try catch(e)
мимокрокодил
Ты похоже тоже ничего не понимаешь в исключениях, как и автор кода. С исключениями код выглядит так:
$db->query(...)
Без try/catch.
Использовал ли ты когда нибудь трейты и считаешь ли ты их применимыми в пыхе?
Трейтов лучше избегать, вместо разделения ответственности они порождают высокую связанность, тут подробнее:
- https://blog.ircmaxell.com/2011/07/are-traits-new-eval.html
- Сравнения трейтов с goto: https://habrahabr.ru/post/333398/#comment_10316684
То есть если у тебя есть какой-нибудь GoogleApiTrait.php, то это признак плохого разделения ответственности и без хаков такой тест не протестируешь.
Лучше просто класс GoogleApi.php, который через DI будет передаваться куда нужно.
Например: у тебя есть N сущностей Доктрины (ORM) и тебе хочется к ним добавить одни и те же поля, например, "дата модификации". Ты делаешь трейт "LastModifiedTrait" с полем lastModified и методами getLM/touch(). После чего инклудишь этот трейт везде, где нужно.
Хотелось бы добавить туда еще связь на пользователя, который редактировал сущность, но, похоже, это невозможно.
Пипец я тупой, пацаны, Земля мне пухом конечно, без вопросов. Но тем не менее прошу помочь вот с чем
Хочу чтобы empty выдавал мне false, а он выдаёт true
Что мне делать? Нужно всего лишь прописать правильный путь в empty
> 2 пик
Да ты что ебанулся что ли?! Ты зачем всё засунул туда? Разбивай на функции, которые по логике будут работать. Это же пиздец какой-то.
Пилю сайт на October CMS, и есть у меня на нём форма обратной связи. При сабмите у меня вызывается такая функция:
https://codeshare.io/jGzQ9
Как только она вызывается, я получаю exception: "Undefined variable: data"
При этом, если делать var_dump, то выводится следующее:
array(4) {
["name"]=>
String(4) "Test"
["email"]=>
String(12) "
["subject"]=>
String(4) "Test"
["text"]=>
String(9) "321123321"
}
null
Меня смущает этот null в конце, подозреваю, что дело как-то связано с ним. Есть какие-нибудь идеи по этому поводу?
https://ideone.com/73VdkK
покажите как надо было сделать
ООП-Будильник https://ideone.com/b3uxlv
Сделал с горем пополам, в консоли каким-то чудом всё работает.
Пожалуйста проверьте, я запутался в реализации кода проигрывания мелодии и вообще не понимаю правильно ли описаны классы. HELP!
Есть значит 10 модулей, у которых есть своя апишка, каждый модуль наследуется от одного класса, в котором свои методы тоже есть их то я и хочу открывать (делая их public с помощью трейта) для каждого модуля отдельно (по дефолту все базовые методы не смогут быть вызваны). Считается ли это примером хуевого кода?
ОПче, по поводу TestHub, не могу разобраться со структурой БД. Когда у вопроса может быть один вариант правильного ответа, тут понятно. А если у нас чек боксы и правильный ответ например 3 чек бокса должны быть выбраны, как сделать это в SQL?
Примерно 2 года работаю на клиентов, до этого был свой небольшой проект, который обеспечивал вполне.
Так вот, проблема в том, что клиентская база так себе, и дохода не хватает, плюс ко всему клиенты очень жадные и для них 1 500 - 2 000 рублей за подключение платежной системы уже "дыра в бюджете", а активно вкладывать в проект это апдейты на 8 000 рублей раз в месяц. Ну и ряд проблем с бесплатными правками, консультациями, и ТЗ написанным в три строчки за 5 минут. Как итог - неохотно с ними работать, да и денег приносит малость, как итог проблемы из-за этого.
Так вот поэтому хочу сменить клиентов, но решил разведать как сейчас на фрилансе: какие скиллы надо иметь, чтобы получать $10/ho? Сейчас плаваю на $4-6.
Работал с CMS: WordPress, DLE.
Фреймворк: Yii2
Работал с REST(-ful) API, JSON-API, настраивал REST-приложение на базе Yii2.
Фронт: HTML, CSS, jQuery.
С ООП "дружу", вряд ли на 100%-ом уровне, но интенсив Елисеева осилил, а также дополнительный материал. С базовыми паттернами, типа: фабрики, декоратора, MVC, сингелтона дружу. Сейчас закрываю дыры по ООП и собираюсь перекатываться на Lavarel.
Дополнительно немного знаний Apache, настройка роутов nginx и базовые настройки в целом. Также GIT, но обучение+небольшая практика.
В основной массе времени работал сервисами и внедрением в их функционала, в основном всё самопис.
>клиенты очень жадные и для них 1 500 - 2 000 рублей за подключение платежной системы
Думаю - мало берёшь. Отсюда и клиенты - жадные колхозники.
>какие скиллы надо иметь, чтобы получать $10/ho?
Английский?
Pre intermediate, хожу на курсы сейчас. Неплохо умею читать, но на слух речь воспринимаю средне, а говорить сложновато.
Я ушел с фриланса на постоянные удаленные долгосрочные проекты.
а. не тратишь время и нервы на поиск клиента и конкуренцию с другими макаками
б. бабла в итоге больше получается, а работы меньше во всяком случае у меня
Я хз, где обитают нежадные клиенты для фриланса, возможно на уровне сарафанки в нужных кругах, но на всяких фриланс-агрегаторах их точно нет.
Если цель расширение возможностей на рынке труда, то
Laravel -> Symfony. Если время не поджимает то Symfony -> Laravel. Yii только, если нужен под конкретную вакансию.
Ты не берешь в расчет, что Питон - это не только веб.
ЗП в конверте, самодурство
Им фуллстак-макака нужна обычно. И вообще погроммист.
Обговаривай условия работы,чтобы не быть и эникеем-сисадмином, и монтажником, и фулл-программером.
Не то, чтобы это было невозможно, но не за 60к\мес.
Заголовок Content-Type с кодировкой либо метатег meta charset указал? Браузер не телепат, угадать кодировку не может.
спасибки, всё заработало. завёл свой сайт на бесплатном хостинге, буду выкладывать свои потуги по изучению пхп http://parcifal.byethost7.com/
тот, где ты будешь создавать все папки и файлы сам. т.е слим, сайлекс
Надо добавить заголовок Content-Type: text/plain; charset=utf-8
Браузер не телепат и угадать, что ты ему шлешь и в какой кодировке, не может.
При указании отступа в px, элементы списка уходят влево, как надо. При указании отступа в % они выходят за пределы блока, смещаясь в другую сторону.
А ты изучал алгоритм расчета размеров при использовании флексбокса?
Спецификация: https://www.w3.org/TR/css-flexbox-1/
Было бы хорошо проверить: это так и должно быть по спецификации, или не должно быть. Во втором случае может быть ошибка у тебя или в браузере. Это сложно и хлопотно, но ты начинающий и тебе изучение спецификации даст полезные навыки и знания.
У тебя сложная ситуация: размер и расположение элемента меню li зависит от размера родителя ul или nav, а размер родителя скорее всего определяется как сумма размеров детей. Увы, там не видно, какие стили использованы на nav/ul и трудно сказать точнее. Возможно, на них неудачно стили поставлены.
Также, я замечу, что у тебя отступы великоваты. 4 отступа по 20% съедят 80% ширины меню.
А еще, нет ли там каких-нибудь float, которые могут отталкивать текст?
Если не получится найти проблему, можешь выгрузить куда-нибудь код - может я гляну.
Не изучал. Спасибо за ссылку, посмотрю.
Прикрепил скрин со стилями.
Вообще, для верхней панели, у меня мало стилей задано. Логотип и nav - flex элементы. Для лого понятно - это фон. Для nav ничего, для ul - flex и выравнивание их элементов.
Можно конечно и просто ссылки выравнивать. Только, не понятно, зачем им задан padding, если речь шла об margin. Да и если задавать ссылкам padding, то отступы тоже становятся кликабельными, что не есть хорошо
У тебя не очень удачно сделано позиционирование. У тебя ul - это flex-контейнер без заданной ширины, значит его размер определяется детьми. Но у детей - li - margin задан в процентах от размера родителя. Получается замкнутый круг, который нормально не разрешится.
Ты не должен ставить свойства наугад или по интуиции. Ты должен для каждого элемента продумывать, как он позиционируется (по какому правилу определяется его размер и положение).
Это очень плохо, если верстальщик не думает, а просто ставит свойства наугад, экспериментируя в браузере. Такая верстка получается очень некачественная и скорее всего может поплыть в другом браузере.
Ну и флексбокс надо изучить более тщательно, а не на уровне "скопировать код из статьи на хабре".
Также, сразу предупрежу, посмотри поддержку флексбокса в браузерах: https://caniuse.com/#search=flexbox (вообще, caniuse должен стать для тебя как библия). Некоторые старые браузеры не поддерживают flexbox, некоторые с багами и старую версию спецификации. Могут быть сложности потом.
Встроенный в пхп не может хуёвничать. Там хуёвничать просто нечему.
Сначала пройди учебник десу
>Только, не понятно, зачем им задан padding
Поменяй padding на margin.
Вопрос был в том, что
>При указании отступа в % они выходят за пределы блока
Чтобы этого не происходило, можно блок навигационной панели и лого, завернуть в container, где указывается max-width, и все это дело завернуть в header, и уже тут указывать background, тогда позиционирование элементов происходит внутри container, но bacground выходит за поля max-width.
https://ideone.com/jiikGU
$tempSummDate = new DateTime(date('Y-m-d'));
$tempSummDate->sub(new DateInterval('P324M'));
$i= $todayDate->diff($tempSummDate);
В $i 26 лет 11 месяцев. Как так то ? Остальные месяцы все правильно считает а тут сука 26 лет и 11 месяцев не 27 лет сука. Я уже заебался. Кто знает чому ?
2 день мучаюсь с кодировкой, в браузере русские символы отображаются ебучими вопросиками?????, раскоментил данную строчку в php.ini mbstring.internal_encoding = но не помогло, что делать?
решил проблему? а то такая же
Ты пробовал указать кодировку utf-8 в заголовке Content-Type или в HTML коде, в метатеге meta charset (погугли, что это)? Браузер не телепат и угадать кодировку не может. Та настройка, которую ты упомянул, влияет в первую очередь на работу функций в PHP, браузер про нее ничего не знает.
>>303326
Загадка разгадана: https://repl.it/repls/AcrobaticIdolizedAutomatedinformationsystem
Если мы работаем в UTC, то все ок. Если в Europe/Moscow, то разница между 2018-12-01 и 1991-12-01 получается 26Y, 11M, 30D, и 23 часа. То есть час куда-то теряется. Поиск истории изменений в часовых поясах дает ответ: https://www.timeanddate.com/time/zone/russia/moscow?year=1991
В 1991 году Московский часовой пояс ненадолго перешел на Восточно-Европейское время, с разницей в 1 час. Потому с учетом этого разница получилась на 1 час меньше.
Да, часовые пояса и операции со временем - сложная вещь, врагу не пожелаешь в этом разбираться.
>>303211
Молодец, верно, продолжай дальше изучать ООП.
https://repl.it/repls/VivaciousFaithfulScandisk
оп, посмотри плз задачку про палиндром, подскажи как упростить код.
Аноны, нет времени, подождите день-два, может на выходных отвечу на ответы и перекачу тред.
>>302796
Там проблема в том, что размеры контейнера и содержимого зависят друг от друга и браузер не может определить их правильные значение. Так как ширина контейнера (меню) определяется шириной содержимого (пунктов), но расстояние между пунктами зависит через проценты от ширины контейнера. Тут в теории конечно можно написать уравнение и решить его, но браузер этим занимться не будет.
Раз уж зашла речь о размерах, то давайте я немного расскажу про их определение, когда они явно не указаны. В теории, все правила описаны в спецификациях CSS, но по факту некоторые вещи там явно не описаны и отданы на откуп производителям браузеров.
С высотой все довольно просто - если она явно не указана, то она почти всегда определяется содержимым. Единственный подвох тут - высота, заданная в процентах, работает только в редких случаях, а именно:
- для блоков c position: absolute/fixed
- для случая, когда у всех предков элемента явно задана высота в пикселях или процентах.
То есть:
div.outer {height=auto}
-div.inner {height=50%}
Тут процентная высота не будет работать, так как у родительского блока (.outer) высота неизвестна. Для .inner высота будет считаться по содержимому, а правило height игнорируется.
Другой пример:
html {height=50%}
-body {height=50%}
--div.inner {height=50%}
Здесь процентная высота для .inner будет работать, так как высота всех родителей задана явно. Высота .inner в итоге будет равна высота_окна_браузера x 50% x 50% x 50% = высота_окна_браузера / 8.
С шириной все немного сложнее. Если ширина не указана, то есть 4 варианта, как она будет считаться:
1) для блочного позиц-я (display: block без position и float): блок займет всю ширину родителя с учетом маргинов и паддингов (алгоритм stretch-fit):
div.outer {width=800px}
-div.inner {width=auto,margin=10%}
Здесь для .inner сначала будет вычислен margin = 10% x 800 = 80px, а затем ширина будет посчитана как 800 - 80 - 80 = 640px. Как видите, все просто.
2) для float, для абс. поз. блоков, для inline-block, для таблиц: для расчета ширины используется алгоритм shrink-to-fit (или fit-content): https://github.com/codedokode/pasta/blob/master/html/shrink-to-fit.md
Его суть в том, что ширина считается так, чтобы по возможности содержимое (например, текст) выстроился бы в одну строчку без переносов, но при этом чтобы по возможности не выходить за ширину родителя.
3) для таблиц: используется алгоритм из спецификации CSS
4) для флексбоксов: используется спецификация
Ссылки:
- алгоритмы расчета ширины/высоты в CSS2.2, основа основ: https://www.w3.org/TR/CSS22/visudet.html
- расчет размеров таблиц: https://www.w3.org/TR/CSS22/tables.html
- спецификация с обновлениями по авт. расчету размеров: https://www.w3.org/TR/css-sizing-3/
- флексбоксы: https://www.w3.org/TR/css-flexbox-1/
Я призываю не делать верстку наугад или по ощущениям. А продумывать, как элементы зависят друг от друга и какие схемы позиционирования будут применены.
Аноны, нет времени, подождите день-два, может на выходных отвечу на ответы и перекачу тред.
>>302796
Там проблема в том, что размеры контейнера и содержимого зависят друг от друга и браузер не может определить их правильные значение. Так как ширина контейнера (меню) определяется шириной содержимого (пунктов), но расстояние между пунктами зависит через проценты от ширины контейнера. Тут в теории конечно можно написать уравнение и решить его, но браузер этим занимться не будет.
Раз уж зашла речь о размерах, то давайте я немного расскажу про их определение, когда они явно не указаны. В теории, все правила описаны в спецификациях CSS, но по факту некоторые вещи там явно не описаны и отданы на откуп производителям браузеров.
С высотой все довольно просто - если она явно не указана, то она почти всегда определяется содержимым. Единственный подвох тут - высота, заданная в процентах, работает только в редких случаях, а именно:
- для блоков c position: absolute/fixed
- для случая, когда у всех предков элемента явно задана высота в пикселях или процентах.
То есть:
div.outer {height=auto}
-div.inner {height=50%}
Тут процентная высота не будет работать, так как у родительского блока (.outer) высота неизвестна. Для .inner высота будет считаться по содержимому, а правило height игнорируется.
Другой пример:
html {height=50%}
-body {height=50%}
--div.inner {height=50%}
Здесь процентная высота для .inner будет работать, так как высота всех родителей задана явно. Высота .inner в итоге будет равна высота_окна_браузера x 50% x 50% x 50% = высота_окна_браузера / 8.
С шириной все немного сложнее. Если ширина не указана, то есть 4 варианта, как она будет считаться:
1) для блочного позиц-я (display: block без position и float): блок займет всю ширину родителя с учетом маргинов и паддингов (алгоритм stretch-fit):
div.outer {width=800px}
-div.inner {width=auto,margin=10%}
Здесь для .inner сначала будет вычислен margin = 10% x 800 = 80px, а затем ширина будет посчитана как 800 - 80 - 80 = 640px. Как видите, все просто.
2) для float, для абс. поз. блоков, для inline-block, для таблиц: для расчета ширины используется алгоритм shrink-to-fit (или fit-content): https://github.com/codedokode/pasta/blob/master/html/shrink-to-fit.md
Его суть в том, что ширина считается так, чтобы по возможности содержимое (например, текст) выстроился бы в одну строчку без переносов, но при этом чтобы по возможности не выходить за ширину родителя.
3) для таблиц: используется алгоритм из спецификации CSS
4) для флексбоксов: используется спецификация
Ссылки:
- алгоритмы расчета ширины/высоты в CSS2.2, основа основ: https://www.w3.org/TR/CSS22/visudet.html
- расчет размеров таблиц: https://www.w3.org/TR/CSS22/tables.html
- спецификация с обновлениями по авт. расчету размеров: https://www.w3.org/TR/css-sizing-3/
- флексбоксы: https://www.w3.org/TR/css-flexbox-1/
Я призываю не делать верстку наугад или по ощущениям. А продумывать, как элементы зависят друг от друга и какие схемы позиционирования будут применены.
Проект на фреймворке, демонстрирующий знание его возможностей, плюс несколько вещей на Яваскрипте.
>>301218
> А если у нас чек боксы и правильный ответ например 3 чек бокса должны быть выбраны, как сделать это в SQL?
С помощью связи многие-ко-многим? Связь между Ответом на Вопрос и Вариантами Выбора.
Если ты не изучил связи 1-1, 1-M, M-N, то изучи.
То есть у нас могут быть примерно такие сущности:
- Сеанс Сдачи Теста
- Ответ На Вопрос (привязан к Сеансу и к Вопросу, содержит выбранный или введенный ответ на вопрос)
- Выбранный Вариант (привязан к Ответу и к Варианту Ответа, используется для ответов с множественным выбором)
Но тут могут быть избыточные данные. Прочти-ка еще на всякий случай урок про нормализацию: https://github.com/codedokode/pasta/blob/master/db/normalization.md
Вот видишь, какая хорошая задачка, учит проектировать базы данных. Аноны, постарайтесь все найти время и сделать ТестХаб.
>>301182
Мутная какая-то идея, конечно. А почему в разных Модулях должны быть одинаковые методы? Мне кажется, корень проблемы тут. Если метод должен быть во всех модулях, мы просто объявляем его в базовом классе. Если не во всех, то конечно можно попробовать вынести их в трейты, но возникает вопрос, откуда такая необходимость и правильно ли спроектированы твои классы?
Я вот хоть и работаю с php лет 10, только сегодня узнал об этом.
Мне не нравится, что надо каждый день пересчитывать время тревоги. Это делает код усложненным и более хрупким - легко забыть где-то это сделать. Лучше бы выбрать такую форму хранения, чтобы ничего менять не требовалось, например:
- хранить отдельно часы и минуты
- хранить DateTime, но использовать из него только часы и минуты
DateTime указывает на точку во времени, но время срабатывания будильника - это не одна точка, а бесконечное множество точек, определяемое часами/минутами и разрешенными днями.
Для одноразовых тревог после срабатывания просто удалять ее, как требуется в задаче.
Также, мне не нравится, что при создании тревоги ей передается текущее время. Это довольно бессмысленно, так как время не стоит на месте, и переданное значение быстро станет устаревшим.
И неудобно, что надо лишние аргументы передавать. Если бы сделать хранение времени в виде часов/минут вместо DateTime, это было бы не нужно.
> $namesOfDaysOfWeek = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
Ты должен использовать тут константы, а не строки. Иначе, если кто-то поменяет значение в константе, твой код сломается. Можно для удобства объявить такую константу в самом классе:
private const ALL_DAYS = [
self::MONDAY,
self::TUESDAY,
...
];
Вместо тайп-хинта DateTime лучше использовать DateTimeInterface, так как это позволяет передавать объекты DateTimeImmutable, которые являются неизменяемыми.
> Возвращает идентификатор тревоги.
А зачем ей идентификатор? Объект сам по себе уникален и не требует добавления искуственных идентификаторов.
> return clone $this->time;
Если бы ты использовал DateTimeImmutable, клонирование бы не требовалось. Кстати, у тебя в setTime() нет клонирования и можно передать объект даты, а потом изменить его без ведома твоего класса, например, поставить дату в прошлом.
Лучше сделать неизменяемую копию переданной даты.
> public function getStatus(): bool
Лучше бы назвать isActive().
> public function deleteAlarm(int $id): void
Можно было бы обойтись без id и передавать сам объект Alarm.
> $yesOrNot = null;
wasDeleted/wasFound
> public function setAlarm(int $id, ?DateTime $alarmTime, ?array $daysOfWeek, ?int $type, ?bool $status): void
Вообще, можно было бы разрешить пользователю создавать Alarm и передавать уже настроенный объект. Хотя можно и так, как у тебя, это может использоваться для введения каких-то дополнительных ограничений и проверок.
> $isEveryday = $alarm->getDaysOfWeek()[0] == Alarm::EVERYDAY;
А, нарушение зоны ответственности! Не логичнее было бы сделать метод isEveryday() в Alarm? Тогда тебе не пришлось бы полагаться на знание про элемент EVERYDAY, что он хранится в нулевом элементе массива.
И, кстати, так ли нужен этот EVERYDAY? Он все усложняет, теперь любой код, который работает с днями недели, должен про него знать и проверять его наличие. Я вижу такие варианты улучшения:
- выпилить EVERYDAY вообще
- сделать, чтобы Alarm сам внутри себя считал, какие дни заданы, и возвращал бы массив только с днями, без EVERYDAY. То есть передать EVERYDAY в Alarm можно, а наружу его не уже возвращают.
- сделать в Alarm методы setEveryday()/isEveryday()
> $alarmTime = $alarm->getTime()->add(
> DateInterval::createFromDateString('tomorrow')
> );
Это нехорошо, ты в функции поиска, которая по логике ничего не должна менять, меняешь дату тревоги.
> // Обновляем время тревоги
> $alarm->setTime($alarmTime, new DateTime);
Это не нужно, ведь у тебя используется изменяемый объект DateTime и ты его уже поменял.
Ну и опять же, этот хитроумный код должен быть в классе Alarm. Ты не хочешь помещать логику в Alarm и относишься к нему как к "глупому" массиву, который способен только хранить данные.
Вообще, мне кажется, весь findNearestAlarmTime() можно без ущерба поместить в Alarm. Непонятно, что он делает в AlarmClock.
> foreach ($alarm->getDaysOfWeek() as $dayOfWeek) {
> "next $dayOfWeek"
Здесь ты полагаешься на то, что константа имеет определенное значение. Не стоит так делать, вдруг значение поменяют на цифры?
> Если время срабатывания тревоги равно текущему,
> а тип тревоги одноразовый - удаляем её
Лучше удалять и прошлые тревоги. Ведь будильник может не работать какое-то время и тогда тревога навсегда останется неудаленной.
> function playMelody(AlarmClock $alarmClock, DateTime $currentTime)
> $nearestAlarm = $alarmClock->findNearestAlarm(new DateTime);
Зачем тогда передавать currentTime?
> // Ожидаем минуту, из-за особенностей работы метода поиска ближайшей тревоги
> sleep(60);
А остальной код ведь тоже занимает какое-то время, допустим, 2 секунды. И получится, общее время работы функции 62 секунды. И если ее выполнять в цикле, где-то будет пропущена минута.
Мне не нравится, что надо каждый день пересчитывать время тревоги. Это делает код усложненным и более хрупким - легко забыть где-то это сделать. Лучше бы выбрать такую форму хранения, чтобы ничего менять не требовалось, например:
- хранить отдельно часы и минуты
- хранить DateTime, но использовать из него только часы и минуты
DateTime указывает на точку во времени, но время срабатывания будильника - это не одна точка, а бесконечное множество точек, определяемое часами/минутами и разрешенными днями.
Для одноразовых тревог после срабатывания просто удалять ее, как требуется в задаче.
Также, мне не нравится, что при создании тревоги ей передается текущее время. Это довольно бессмысленно, так как время не стоит на месте, и переданное значение быстро станет устаревшим.
И неудобно, что надо лишние аргументы передавать. Если бы сделать хранение времени в виде часов/минут вместо DateTime, это было бы не нужно.
> $namesOfDaysOfWeek = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
Ты должен использовать тут константы, а не строки. Иначе, если кто-то поменяет значение в константе, твой код сломается. Можно для удобства объявить такую константу в самом классе:
private const ALL_DAYS = [
self::MONDAY,
self::TUESDAY,
...
];
Вместо тайп-хинта DateTime лучше использовать DateTimeInterface, так как это позволяет передавать объекты DateTimeImmutable, которые являются неизменяемыми.
> Возвращает идентификатор тревоги.
А зачем ей идентификатор? Объект сам по себе уникален и не требует добавления искуственных идентификаторов.
> return clone $this->time;
Если бы ты использовал DateTimeImmutable, клонирование бы не требовалось. Кстати, у тебя в setTime() нет клонирования и можно передать объект даты, а потом изменить его без ведома твоего класса, например, поставить дату в прошлом.
Лучше сделать неизменяемую копию переданной даты.
> public function getStatus(): bool
Лучше бы назвать isActive().
> public function deleteAlarm(int $id): void
Можно было бы обойтись без id и передавать сам объект Alarm.
> $yesOrNot = null;
wasDeleted/wasFound
> public function setAlarm(int $id, ?DateTime $alarmTime, ?array $daysOfWeek, ?int $type, ?bool $status): void
Вообще, можно было бы разрешить пользователю создавать Alarm и передавать уже настроенный объект. Хотя можно и так, как у тебя, это может использоваться для введения каких-то дополнительных ограничений и проверок.
> $isEveryday = $alarm->getDaysOfWeek()[0] == Alarm::EVERYDAY;
А, нарушение зоны ответственности! Не логичнее было бы сделать метод isEveryday() в Alarm? Тогда тебе не пришлось бы полагаться на знание про элемент EVERYDAY, что он хранится в нулевом элементе массива.
И, кстати, так ли нужен этот EVERYDAY? Он все усложняет, теперь любой код, который работает с днями недели, должен про него знать и проверять его наличие. Я вижу такие варианты улучшения:
- выпилить EVERYDAY вообще
- сделать, чтобы Alarm сам внутри себя считал, какие дни заданы, и возвращал бы массив только с днями, без EVERYDAY. То есть передать EVERYDAY в Alarm можно, а наружу его не уже возвращают.
- сделать в Alarm методы setEveryday()/isEveryday()
> $alarmTime = $alarm->getTime()->add(
> DateInterval::createFromDateString('tomorrow')
> );
Это нехорошо, ты в функции поиска, которая по логике ничего не должна менять, меняешь дату тревоги.
> // Обновляем время тревоги
> $alarm->setTime($alarmTime, new DateTime);
Это не нужно, ведь у тебя используется изменяемый объект DateTime и ты его уже поменял.
Ну и опять же, этот хитроумный код должен быть в классе Alarm. Ты не хочешь помещать логику в Alarm и относишься к нему как к "глупому" массиву, который способен только хранить данные.
Вообще, мне кажется, весь findNearestAlarmTime() можно без ущерба поместить в Alarm. Непонятно, что он делает в AlarmClock.
> foreach ($alarm->getDaysOfWeek() as $dayOfWeek) {
> "next $dayOfWeek"
Здесь ты полагаешься на то, что константа имеет определенное значение. Не стоит так делать, вдруг значение поменяют на цифры?
> Если время срабатывания тревоги равно текущему,
> а тип тревоги одноразовый - удаляем её
Лучше удалять и прошлые тревоги. Ведь будильник может не работать какое-то время и тогда тревога навсегда останется неудаленной.
> function playMelody(AlarmClock $alarmClock, DateTime $currentTime)
> $nearestAlarm = $alarmClock->findNearestAlarm(new DateTime);
Зачем тогда передавать currentTime?
> // Ожидаем минуту, из-за особенностей работы метода поиска ближайшей тревоги
> sleep(60);
А остальной код ведь тоже занимает какое-то время, допустим, 2 секунды. И получится, общее время работы функции 62 секунды. И если ее выполнять в цикле, где-то будет пропущена минута.
На ideone забыли поставить расширение mbstring, можно использовать repl.it.
> if (!function_exists('mb_ucfirst')
Эту проверку можно и не делать, так как такой функции нету.
> mb_ucfirst($str, $encoding='UTF-8')
> mb_ereg_replace('^[\ ]+', '', $str);
А почему сюда кодировка не передается? Какой тогда в ней смысл?
Также, учти что mb_ereg_replace использует немного другой диалект регулярок - Extended Posix, а не PCRE.
> mb_strlen($str)
Сюда не передана кодировка.
> function makeFirstLetterUppercase($str) {
Лучше указать, что функция работает с массивом, переименовать ее.
> [^\s]
То же что и просто \S
Мне кажется, писать [^\s] не требуется. Квантификаторы по умолчанию жадные и конструкция \s* захватит максимально возможное число пробелов.
Ну и что-то у тебя многоточие раскорежило.
>>300880
> Меня смущает этот null в конце, подозреваю, что дело как-то связано с ним. Есть какие-нибудь идеи по этому поводу?
Если ты пытаешься обратиться к несуществующей переменной, то будет сгенерировано предупреждение и возвращен null.
На ideone забыли поставить расширение mbstring, можно использовать repl.it.
> if (!function_exists('mb_ucfirst')
Эту проверку можно и не делать, так как такой функции нету.
> mb_ucfirst($str, $encoding='UTF-8')
> mb_ereg_replace('^[\ ]+', '', $str);
А почему сюда кодировка не передается? Какой тогда в ней смысл?
Также, учти что mb_ereg_replace использует немного другой диалект регулярок - Extended Posix, а не PCRE.
> mb_strlen($str)
Сюда не передана кодировка.
> function makeFirstLetterUppercase($str) {
Лучше указать, что функция работает с массивом, переименовать ее.
> [^\s]
То же что и просто \S
Мне кажется, писать [^\s] не требуется. Квантификаторы по умолчанию жадные и конструкция \s* захватит максимально возможное число пробелов.
Ну и что-то у тебя многоточие раскорежило.
>>300880
> Меня смущает этот null в конце, подозреваю, что дело как-то связано с ним. Есть какие-нибудь идеи по этому поводу?
Если ты пытаешься обратиться к несуществующей переменной, то будет сгенерировано предупреждение и возвращен null.
Да ты прав. Это вообще на мой взгляд очень плохо, что функции и классы не чувствительны к регистру символов и с этим у меня возникла проблема.
Я делал небольшой фреймворк для собственного использования в своих проектах и хотел частично повторить принцип руби на рельсах с вызовом контроллеров.
Т.е. сделать так, что бы при открытии ссылки
site.com/huita запускался котроллер HuitaController,
при запуске
site.com/labuda что бы запускался LabudaController,
и так далее. И в общем всё это отлично работает, но как оказалось, если написать
site.com/HUiTa, то контроллер HuitaController всё равно запускается, а это на мой взгляд совсем не правильно, так как я хочу, что бы каждая ссылка была строго чувствительной к регистру.
А насчет автозагрузки могу только сказать, что я её не использую. Вместо этого я написал небольшую функцию, которая рекурсивно сканирует необходимую папку и загружает все имеющиеся php файлы. Т.е. в результате файлы в этой папке можно перемещать и переименовывать как захочется, а так же при необходимости перемещать файлы во внутренние папки. Возможно это замедляет обработку запроса на считанные наносекунды, так как не всё содержимое этой папки может понадобится в данный конкретный момент, но зато это очень удобно.
кококо, срочно переделать.
человек пишет же что у него проблема, он нуб. не перегревай его
>>303408
ты ебанулся. есть стандарты оформления коды. пиши HuitaController, либо huita_controller
но тебе яйца отрежут за другие варианты нормальные разработчики. эту хуйню надо потом будет использовать возможно не только тебе, и попробуй запомни что ты там класс назвал HuI_TaCoNtTrOlLer
Я в качестве своего первого проекта запилил интернет магазин с нуля. Интернет магазин получился довольно неплохим, хоть разумеется и не дотягивает до уравня всяких амазонов и ибэев.
>рекурсивно сканирует необходимую папку и загружает все имеющиеся php файлы
>Возможно это замедляет обработку запроса на считанные наносекунды
И засирает глобальный неймспейс сотнями говна.
Решение - так себе. Почему просто не использовать неймспейсы? Они очень удобны - через простейшую функцию подключаются и показывают разработчику расположение подключаемого модуля в каждом конкретном случае что есть тру. Наиболее изящное решение, заставляющее любую макаку вроде меня писать правильно и не изобретать велосипед.
По стандартам - пиши нормально и без велосипедов. Из тебя не получится хорошего программера, если будешь писать велосипеда и игнорировать эти самые промышленные стандарты.
У вас на руби все такие велосипедисты? Тогда понятно почему не взлетает.
Титл текст и лайки.
вопрос такой. как организовать лайканье без авторизации и регистрации?
Куки наверное? что копать вообще?
окей. капает. в Мysql. А как сделать чтоб один юзер не накликал 100500
я не ебу, 4 день пых изучаю:3
Мда, не думал что всё настолько плачевно.
>Лучше удалять и прошлые тревоги.
Я сломал голову пытаясь реализовать эту возможность.
Допустим у нас есть тревога на среду, пятницу и воскресенье в 15:00. Если сегодня четверг, то срабатываем в 15:00 пятницы, ну хорошо тут ничего сложного. После срабатывания удаляем тревогу, но если скрипт перезапустить он не сможет определить срабатывала ли уже тревога и снова будет ожидать ближайший день недели. Был бы рад подсказке, хотя мне кажется это невозможно. Проиллюстрировал проблему
>Также, мне не нравится, что при создании тревоги ей передается текущее время. Это довольно бессмысленно, так как время не стоит на месте, и переданное значение быстро станет устаревшим.
>Зачем тогда передавать currentTime?
Как я понял по условию задачи, будильник должен получать текущее время снаружи.
Получается, достаточно завести свойство $часы в котором будет лежать объект DateTime?
Куки глянь
Если ты удалил тревогу из будильника, то как она сработает? Здесь не требуется решать проблему сохранения данных между перезапусками скрипта, это не зона ответственности Будильника. Это будет делать какой-то другой код. Это уже не твоя проблема.
Понятно, что в случае реального использования будет прикручено сохранение данных в файлы или в БД (если у тебя есть время и желание, можешь сделать сохранение/восстановление из файла, например, в формате JSON или CSV, или в обоих, в идеале чтобы это делалось в соответствие с принципом разделения обязанностей снаружи и не требовало никаких доработок в коде будильника).
Также в реальному будильнику будет прикручен какой-то пользовательский интерфейс для управления тревогами (сами себя они ведь не добавят). Но при правильной архитектуре твой код никак не зависит от кода графического интерфейса, ничего о нем не знает, и может спокойно работать без него, через добавление тревог программным путем. И также твой код ничего не знает про сохранение/восстановление данных.
То есть: если тревога активна и сейчас есть в Будильнике - она должна сработать. Если ее оттуда удалили - то не должна.
Результат твоей работы - это просто несколько классов, без кода для сохранения/загрузки данных, без пользовательского интерфейса. Разве что для теста можно какой-то простой проверочный скрипт добавить, как ты это сделал.
Или я что-то не так понял? Тогда уточни вопрос.
> Как я понял по условию задачи, будильник должен получать текущее время снаружи.
Получается, достаточно завести свойство $часы в котором будет лежать объект DateTime?
Ты пытаешься дать будильнику постоянный доступ к текущему времени, чтобы оно там внутри хранилось. Но реально оно нужно всего в нескольких местах, вроде таких:
- определить ближайшую сработающую тревогу (тут конечно надо знать, сколько сейчас времени)
- удалить одноразовые тревоги, которые сработали или пропустили свое время
То есть время должно передаваться только в отдельные функции, а внутри будильника постоянно хранить его не надо.
А еще, в этой задаче очень удобно для проверки правильности кода использовать юнит-тесты, не знаю, слышал ли ты про них. То есть читаем описание задачи, и выделяем из него требования (каким требованиям должен соответствовать написанный код). Ну вот, что я увидел, по порядку:
- Нельзя поставить Тревоге неправильное время
- Тревога срабатывает только в установленное время
- Многократная тревога сработает неограниченное число раз
- Если в Будильник добавить одноразовую Тревогу на будущее, то она сработает однократно
- Одноразовая тревога на прошлое никогда не сработает
- Тревога срабатывает только в установленные дни
- Неактивная тревога не срабатывает
- Можно добавить Тревогу в Будильник
- Можно удалить Тревогу из Будильника
- Можно менять настройки Тревоги после добавления
- Можно определить ближайшее время срабатывания даже для неактивной тревоги
- Можно удалить одноразовые тревоги на время в прошлом
- Можно узнать ближайшую сработающую Тревогу, даже если их несколько
Для проверки этих требований пишутся 1 или более сценариев. Сценарии иногда описывают в виде "Дано - Если - То", и составление сценария - это иногда непростая творческая задача. Сценарии бывают позитивные - когда все делается правильно, и негативные - когда делаются ошибки (неправильно указано время), и они должны быть обнаружены.
Вот, как можно проверить выполнение требования "Тревога срабатывает только в установленное время":
Дано: Будильник, в него добавлена Тревога на все дни недели на 12:00
Если: сейчас понедельник, 12:00
То: данная Тревога срабатывает
Если: сейчас понедельник, 13:00
То: данная Тревога не срабатывает
Это можно записать в виде кода:
// Включаем функцию assert, иначе она может не работать
assert_options(ASSERT_ACTIVE, true);
assert_options(ASSERT_BAIL, true);
// Дано
$clock = new AlaramClock();
$alarm = new Alarm(12, 0, Alarm::ALL_DAYS);
$clock->addAlarm($alarm);
// Если-то
$now = new DateTime('2018-12-03 12:00:00');
$ringingAlarm = $clock->getActiveAlarmAt($now);
assert($ringingAlarm !== null);
assert($ringingAlarm === $alarm);
$now2 = new DateTime('2018-12-03 13:00:00');
$ringingAlarm2 = $clock->getActiveAlarmAt($now2);
assert($ringingAlarm2 === null);
echo "Тест пройден: Тревога срабатывает только в установленное время\n";
Функция assert(...) просто проверяет, что аргумент равен true, и бросает исключение, если это не так.
Вот такой вот код автоматически проверяет первое требование. Конечно, тут можно сказать, что он не гарантирует на 100%, что требование выполняется - мы лишь проверили время 12:00 и 13:00, а не все возможные варианты. Но тесты и не гарантируют 100% правильность. Они проверяют, что код как-то использует переданное время, а не возвращает первый попавшийся результат. Они помогают обнаруживать ошибки. Например, если ты - забудешь сделать проверку времени срабатывания, или отключишь ее, то такой тест это обнаружит.
С тестами очень легко делать рефакторинг кода: не надо бояться, что ты нечаянно сломаешь какой-то функционал.
Вот еще примеры сценариев:
Требование: Многократная тревога сработает неограниченное число раз
Дано: Будильник, добавлена многоразовая Тревога на все дни на 12:00
Если: сейчас 12:00 1 декабря, то эта Тревога срабатывает
Если: сейчас 12:00 2 декабря, то эта Тревога срабатывает
Если: сейчас 12:00 1 января, то эта Тревога срабатывает
Требование: Можно удалить Тревогу из Будильника
Дано: Будильник, добавлена Тревога на 12:00
Если: удалить эту Тревогу и запросить список Тревог, то ее в списке нет
Требование: Можно менять время срабатывания многоразовой Тревоги после добавления
Дано: Будильник, добавлена Тревога на 12:00 на каждый день
Если: сейчас 12:00, то Тревога срабатывает
Если: поменять время Тревоги на 13:00, и сейчас 12:00, то Тревога не срабатывает
Если: сейчас 13:00, то Тревога срабатывает
Требование: Нельзя добавить Тревогу с неправильным временем
Дано: Будильник
Если: попытаться добавить тревогу на 25:00, то будет выброшено исключение
Если: попытаться добавить тревогу на 12:99, то будет выброшено исключение
Заметь, что мы в тестах каждый раз создаем новые Будильники и Тревоги. Это позволяет нам выкинуть их после теста, и за счет этого один тест никак не влияет на выполнение других. В случае со статическими методами или глобальными переменными это было бы трудно. Это плюс использования ООП в данном случае. Код с хорошей архитектурой обычно проще тестировать.
Я вижу, ты пытаешься разобраться в ООП, значит тебе наверно было бы интересно заодно и юнит-тесты поучиться делать. Если что, подробный длинный урок про автоматизированное тестирование: https://gist.github.com/codedokode/a455bde7d0748c0a351a
Автоматическое тестирование используют такие компании, как Яндекс, Гугл. Если ты хочешь ориентироваться на их уровень, а не подвальную студию Замкадинска "ООО Интернет", то стоит осваивать хотя бы юнит-тесты.
А еще, в этой задаче очень удобно для проверки правильности кода использовать юнит-тесты, не знаю, слышал ли ты про них. То есть читаем описание задачи, и выделяем из него требования (каким требованиям должен соответствовать написанный код). Ну вот, что я увидел, по порядку:
- Нельзя поставить Тревоге неправильное время
- Тревога срабатывает только в установленное время
- Многократная тревога сработает неограниченное число раз
- Если в Будильник добавить одноразовую Тревогу на будущее, то она сработает однократно
- Одноразовая тревога на прошлое никогда не сработает
- Тревога срабатывает только в установленные дни
- Неактивная тревога не срабатывает
- Можно добавить Тревогу в Будильник
- Можно удалить Тревогу из Будильника
- Можно менять настройки Тревоги после добавления
- Можно определить ближайшее время срабатывания даже для неактивной тревоги
- Можно удалить одноразовые тревоги на время в прошлом
- Можно узнать ближайшую сработающую Тревогу, даже если их несколько
Для проверки этих требований пишутся 1 или более сценариев. Сценарии иногда описывают в виде "Дано - Если - То", и составление сценария - это иногда непростая творческая задача. Сценарии бывают позитивные - когда все делается правильно, и негативные - когда делаются ошибки (неправильно указано время), и они должны быть обнаружены.
Вот, как можно проверить выполнение требования "Тревога срабатывает только в установленное время":
Дано: Будильник, в него добавлена Тревога на все дни недели на 12:00
Если: сейчас понедельник, 12:00
То: данная Тревога срабатывает
Если: сейчас понедельник, 13:00
То: данная Тревога не срабатывает
Это можно записать в виде кода:
// Включаем функцию assert, иначе она может не работать
assert_options(ASSERT_ACTIVE, true);
assert_options(ASSERT_BAIL, true);
// Дано
$clock = new AlaramClock();
$alarm = new Alarm(12, 0, Alarm::ALL_DAYS);
$clock->addAlarm($alarm);
// Если-то
$now = new DateTime('2018-12-03 12:00:00');
$ringingAlarm = $clock->getActiveAlarmAt($now);
assert($ringingAlarm !== null);
assert($ringingAlarm === $alarm);
$now2 = new DateTime('2018-12-03 13:00:00');
$ringingAlarm2 = $clock->getActiveAlarmAt($now2);
assert($ringingAlarm2 === null);
echo "Тест пройден: Тревога срабатывает только в установленное время\n";
Функция assert(...) просто проверяет, что аргумент равен true, и бросает исключение, если это не так.
Вот такой вот код автоматически проверяет первое требование. Конечно, тут можно сказать, что он не гарантирует на 100%, что требование выполняется - мы лишь проверили время 12:00 и 13:00, а не все возможные варианты. Но тесты и не гарантируют 100% правильность. Они проверяют, что код как-то использует переданное время, а не возвращает первый попавшийся результат. Они помогают обнаруживать ошибки. Например, если ты - забудешь сделать проверку времени срабатывания, или отключишь ее, то такой тест это обнаружит.
С тестами очень легко делать рефакторинг кода: не надо бояться, что ты нечаянно сломаешь какой-то функционал.
Вот еще примеры сценариев:
Требование: Многократная тревога сработает неограниченное число раз
Дано: Будильник, добавлена многоразовая Тревога на все дни на 12:00
Если: сейчас 12:00 1 декабря, то эта Тревога срабатывает
Если: сейчас 12:00 2 декабря, то эта Тревога срабатывает
Если: сейчас 12:00 1 января, то эта Тревога срабатывает
Требование: Можно удалить Тревогу из Будильника
Дано: Будильник, добавлена Тревога на 12:00
Если: удалить эту Тревогу и запросить список Тревог, то ее в списке нет
Требование: Можно менять время срабатывания многоразовой Тревоги после добавления
Дано: Будильник, добавлена Тревога на 12:00 на каждый день
Если: сейчас 12:00, то Тревога срабатывает
Если: поменять время Тревоги на 13:00, и сейчас 12:00, то Тревога не срабатывает
Если: сейчас 13:00, то Тревога срабатывает
Требование: Нельзя добавить Тревогу с неправильным временем
Дано: Будильник
Если: попытаться добавить тревогу на 25:00, то будет выброшено исключение
Если: попытаться добавить тревогу на 12:99, то будет выброшено исключение
Заметь, что мы в тестах каждый раз создаем новые Будильники и Тревоги. Это позволяет нам выкинуть их после теста, и за счет этого один тест никак не влияет на выполнение других. В случае со статическими методами или глобальными переменными это было бы трудно. Это плюс использования ООП в данном случае. Код с хорошей архитектурой обычно проще тестировать.
Я вижу, ты пытаешься разобраться в ООП, значит тебе наверно было бы интересно заодно и юнит-тесты поучиться делать. Если что, подробный длинный урок про автоматизированное тестирование: https://gist.github.com/codedokode/a455bde7d0748c0a351a
Автоматическое тестирование используют такие компании, как Яндекс, Гугл. Если ты хочешь ориентироваться на их уровень, а не подвальную студию Замкадинска "ООО Интернет", то стоит осваивать хотя бы юнит-тесты.
Если не понятно объяснил, то вот взгляните пожалуйста на пример. Я никак, ну никак не могу понять в чем смысл ретурн тру в этой функции.
https://github.com/victor-zinchenko/shop.php-start.com/blob/master/controllers/CatalogController.php
Конкретно у Витька что бы call_user_func_array в Router вернул true.
Я бы ни стал тратить время на его код, там есть пара весьма пахнущих моментов.
По началу не уловил в шаблоне ходы мысли ОПа, поэтому решил сам строчить. Все вроде работает, но код, мне кажется, шибко объемный, корявый - сначала какую-то основу накидал, потом уже косяки исправлял, как мог. Собственно, хотел узнать, что мож посоветуете. Щас глянул подсказки в учебнике и осознал, что, как минимум, можно было выбор слов-чисел проще осуществить. Кароче, подскажите, что тут имеет право на жизнь, а что - не имеет.
Ну и за одно, что эта хуета от меня требует -https://ideone.com/prkZ1h ?
Ды ебаныйврот! А на чей код тогда тратить время? Просто у него самое доступное объяснение. Всё остальное супер не понятно
Все равно не понимаю. Возвращает call_user_func_array в руотутер тру. Дальше это самое тру записывается в переменную $result. И с ней ничего не происходит, кроме операции сравнения.
Он прерывает цикл foreach https://github.com/victor-zinchenko/shop.php-start.com/blob/e4973a695f36ec367f88488e604975c843ac0e20/components/Router.php#L84
что бы не проходить остаток массива, когда нужный роут найден.
Суть. На первом скрине я пишу запрос ручками и выдаёт такую ошибку, на втором скриншоте я удаляю начало запрос SELECT (звёзодчка) и нажимаю на кнопку которая опять добавляет SELECT (звезда). После этого никакой ошибки нет
WTF?!
Скрины перепутались местами
упс, вижу теперь что запрос полностью меняется, но сути проблемы всё равно не пойму, почему выдаёт ошибку?
Подчёркивание использую если функциональщину пишу, камелКейс - через объекты.
У тебя там 2 разных запроса.
Ему строка запроса не нравится.
Программирование не всем даётся (даже на пхп), поэтому если у тебя не получается решить даже такую простую задачу, то наверное тебе лучше заняться чем нибудь другим: вагоны разгружать например или в армию пойти по контракту.
Напиши пожалуйста, что именно непонятно, может мы сможем пояснить. Если ты не можешь решить задачу, покажи тот код, который ты смог написать, и напиши, на чем запнулся.
А то так, непонятно даже, в чем именно проблема.
>>304261
Ты используешь неправильный вид кавычек. Посмотри внимательнее на скриншоты, а потом на свою клавиатуру. Косые кавычки и одиночные кавычки это разные символы.
Также, MySQL тебе дает подсказку, в каком месте ошибка, смотри внимательно:
...to use near ''user' GROUP BY ...
То есть он тебе прямо пишет, что ошибка в кавычке.
>>304117
PSR не дает рекомендаций по именам функций. Для методов:
> Method names MUST be declared in camelCase.
Для классов:
> Class names MUST be declared in StudlyCaps.
Имена функций в таком стиле, так как большинство стандартных функций PHP это аналоги сишных функций, и они копируют их стиль наименования. Они были добавлены когда в PHP еще не было ООП.
Напиши пожалуйста, что именно непонятно, может мы сможем пояснить. Если ты не можешь решить задачу, покажи тот код, который ты смог написать, и напиши, на чем запнулся.
А то так, непонятно даже, в чем именно проблема.
>>304261
Ты используешь неправильный вид кавычек. Посмотри внимательнее на скриншоты, а потом на свою клавиатуру. Косые кавычки и одиночные кавычки это разные символы.
Также, MySQL тебе дает подсказку, в каком месте ошибка, смотри внимательно:
...to use near ''user' GROUP BY ...
То есть он тебе прямо пишет, что ошибка в кавычке.
>>304117
PSR не дает рекомендаций по именам функций. Для методов:
> Method names MUST be declared in camelCase.
Для классов:
> Class names MUST be declared in StudlyCaps.
Имена функций в таком стиле, так как большинство стандартных функций PHP это аналоги сишных функций, и они копируют их стиль наименования. Они были добавлены когда в PHP еще не было ООП.
Я бы в дополнение посоветовал почитать наши уроки отсюда: https://github.com/codedokode/pasta/ . Там подробно разъясняется теория про MVC, DI, паттерны работы с базой данных, интерфейсы, исключения.
Кстати, в уроке про MVC есть пример кода и он в разы проще!
>>304109
> http://sandbox.onlinephpfunctions.com/code/27ceda4f92a17777bc54652cdb04454d9ade39ad
Плохо работать с числами как со строками. Во-первых, есть математика, зачем заморачиваться? Во-вторых, это делает код ненадежнее, так как PHP может представлять большие числа в виде 1e20 и твой код будет просто выдавать ерунду при работе с ними.
Если уж ты решил использовать строчные методы, то использовал бы mb_substr(), а не регулярку с циклом. А еще лучше - математические методы.
Там два основных метода:
987 % 100 = 87
floor(987 / 100) = 9
> $count=preg_match($regexp, $number, $array);
> $string=implode('',$array);
Почитай документацию по preg_match, в каком формате функция возвращает данные и что кладется в массив array. Ты должен брать нулевой элемент массива, а не делать implode.
Ты явно написал этот код наугад, не читая мануал. Это плохо, так как он потом может сломаться при изменениях, например, при добавлении скобок в регулярку и ты будешь долго гадать, почему.
> function formAndMerge ($array)
> {
> global $number;
Вот это плохая идея. Ты ведь можешь просто передать $number через аргументы, напрямую, но вместо этого решил пойти обходным путем. Чтобы вызвать твою функцию, мы должны как-то догадаться поменять глобальную переменную, и только потом вызывать твою функцию, то есть мы должны писать:
gloabl $number;
$number = 123;
formAndMerge(...);
Вместо того, чтобы писать просто:
formAndMerge(123, ...);
Вот посмотри, неужели первый вариант удобнее? Какие у него преимущества?
Видимо ты не понял идею разбиения кода на функции. Суть в том, что длинный кусок кода, который делает несколько вещей, сложно понять. Его сложно править, в нем много переменных, и можно нечаянно что-то сломать. Ну и физически прочитать 1000 или 10 000 строк кода быстро невозможно. Поэтому код разбивают на отдельные действия и выносят эти действия в функции. Так, что мы можем вместо огромной портянки кода читать только небольшую функцию, которая нас интересует.
Но для этого функции должны быть отделены от других частей кода. Они должны иметь определенное назначение (не размытое, вроде "делает одно действие, кусочек другого и готовит данные для третьего"). Они должны иметь понятное название, в котором описано их назначение. И они должны иметь понятный набор входных аргументов, что они принимают на вход, и что возвращают.
У тебя это не соблюдается. Я пытаюсь изучить эту функцию, не прочитав остальной код:
- название функции ничего не говорит мне: formAndMerge. Я понимаю отдельные слова, но не понимаю смысл.
- комментарий тоже малопонятный: "ну это, значит, мы готовимся к тому, что бы выбрать падежи - соотносим группы слов с элементами массива"
- функция не изолирована от остального кода: ее поведение зависит от какой-то глобальной переменной, про которую я ничего пока не знаю. Ее нельзя использовать в другой программе, так как там нет этой глобальной переменной.
- входные параметры функции никак не описаны: я вижу, что она получает на вход переменную с ничего не говорящим названием. Массив непонятно какого вида, непонятно что в нем должно быть.
То есть, сделаны все ошибки, которые можно сделать при определени функции. Ты начинающий, это не беда, думаю, ты в итоге научишься проектировать функции правильно.
Вот пример более адекватной функции:
/**
* Принимает на вход целое число от 0 до 999 и возвращает его
* текстовое представление.
*
* Например, для числа 312 вернет "триста двенадцать".
*/
function spellNumber(int $number): string
Согласись, что даже если ты не прочитал код функции, ты из описания уже понимаешь, что она делает, и как ее можно использовать. Например, так:
echo spellNumber(123) . "\n";
Комментарий /** ... */ - это комментарий в формате phpdoc ( https://ru.wikipedia.org/wiki/PHPDoc ). Слово int и string - это тайп-хинты, советую их изучить:
- http://php.net/manual/ru/functions.arguments.php#functions.arguments.type-declaration
- http://php.net/manual/ru/functions.returning-values.php
То есть ты должен в идеале каждую функцию так описать. Если ты не можешь понятно описать назначение функции и формат ее аргументов, то скорее всего, ты что-то неудачно спроектировал.
Имя функции начинается с глагола, в виде сделайЧтоТо().
Вместо array(...) в PHP можно давно уже писать [...]
> foreach ($array as $key=>$value)
Названия переменных ничего не говорят. Что значит value? Любая переменная хранит в себе какое-то значение.
> function wordShapeSelection($magnitude1, $magnitude2)
Непонятно, что надо передавать функции.
> $regexp1='/1[0-9]$/ui';
> $regexp2='/[^1]?[2-4]$/ui';
Тут можно использовать математику.
> function smallNumberToText($parts)
Непонятно, что надо передавать в функцию.
Код этой функции излишне усложнен. Смотри, как можно делать намного проще:
слова = пустой массив;
если (число >= 100) {
берем число сотен;
берем соответствующее ему слово и кладем в массив слов
}
если (2 последних цифры >= 20) {
берем число десятков;
....
}
в конце просто склеиваем массив слов в строку.
В общем, самая главная проблема это неправильно спроектированные функции. Начни с их исправления. Это самое важное. Сейчас у тебя функции просто для видимости, так как реального разделения кода на действия нет и одна функция создает массив непонятного вида, который потом использует другая функция.
На ideone не установили расширение mbstring, и mb-функции там недоступны. Используй другие сайты вроде https://repl.it/languages/php - он даже без рекламы.
Я бы в дополнение посоветовал почитать наши уроки отсюда: https://github.com/codedokode/pasta/ . Там подробно разъясняется теория про MVC, DI, паттерны работы с базой данных, интерфейсы, исключения.
Кстати, в уроке про MVC есть пример кода и он в разы проще!
>>304109
> http://sandbox.onlinephpfunctions.com/code/27ceda4f92a17777bc54652cdb04454d9ade39ad
Плохо работать с числами как со строками. Во-первых, есть математика, зачем заморачиваться? Во-вторых, это делает код ненадежнее, так как PHP может представлять большие числа в виде 1e20 и твой код будет просто выдавать ерунду при работе с ними.
Если уж ты решил использовать строчные методы, то использовал бы mb_substr(), а не регулярку с циклом. А еще лучше - математические методы.
Там два основных метода:
987 % 100 = 87
floor(987 / 100) = 9
> $count=preg_match($regexp, $number, $array);
> $string=implode('',$array);
Почитай документацию по preg_match, в каком формате функция возвращает данные и что кладется в массив array. Ты должен брать нулевой элемент массива, а не делать implode.
Ты явно написал этот код наугад, не читая мануал. Это плохо, так как он потом может сломаться при изменениях, например, при добавлении скобок в регулярку и ты будешь долго гадать, почему.
> function formAndMerge ($array)
> {
> global $number;
Вот это плохая идея. Ты ведь можешь просто передать $number через аргументы, напрямую, но вместо этого решил пойти обходным путем. Чтобы вызвать твою функцию, мы должны как-то догадаться поменять глобальную переменную, и только потом вызывать твою функцию, то есть мы должны писать:
gloabl $number;
$number = 123;
formAndMerge(...);
Вместо того, чтобы писать просто:
formAndMerge(123, ...);
Вот посмотри, неужели первый вариант удобнее? Какие у него преимущества?
Видимо ты не понял идею разбиения кода на функции. Суть в том, что длинный кусок кода, который делает несколько вещей, сложно понять. Его сложно править, в нем много переменных, и можно нечаянно что-то сломать. Ну и физически прочитать 1000 или 10 000 строк кода быстро невозможно. Поэтому код разбивают на отдельные действия и выносят эти действия в функции. Так, что мы можем вместо огромной портянки кода читать только небольшую функцию, которая нас интересует.
Но для этого функции должны быть отделены от других частей кода. Они должны иметь определенное назначение (не размытое, вроде "делает одно действие, кусочек другого и готовит данные для третьего"). Они должны иметь понятное название, в котором описано их назначение. И они должны иметь понятный набор входных аргументов, что они принимают на вход, и что возвращают.
У тебя это не соблюдается. Я пытаюсь изучить эту функцию, не прочитав остальной код:
- название функции ничего не говорит мне: formAndMerge. Я понимаю отдельные слова, но не понимаю смысл.
- комментарий тоже малопонятный: "ну это, значит, мы готовимся к тому, что бы выбрать падежи - соотносим группы слов с элементами массива"
- функция не изолирована от остального кода: ее поведение зависит от какой-то глобальной переменной, про которую я ничего пока не знаю. Ее нельзя использовать в другой программе, так как там нет этой глобальной переменной.
- входные параметры функции никак не описаны: я вижу, что она получает на вход переменную с ничего не говорящим названием. Массив непонятно какого вида, непонятно что в нем должно быть.
То есть, сделаны все ошибки, которые можно сделать при определени функции. Ты начинающий, это не беда, думаю, ты в итоге научишься проектировать функции правильно.
Вот пример более адекватной функции:
/**
* Принимает на вход целое число от 0 до 999 и возвращает его
* текстовое представление.
*
* Например, для числа 312 вернет "триста двенадцать".
*/
function spellNumber(int $number): string
Согласись, что даже если ты не прочитал код функции, ты из описания уже понимаешь, что она делает, и как ее можно использовать. Например, так:
echo spellNumber(123) . "\n";
Комментарий /** ... */ - это комментарий в формате phpdoc ( https://ru.wikipedia.org/wiki/PHPDoc ). Слово int и string - это тайп-хинты, советую их изучить:
- http://php.net/manual/ru/functions.arguments.php#functions.arguments.type-declaration
- http://php.net/manual/ru/functions.returning-values.php
То есть ты должен в идеале каждую функцию так описать. Если ты не можешь понятно описать назначение функции и формат ее аргументов, то скорее всего, ты что-то неудачно спроектировал.
Имя функции начинается с глагола, в виде сделайЧтоТо().
Вместо array(...) в PHP можно давно уже писать [...]
> foreach ($array as $key=>$value)
Названия переменных ничего не говорят. Что значит value? Любая переменная хранит в себе какое-то значение.
> function wordShapeSelection($magnitude1, $magnitude2)
Непонятно, что надо передавать функции.
> $regexp1='/1[0-9]$/ui';
> $regexp2='/[^1]?[2-4]$/ui';
Тут можно использовать математику.
> function smallNumberToText($parts)
Непонятно, что надо передавать в функцию.
Код этой функции излишне усложнен. Смотри, как можно делать намного проще:
слова = пустой массив;
если (число >= 100) {
берем число сотен;
берем соответствующее ему слово и кладем в массив слов
}
если (2 последних цифры >= 20) {
берем число десятков;
....
}
в конце просто склеиваем массив слов в строку.
В общем, самая главная проблема это неправильно спроектированные функции. Начни с их исправления. Это самое важное. Сейчас у тебя функции просто для видимости, так как реального разделения кода на действия нет и одна функция создает массив непонятного вида, который потом использует другая функция.
На ideone не установили расширение mbstring, и mb-функции там недоступны. Используй другие сайты вроде https://repl.it/languages/php - он даже без рекламы.
тащемто ничего сложного нет, это просто нужно запомнить
https://ideone.com/dXxJDD
Что КОНКРЕТНО полразумевается? что нужно знать и уметь?
Если ты не понимаешь - значит у тебя хуевое понимание ООП. В гугле забанили?
Базовые принципы ООП.
Реализация ООП в PHP 5, 7.
SOLID, YAGNI, KISS etc
DI.
MVC.
Паттерны проектирования.
Сразу предупреждаю, если просто заучить наизусть определения и не иметь практики и приличного понимания, это обнаружат на собеседовании за пару вопросов.
1) Как можно узнать, с использованием какого фронт/бэк фреймворка написан сайт? Хочу просто посмотреть сайты на ангуляре/реакте/ларавеле/симфонии/и т.д.
2) А вообще, может ли быть сайт написан с использованием и бэк-фреймворка и фронт-фреймворка, например на yui2/react?
И в дополнение ко второму, третий: а что вообще делает js-фреймворк? Про php-фреймворки мне понятно, там реализуется MVC на стороне сервера. А вот из описаний js-фреймворков не особо понимаю их назначение.
Чувак, ты такую хуйню написал, йобана. Иди на завод, программирование - не твоё. Я не шучу. Ты абсолютную чушь написал, про MVC вообще орнул.
> Как можно узнать, с использованием какого фронт/бэк фреймворка написан сайт?
Точно определить не получится, но есть специальные расширения для браузера, которые по кускам HTML и JS kkкода пытаются "угадать" фронтенд и бекенд фреймворки, например Wappalyzer: https://www.wappalyzer.com/
Например, он задетектил, что GitHub написан на Ruby On Rails, что новый Reddit использует React. Если ты на основе этих данных хочешь выбирать фреймворк, то в этом смысла нет, так как сейчас все популярные фреймворки позволяют сделать примерно одно и то же, вопрос лишь в профессионализме разработчика.
> А вообще, может ли быть сайт написан с использованием и бэк-фреймворка и фронт-фреймворка, например на yui2/react?
Конечно. На бекенде может быть только JSON API, а на фронте всё остальное. Может быть комбинация - бекенд отдаёт HTML тоже, но интерактивные части сделаны на JS-фрейморке. SPA фрейморк не единственный способ создать приложение без перезагрузки страницы, есть ещё pjax, GitHub до сих пор так и работает.
> что вообще делает js-фреймворк?
Предоставляет удобные абстракции для написания SPA - приложений, работающих без перезагрузки страницы. То, что на jQuery писать сложно и неудобно. То есть ты сам поймёшь, когда тебе нужен JS-фрейморк, когда лапшу из jQuery/чистого JS поддерживать станет проблемно. Примеры приложений, в которых уместно использование JS-фреймворков - Trello, SoundCloud, VK. Или вот такое: https://github.com/codedokode/pasta/blob/master/js/spa.md
Спасибо за подробное объяснение.
>Если ты на основе этих данных хочешь выбирать фреймворк
Но выбрать таки что-то нужно. А я даже не могу выбрать, фронт или бэк. Прям как задача про два стула.
Зачем? Это основы. Если ты не смог их понять - то толку от объяснения не будет никакого.
Аноны, а интересно, как бы вы перевели "statement", например, отсюда:
> As in C or Perl, PHP requires instructions to be terminated with a semicolon at the end of each statement.
Я обычно и statement, и instruction перевожу как "команда".
Ну и заодно, как бы вы перевели "clause" из SQL, например, "ORDER clause", "WHERE clause"?
>>304721
> использованием какого фронт...
Открой HTML-код страницы и посмотри, JS код ведь виден на стороне браузера. Также освой Developer Tools в браузере (Ctrl + Shift + I), с помощью которых можно изучать содержимое страницы.
> бэк фреймворка
Можно посмотреть на страницы ошибок вроде 404 - возможно, там используется стандартная страница фреймворка. Ну и иногда бывают еще некоторые признаки.
Но проще по моему просто зайти в документацию фреймворка или Гугл и найти список там:
- гугли "Symfony sites"
- https://madewithlaravel.com/
> А вообще, может ли быть сайт написан с использованием и бэк-фреймворка и фронт-фреймворка, например на yui2/react?
Может. Но это не всегда хорошая идея. Есть сайты-сайты, которые лучше реализовывать на сервере, и сайты-приложения, в которых выгоднее использовать толстый клиент на JS.
> а что вообще делает js-фреймворк?
Например, реализует MVC на стороне клиента. Вообще, в JS есть здоровая традиция делать библиотеки, которые выполняют одну функцию (например: реакт), а не фреймворки, которые определяют всю архитектуру приложения (например: ангулар).
Ты можешь почитать описание Ангулар, например: https://angular.io/guide/architecture
Чтобы его понять, надо знать хотя бы такие вещи, как MVC, DI.
Аноны, а интересно, как бы вы перевели "statement", например, отсюда:
> As in C or Perl, PHP requires instructions to be terminated with a semicolon at the end of each statement.
Я обычно и statement, и instruction перевожу как "команда".
Ну и заодно, как бы вы перевели "clause" из SQL, например, "ORDER clause", "WHERE clause"?
>>304721
> использованием какого фронт...
Открой HTML-код страницы и посмотри, JS код ведь виден на стороне браузера. Также освой Developer Tools в браузере (Ctrl + Shift + I), с помощью которых можно изучать содержимое страницы.
> бэк фреймворка
Можно посмотреть на страницы ошибок вроде 404 - возможно, там используется стандартная страница фреймворка. Ну и иногда бывают еще некоторые признаки.
Но проще по моему просто зайти в документацию фреймворка или Гугл и найти список там:
- гугли "Symfony sites"
- https://madewithlaravel.com/
> А вообще, может ли быть сайт написан с использованием и бэк-фреймворка и фронт-фреймворка, например на yui2/react?
Может. Но это не всегда хорошая идея. Есть сайты-сайты, которые лучше реализовывать на сервере, и сайты-приложения, в которых выгоднее использовать толстый клиент на JS.
> а что вообще делает js-фреймворк?
Например, реализует MVC на стороне клиента. Вообще, в JS есть здоровая традиция делать библиотеки, которые выполняют одну функцию (например: реакт), а не фреймворки, которые определяют всю архитектуру приложения (например: ангулар).
Ты можешь почитать описание Ангулар, например: https://angular.io/guide/architecture
Чтобы его понять, надо знать хотя бы такие вещи, как MVC, DI.
С моей точки зрения, чушь пишешь ты. Бессмысленный пост, не несущий никакой информации. То ли ты сам не знаешь ответ, то ли тебе просто нечего делать.
>>304897
> А я даже не могу выбрать, фронт или бэк
Я написал выше, зависит от задачи. Тебе надо сделать сайт мэрии? Используй генерацию страниц на сервере и CMS. Надо сделать редактор электрических схем? Используй клиентское приложение.
>>304647
Вот, кстати, у нас есть задачи для проверки своих знаний ООП:
- ООП-Будильник: https://phpclub.tech/pr/res/1232710.html#1263399
- ООП-Гостиница: https://phpclub.tech/pr/res/1082507.html#1097078
>>304642
Можно было сделать цикл из 2 шагов, чтобы не копипастить 2 раза код для генерации первых двух строчек.
Вместо $rand_keys я бы сразу брал нужное слово строчкой вроде
$word1 = $words1[array_rand(...)];
А так, верно.
Сделать голосование платным.
>>303503
Это конечно удобнее делать на JS в браузере, так как там ведь надо постоянно хранить в памяти состояние игры. А c PHP будет довольно невыгодно:
- браузер отправляет запрос
- PHP скрипт запускается, загружает откуда-то (файлы, БД) состояние игры
- делает изменения
- сохраняет состояние
- отправляет данные в браузер
- завершается
Заметь, что тут кучу действий надо сделать ради того, чтобы просто передвинуть персонажа, например.
Однако, если ты хочешь, чтобы игра была многопользовательская, то тебе все равно придется хранить состояние на сервере. И сохранять его придется, чтобы при падении сервера достижения бы не терялись. Тогда стоит сделать JS-клиент игры + API на сервере.
Вообще, обычно для игр все же пишут игровые демоны. Это серверная программа, часто на языках вроде Си или Го для максимальной производительности, которая держит состояние игры в памяти. Однако, можно использовать Node.JS или PHP в виде демона, в "неумирающем" режиме на ReactPHP. Её логика работы такая:
- загрузить состояние игры в память
- принять множество соединений от клиентов (браузеров) и ждать прихода сообщений
- по приходу сообщения от клиента (например: передвинуть персонажа), обработать его, изменить состояние игры
- асинхронно запустить отправку клиенту ответа, перейти к ожиданию следующего сообщения
- периодически сохранять изменения в состоянии игры на диск на случай падения/перезапуска демона
Это позволяет получить макс. производительность и макс. число игроков на одном сервере. Традиционный подход с "умирающим" PHP, когда на каждый запрос с клиента запускается скрипи будет в разы медленнее. Естественно, для этого придется осваивать сетевое программирование, придумывать, как сохранять изменения в игре без перегрузки дисковой системы, и тд.
Общее описание разных серверных архитектур: https://gist.github.com/codedokode/ffd520440a970c07c1c6
Для максимальной производительности нужна асинхронная архитектура. Но у нее есть и минусы: код под нее писать сложнее. Тут у языка Го есть преимущество перед другими перечисленными выше: он позволяет писать асинхронный код гораздо проще. Плюс, он автоматически позволяет задействовать несколько ядер процессора.
В общем, если хочешь писать игровой демон по-настоящему, как это делают игровые студии, то тебе нужен асинхронный код. Я готов подсказать по теории, но тебе придется так же много чего изучать.
Если ты не хочешь многопользовательский режим, то пиши просто в браузере на JS, а на сервере сделай только сохранение/загрузку данных игры.
Сделать голосование платным.
>>303503
Это конечно удобнее делать на JS в браузере, так как там ведь надо постоянно хранить в памяти состояние игры. А c PHP будет довольно невыгодно:
- браузер отправляет запрос
- PHP скрипт запускается, загружает откуда-то (файлы, БД) состояние игры
- делает изменения
- сохраняет состояние
- отправляет данные в браузер
- завершается
Заметь, что тут кучу действий надо сделать ради того, чтобы просто передвинуть персонажа, например.
Однако, если ты хочешь, чтобы игра была многопользовательская, то тебе все равно придется хранить состояние на сервере. И сохранять его придется, чтобы при падении сервера достижения бы не терялись. Тогда стоит сделать JS-клиент игры + API на сервере.
Вообще, обычно для игр все же пишут игровые демоны. Это серверная программа, часто на языках вроде Си или Го для максимальной производительности, которая держит состояние игры в памяти. Однако, можно использовать Node.JS или PHP в виде демона, в "неумирающем" режиме на ReactPHP. Её логика работы такая:
- загрузить состояние игры в память
- принять множество соединений от клиентов (браузеров) и ждать прихода сообщений
- по приходу сообщения от клиента (например: передвинуть персонажа), обработать его, изменить состояние игры
- асинхронно запустить отправку клиенту ответа, перейти к ожиданию следующего сообщения
- периодически сохранять изменения в состоянии игры на диск на случай падения/перезапуска демона
Это позволяет получить макс. производительность и макс. число игроков на одном сервере. Традиционный подход с "умирающим" PHP, когда на каждый запрос с клиента запускается скрипи будет в разы медленнее. Естественно, для этого придется осваивать сетевое программирование, придумывать, как сохранять изменения в игре без перегрузки дисковой системы, и тд.
Общее описание разных серверных архитектур: https://gist.github.com/codedokode/ffd520440a970c07c1c6
Для максимальной производительности нужна асинхронная архитектура. Но у нее есть и минусы: код под нее писать сложнее. Тут у языка Го есть преимущество перед другими перечисленными выше: он позволяет писать асинхронный код гораздо проще. Плюс, он автоматически позволяет задействовать несколько ядер процессора.
В общем, если хочешь писать игровой демон по-настоящему, как это делают игровые студии, то тебе нужен асинхронный код. Я готов подсказать по теории, но тебе придется так же много чего изучать.
Если ты не хочешь многопользовательский режим, то пиши просто в браузере на JS, а на сервере сделай только сохранение/загрузку данных игры.
Ты вообще-то можешь проверять регистр перед вызовом контроллера.
> Т.е. в результате файлы в этой папке можно перемещать и переименовывать как захочется, а так же при необходимости перемещать файлы во внутренние папки.
Это плохо. Во-первых, почему другие должны разбираться с твоей нестандаратной схемой? Если каждый начнет свои схемы загрузки придумывать, будет бардак и путаница. Во-вторых, непонятно, в чем ее плюсы. Свобода перемещения файлов куда угодно это минус, так как нет однозначности, где искать тот или иной класс, или куда его поместить.
Есть PSR-4 и композер, не надо заниматься изобретением велосипеда с квадратными колесами.
>>303382
Ошибка 404, код не открывается.
спасибо
приходит такая хуйня.
{"channel":{"id":532400,"name":"House","latitude":"0.0","longitude":"0.0","field1":"Temp_indoor","created_at":"2018-07-04T11:10:55Z","updated_at":"2018-12-02T17:38:27Z","last_entry_id":7},"feeds":[{"created_at":"2018-12-02T18:13:40Z","entry_id":7,"field1":"26.00000"}]}
как полуить 26.00000 из этого хлама?
echo $x->feeds[0]->field1;
или
$x = json_decode($str, true);
echo $x['feeds'][0]['field1'];
спасибо, сработало
поясни только, мы делаем декода джейсона.
получаем объект Х, а не массив. в нем обращаемся к полю feed[0] вот это уже не понял. Фидс тоже объект? и в объекте фидс поле фиелд1?
feeds массив объектов. в ячейке ноль объект и у него поле field1.
смотри var_dump или дебагером что бы ориентироваться что json_decode отдаст.
>разбиваем текст на массив предложений с помощью preg_split. Каждое предложение пропускаем через функцию, делающую первую букву заглавной.
После того как я разбил строку по предложениям, и каждое предложение лежит в массиве, как с помощью функции поменять регистр 1 буквы в каждом эл-е массива? Ещё я не совсем понимаю как обращаться к элементу массива в preg_split`e чтоб он принимал элемент как строку>>304938
https://ideone.com/V6Rxdg
https://repl.it/@askarpro24/VivaciousFaithfulScandisk
Регистр поменял, теперь вопрос как вернуть из функции массив?
php 7
При этом не отключая остальные варнинги. Мне просто не нужен конкретно этот тип варнингов
Не является проблемой подменить заголовки, реферер, уникальный ип, куки.
Что является проблемой - отследить перечень перенаправлений, модификацию кук в процессе перенаправлений, особенно, если на сайте присутствует много js или не дай бог технологии посложнее/запросов десятки и в каждом необходимо разобраться
Через отладчик фаерфокса проверять передаваемые куки, необходимые хеадеры может быть слишком трудозатратно.
Какие есть средства, позволяющие проанализировать цепочку запросов до получения конечного результата, в идеале сами генерирующие код, либо сильно облегчающие генерацию кода на php? На ум приходят браузерные плагины, но я таких не знаю
Значит плохая идея для пет-проекта по бэку, в фронт углубляться я пока не хочу, учу php пока что по твоим ссылкам.
Потому что цель упражнения написать простой алгоритм, а не изучить встроенные функции PHP. Палиндром часто спрашивают на собеседованиях.
А твоя программа на втором скриншоте работающая? Ну-ка проверь ее на строчке "А роза упала на лапу Азора" в utf-8.
У меня есть ощущение, что она не работает и ты скорее всего ее не проверял на русскоязычных фразах.
Урок: https://github.com/codedokode/pasta/blob/master/php/strings-utf8.md
Какой бамплимит на этой доске? Перекат будет?
Да, погоди, сегодня постараюсь перекатить.
Картинки, чтобы отучать копипастить. Если кода много, то обычно дается ссылка на код. И вообще, ты должен решения задач писать сам, а не копировать.
Если тебе во что бы то ни стало хочется копировать, то освой библиотеку вроде Tesseract или используй сайт с бесплатным OCR.
Спасибо за развернутый комментарий
Посмотри, вот "работа над ошибками":
https://repl.it/repls/MisguidedAnotherAggregators
> Принимает на вход текстовую форму числа,
> наименование величины, начальное число в цифровом формате,
> номер элемента массива
Непонятно, что такое "номер элемента массива". И что за "наименование величины". Ну и я не уверен, что тут стоило делать функцию.
Также, непонятно, почему "текстовая форма числа" передается в виде массива. Это явно не отдельная независимая законченная функция, а просто вырезанный откуда-то кусок кода (из spellNumber, я так думаю). Это объясняет, откуда берется $arrayKey.
> Принимает на входе число от 0 до 999 и
> номер элемента массива (для определения степеней числа)
Непонятно, что за номер. Лучше было бы передавать в функцию массив с формами слова либо сами формы слов:
echo selectWordform(123, ['рубль', 'рубля', 'рублей'])
echo selectWordform(123, 'рубль', 'рубля', 'рублей')
Так мы получаем универсальную функцию, работающую с любыми словами.
Ну или хотя бы заменить arrayKey на wordNumber и написать, что это номер склоняемого слова от 0 до N.где 0 - это ..., 1 - это ... итд.
В функции getWordForm() слишком сложные if, их можно было бы упростить, перестав и убрав вложенность.
> if ($isFemale==1 && $lastDigits<3)
> {
> $units=$lastDigits;
> $words[]=$femaleSpelling[$units];
Это скопировано 2 раза, это плохо. Тут можно обойтись без копипасты, чуть-чуть переставв куски кода местами.
> Принимает на вход целое число от 0 до 10^12,
> разбивает его на части по 3 цифры с конца
В документации к функции не требуется писать принцип ее работы, если это ни на что не влияет. Достаточно просто написать, что принимает число и возвращает текстовую форму.
> if($number!=0)
> {
> ... много кода ...
> }
> else
> {
> $result='(0) рублей';
> }
Тут лучше перевернуть if:
if ($number == 0) {
return ...;
}
... много кода ...
> $count=preg_match($regPart, $number, $onePart);
> $threeDigit[]=$onePart[0];
Тут проще использовать математику, для отщепления 3 последних цифр. Хотя твой вариант относительно работающий, так все же будет чище.
> foreach ($threeDigit as $key => $value)
foreach ($groups as $group)
> $combineElements=array_reverse($combineElements);
$parts
> $wordForm[]=getWordForm ($value, $key);
Непонятно, зачем тут использован массив.
> Принимает на вход текстовую форму числа,
> наименование величины, начальное число в цифровом формате,
> номер элемента массива
Непонятно, что такое "номер элемента массива". И что за "наименование величины". Ну и я не уверен, что тут стоило делать функцию.
Также, непонятно, почему "текстовая форма числа" передается в виде массива. Это явно не отдельная независимая законченная функция, а просто вырезанный откуда-то кусок кода (из spellNumber, я так думаю). Это объясняет, откуда берется $arrayKey.
> Принимает на входе число от 0 до 999 и
> номер элемента массива (для определения степеней числа)
Непонятно, что за номер. Лучше было бы передавать в функцию массив с формами слова либо сами формы слов:
echo selectWordform(123, ['рубль', 'рубля', 'рублей'])
echo selectWordform(123, 'рубль', 'рубля', 'рублей')
Так мы получаем универсальную функцию, работающую с любыми словами.
Ну или хотя бы заменить arrayKey на wordNumber и написать, что это номер склоняемого слова от 0 до N.где 0 - это ..., 1 - это ... итд.
В функции getWordForm() слишком сложные if, их можно было бы упростить, перестав и убрав вложенность.
> if ($isFemale==1 && $lastDigits<3)
> {
> $units=$lastDigits;
> $words[]=$femaleSpelling[$units];
Это скопировано 2 раза, это плохо. Тут можно обойтись без копипасты, чуть-чуть переставв куски кода местами.
> Принимает на вход целое число от 0 до 10^12,
> разбивает его на части по 3 цифры с конца
В документации к функции не требуется писать принцип ее работы, если это ни на что не влияет. Достаточно просто написать, что принимает число и возвращает текстовую форму.
> if($number!=0)
> {
> ... много кода ...
> }
> else
> {
> $result='(0) рублей';
> }
Тут лучше перевернуть if:
if ($number == 0) {
return ...;
}
... много кода ...
> $count=preg_match($regPart, $number, $onePart);
> $threeDigit[]=$onePart[0];
Тут проще использовать математику, для отщепления 3 последних цифр. Хотя твой вариант относительно работающий, так все же будет чище.
> foreach ($threeDigit as $key => $value)
foreach ($groups as $group)
> $combineElements=array_reverse($combineElements);
$parts
> $wordForm[]=getWordForm ($value, $key);
Непонятно, зачем тут использован массив.
Видимо, да. Вообще, текстовую игру на PHP можно было бы запускать в консоли в режиме диалога (где она бы работала постоянно), но в Windows сложности с отображением utf-8 в консоли... это впрочем можно решить перекодировкой с помощью http://php.net/manual/ru/book.outcontrol.php
Не хочешь консольную текстовую игру? Я могу подсказать, как можно сделать цветные буковки (гугли последовательности ANSI. Увы, они не работают в нативной консоли до Windows 10, но работают в сторонних эмуляторах терминалов вроде mintty из Cygwin).
Впрочем, это к бекенду мало имеет отношения.
>>305175
Можно запустить эмулятор браузера, загрузить в нем страницу и найти нужный текст. На нищебродском PHP shared хостинге работать, естественно, не будет.
>>305173
Не надо так. Надо передавать все требуемые параметры или задать им значения по умолчанию.
>>305031
> for($i=0;$i<count($dividedLine);$i++){
Используй foreach
> После того как я разбил строку по предложениям, и каждое предложение лежит в массиве, как с помощью функции поменять регистр 1 буквы в каждом эл-е массива?
$result = [];
foreach ($sentences as $sentence) {
$result[] = fn($sentence);
}
Примерно как у тебя и сделано.
Есть еще array_map(), смотри мануал, он позволяет обойтись без цикла в 1 строчку.
ucfirst не работает, смотри урок: https://github.com/codedokode/pasta/blob/master/php/strings-utf8.md
> Ещё я не совсем понимаю как обращаться к элементу массива в preg_split`e чтоб он принимал элемент как строку
Как взять элемент из массива? $array[0] например.
>>305087
Не знаю. Установка какой-нибудь Node.JS может быть? Надо смотреть док-ю.
Вы видите копию треда, сохраненную 12 декабря 2018 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.