Это копия, сохраненная 24 июля 2015 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
Почему PHP? Потому что фейсбук и википедия на нем написаны, и вакансий море, и учить легко.
Это тред для начинающих. Не написал за свою жизнь ни одной программы? Ты наш человек.
Устанавливать пока что ничего не требуется, разве что редактор кода вроде Sublime Text 3, Notepad++, Netbeans PHP или PhpStorm (с ним будет удобнее).
Предыдущий тред был тут: >>494598
Что самое главное для программиста? Умение аккуратно оформлять код (читай пост ниже).
Правила: ведем себя воспитанно, помогаем новичкам, постим ссылки на решения задачек, ОП их проверяет и дает советы и замечания. ОП отвечает даже на самые нубские вопросы. ОП заходит где-то раз в день-два, не жди его, решай задачки дальше.
У нас есть уроки по основам PHP, они собраны и выложены по адресу http://archive-ipq-co.narod.ru/ Это учебник для изучающих с нуля, то есть если ты вообще ничего не знаешь, то надо начать с него. Он простой и понятный (по крайней мере в начале). Там есть задачи, их надо решать обязательно (чтобы стать программистом, надо писать код — иначе никак). Пости ссылки на решения в тред, мы их проверим, напишем замечания и дадим советы по улучшению.
Если не знаешь как решать, запости код, напиши в каком месте остановился и попроси подсказку.
Учебник дает основы языка PHP, но чтобы делать сайты, этого недостаточно. Если ты его прошел, то надо переходить в более серьезным задачкам, которые научат тебя как выдавать страницы в браузер, работе с таблицами в БД, работе с формами, MVC.
- Простая, но полезная задача сделать список студентов: https://github.com/codedokode/pasta/blob/master/student-list.md
- Более сложная задача сделать файлообменник на микрофреймворке Slim: https://gist.github.com/codedokode/9424217
- Еще более сложная и долгая задача на Yii/Yii2: https://gist.github.com/codedokode/8733007
- После нее можно изучать автоматизированное тестирование
- Если ты все решил, переходи к Symfony 2/Doctrine 2
Чтобы делать эти задания, тебе надо установить Апач + PHP (можно заодно сразу и MySQL) на компьютер. Вот полезные инструкции:
https://gist.github.com/codedokode/10774100
https://gist.github.com/codedokode/7054af4a03865c4cc863
Может тебе понадобится пользоваться командной строкой, вот гайд https://gist.github.com/codedokode/10539568
Вот небольшой туториал по тому как начать использовать PHP на сервере для отдачи странички в браузер: https://php.net/manual/ru/tutorial.php Увы, уроков плавно подводящих к тому, как сделать задачи выше, пока нет, так что если что, задавай вопросы.
Решения задач лучше показать мне, особенно на ООП,так как сам ты вряд ли увидишь все ошибки. Пости свой код на гитхаб и вкидывай ссылку в тред по мере решения. Я прокомментирую и укажу на ошибки.
Также, у нас есть задачи которые позволят тебе изучить или подтянуть до нормального уровня знания JS/HTML/CSS/SQL. Решай их параллельно с задачами выше.
- HTML/CSS: https://gist.github.com/codedokode/58ebc90bd006baf4b35c
- JS: https://gist.github.com/codedokode/ce30e7a036f18f416ae0
- Проверялка решений на JS: http://dkab.github.io/jasmine-tests/
- MySQL: https://gist.github.com/codedokode/10539213
Что почитать
- Мануал по PHP — http://www.php.net/manual/ru/langref.php
- Сайт phptherightway (перевод на русский: http://getjump.github.io/ru-php-the-right-way/ )
- По PHP: Профессиональное программирование на PHP Джордж Шлосснейгл
- По PHP: Мэтт Зандстра — PHP: Объекты, шаблоны, методики программирования
- JS: learn.javascript.ru
- Про Git:
Подскажи сайты для поиска работы, я не умею гуглить? brainstorage.me, geekjob.ru, hh.ru
Нужен ли ООП, фреймворки, MVC? — Да, однозначно. Посмотри любую вакансию.
Сайт опять упал!!!!! — Не паникуй, а открой http://rghost.net/45000175
Оформляй код аккуратно!!! — например пропусти через phpformatter.com . Также, если ты пользуешься IDE вроде PhpStorm, Netbeans, Eclipse, то в них эта опция встроена, подробнее: https://gist.github.com/codedokode/8759492
ОП, сделай за меня мою работу или домашнее задание? — Это конечно, хорошая идея, но нет.
Где искать работу и заказы — hh.ru, geekjob.ru, brainstorage.me, fl.ru, odesk.com. Имей в виду, что кроме фриланса есть еще постоянная удаленная работа (remote job) когда тебе не надо тратить время на поиск заказов и переговоры с неадекватными заказчиками.
Если тебе лень выравнивать код руками, закачай его на http://beta.phpformatter.com/ и нажми «format». Робот исправит выравнивание и отступы в мгновение ока (да, прогресс не стоит на месте). Если ты используешь мощную IDE вроде PhpStorm, там тоже есть функция форматирования кода.
Горячие клавиши для форматирования кода в разных IDE: https://gist.github.com/codedokode/8759492
Вообще, в PHP долгое время не было единого стандарта оформления кода, все писали как попало и было много бардака, но сейчас дело лучше — есть стандарты PSR-1 и 2. Вот как надо оформлять код:
- переменные и функции пишутся с маленькой буквы, подчеркивание не используется, используется camelCase, пример: $x, $numberOfPeople, printResults()
- Название функции начинается с глагола, в стиле «сделайЧтоТо»
- не знаешь английский? Не беда, в 21 веке есть решение этой проблемы. Не пиши транслитом, открой лучше Гугл Транслейт или slovari.yandex.ru и найди название для переменной там
- в именах классов используется CamelCase, первая буква большая, «_» может использоваться
- мы предпочитаем подстановку переменных вместо конкатенации строк: "I am $age years old" — хорошо, 'I am ' . $age . ' years old' — плохо из-за обилия точек и кавычек
- мы используем для отступов 4 пробела (можно настроить редактор, чтобы при нажатии Tab он вставлял 4 пробела)
Вот ссылка на стандарты, где все это описано подробнее и даны примеры оформления:
PSR-1: https://github.com/php-fig/fig-standards/blob/master/accepted/ru/PSR-1-basic-coding-standard.md
PSR-2: https://github.com/php-fig/fig-standards/blob/master/accepted/ru/PSR-2-coding-style-guide.md
------------------
Итак, ты зашел в тред и решил помочь какому-то анону, дав ему совет или подсказку. Спасибо! Но прочти сначала эти напоминания, чтобы твоя помощь действительно была полезной.
Будь доброжелателен
Не годится: «Ты мануал хоть раз в жизни открывал, обезьяна?»
Не годится: «В гугле забанили?»
Не годится: «Твой код плохой»
Хорошо: «Вот, как можно улучшить этот код: ...»
Хорошо: «Ты неправильно используешь функцию abc(). Вот ее описание: ссылка, и как видишь ей надо передать строку, а не массив»
Объясняй
Не очень хорошо: «сделай как в этом коде»
Хорошо: «если ты вставляешь текст от пользователя в SQL запрос, то получается SQl-инъекция, которая позволяет взломать твой сервер (ссылки). Чтобы этого избежать, надо вставлять данные с помощью плейсхолдеров (ссылки)»
Хорошо: «Помни, что код пишется для людей. Если писать такие большие функции, то в них становится трудно разобраться...»
Не проповедуй
Мы учим использованию самых распространненных подходов, стандартов, библиотеки фреймворков. Если ты не любишь ООП, пробелы в коде, jQuery, сам PHP, то рассказать об этом стоит в каком-нибудь другом треде.
Ах да. Если тебе кажется, что что-то в учебнике или задачах можно сделать лучше — пиши, обратная связь всегда очень полезна.
Если тебе лень выравнивать код руками, закачай его на 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/php-fig/fig-standards/blob/master/accepted/ru/PSR-1-basic-coding-standard.md
PSR-2: https://github.com/php-fig/fig-standards/blob/master/accepted/ru/PSR-2-coding-style-guide.md
------------------
Итак, ты зашел в тред и решил помочь какому-то анону, дав ему совет или подсказку. Спасибо! Но прочти сначала эти напоминания, чтобы твоя помощь действительно была полезной.
Будь доброжелателен
Не годится: «Ты мануал хоть раз в жизни открывал, обезьяна?»
Не годится: «В гугле забанили?»
Не годится: «Твой код плохой»
Хорошо: «Вот, как можно улучшить этот код: ...»
Хорошо: «Ты неправильно используешь функцию abc(). Вот ее описание: ссылка, и как видишь ей надо передать строку, а не массив»
Объясняй
Не очень хорошо: «сделай как в этом коде»
Хорошо: «если ты вставляешь текст от пользователя в SQL запрос, то получается SQl-инъекция, которая позволяет взломать твой сервер (ссылки). Чтобы этого избежать, надо вставлять данные с помощью плейсхолдеров (ссылки)»
Хорошо: «Помни, что код пишется для людей. Если писать такие большие функции, то в них становится трудно разобраться...»
Не проповедуй
Мы учим использованию самых распространненных подходов, стандартов, библиотеки фреймворков. Если ты не любишь ООП, пробелы в коде, jQuery, сам PHP, то рассказать об этом стоит в каком-нибудь другом треде.
Ах да. Если тебе кажется, что что-то в учебнике или задачах можно сделать лучше — пиши, обратная связь всегда очень полезна.
Предлагаю добавить рубрику "платина", или faq.
> Как стать успешным программистом, ничего не делая?
> Посоветуйте книжку, где рассказывается про ВСЕ, начиная с верстки, заканчивая симфони. Только чтобы поменьше "воды" (не больше 200 страниц)
> Как пользоваться гуглом?
> Сколько времени нужно (в минутах), чтобы выучиться на программиста? Так примерно можешь почувствовать?
> У миня оно не работает, помогайте! (Кидает код из трех строчек, где опечатка вроде price/prise)
> Что нужно знать чтобы устроиться джуниором? Я знаю синтаксис, умею делать helloworld. Меня возьмут на зп 30килорублей? За меньшие деньги не пойду, а то пацаны с бе засмеют.
>И еще кое-что. Ты вписал код загрузки картинки прямо в reg.php, но лучше бы вынести его в функции или методы. Очевидно что надо миниумм 2 функции:
— проверка правильности загруженной картинки и выдача сообщений об ошибке
— сохранение картинки
>Логично сделать класс ЗагрузчикКартинок с 2 такими методами.
Сделал. Я вот хочу ещё добавить возможность писать личные сообщения (ну или хотя бы сделать возможность оставлять комментарии в профиле у студента) с чего начать? Я так понимаю нужна будет отдельная БД со связями с БД студентов через внешние ключи?
А внешним ключем будет ID (так как он уникальный и автоинкрементный)
>> У миня оно не работает, помогайте! (Кидает код из трех строчек, где опечатка вроде price/prise)
Нет, платина это когда код не кидают, а просто пишут «не могу решить задачу» (не поясняя какую).
>>503658
Не отдельная БД, а отдельная таблица, хранящая список сообщений. А может лучше сделать для начала не личные сообщения, а стену, где можно сообщение оставить? Мне кажется, с ними проще получится.
> У миня оно не работает, помогайте! (Кидает код из трех строчек, где опечатка вроде price/prise)
Вот тут поддвачну, очень часто закидывают подобное. Пора добавить куда-нибудь памятку об ошибках в айдеоне.
Дело даже не в этом. Может человек не знает английского, и ему "undefined variable 'hello' on line 22" ничего не говорит.
Претензия к тому, что человек запустил один раз код, увидел ошибку и даже не пытался самостоятельно разобраться.
Ну прочитай ты свой код хотя бы один раз, проверь. Не хочу, хочу чтобы за меня это сделали, а я отделаюсь "спасибо :З"
Опу конечно льстит, что нубы его превозносят и любят как маму за ласковое обращение.
Но самостоятельное решение проблем для программиста один из важнейших навыков, поэтому нужно приучать заранее.
Строгость в коде, обдуманность каждой мелочи, глубокий анализ возникшей проблемы.
Или другой случай, когда человеку лень прочитать мануал полностью, он пытается что-то коряво нагородить из тех скудных знаний, что есть в наличии, а потом умоляет указать на ошибку. А ошибки нет, просто знания отсутствуют. Как решить задачу, если ты не знаешь элементарной теории?
Тогда лучше заготовить стандартную поясняющую и направляющую в нужную сторону копипасту для таких анонов.
Ну напиши, если думаешь, что ее кто-то будет читать.
Собсна, мои посты носят юмористический (ваганыч) характер, рассчитаны на людей склонных к самоиронии, а не к самобичеванию.
Я тоже пожалуй часто задаю тупые вопросы, вместо того чтобы разобраться как следует.
Например, пару недель назад познакомился с композером. "Знакомство" ограничилось composer require vendor/package, и прописыванием своих классов в его автозагрузку.
Тогда все заработало, сейчас запилил примитивный проектик для тестирования слима, точь в точь повторил все как в прошлый раз, а не работает. Автозагрузка почему-то видит слим, а смарти упорно не хочет видеть. Дамп-автолод делал раз 5, не помогает.
Так что пожалуй настало время более скрупулезно изучить возможности композера, чем задавать тут тупой вопрос "че оно не работает?"
bljad, оно же за собой тянет "slim/views"!
Вот как бывает полезно сначала подумать, а потом говорить/писать.
Черт, мне уже расхотелось читать документацию композера...
стеретипы такие.
Хуй знает. Мне 25, вот буквально пару месяцев назад начал учить, сейчас файлообменник доделываю. Вроде более-менее норм идет и это при том, что я до этого бухал как сука чуть ли не каждый день и в ММОшки дрочился, т.е. мозги вообще атрофированы были.
Ну из ммо только ева, но в нее можно месяцами не заходить. Я последнее время даже курить бросил, не то что бухать.
Конечно не поздно. Мифы о возрасте это либо маняотговорки, либо оправдания тех, кто неудачно выбрал профессию.
Вопрос только в том, удачным ли айти будет выбором для тебя?
Ожидай стандартный вопрос на собеседовании: "почему вы выбрали эту сферу?".
Если скажешь "потому что слышал, что тут получают много бабла", то тебе "перезвонят".
Required:
- энтузиазм и любовь к своему делу, тебе должно как минимум нравиться программирование, а желательно тащиться от него;
- огромное терпение, учиться придется много, информация подается неупорядоченно и бестолково;
- ну и некоторые умственные способности, способность к аналитическому и абстрактному мышлению, память как у полиглота.
>>503822
>>503824
С какими простолюдинами я обретаюсь на сем интеллигентом форуме.. (обязательно две точки.. а лучше побольше.....)
Надоело "работать с людьми", по крайней мере постоянно, ну просто до тошноты, хочу созидать в одиночестве.
Программистам тоже надо с коллегами общаться, хотя в целом конечно поменьше, чем менеджерам каким-нибудь.
Это очень отдаленно по сравнению с работой с клиентами. А где-нибудь в ритейле, где бешеная текучка, где тебя даже за человека не считают, ни клиенты, которые думают что все им должны, ни начальство с церковно-приходским управленческим образованием для которых ты живой банкомат, я как-то по молодости туда попадал, бежал оттуда как от бубонной чумы.
Оп (я тебя узнаю по \n в начале поста), расскажи о работе удаленно.
Там толково поставлена работа, или тоже нужно перебиваться как на фриланс-биржах?
Как это вообще выглядит?
Фриланс насколько я понял более чем на половину состоит из поиска клиентов, долгого обсуждения с ними проекта. А когда они допрут, что контент, логотип и сео-раскрутка сайта не входят в стоимость, то посылают в голубые дали, а ты теряешь время.
А что такое удаленка и где ее искать?
Я в крайнем случае перееду в большой город, но не хотелось бы все бросать.
Перечитайте оба (желательно, в одиночестве) книги Сент-Экзюпери, тогда наверное поймёте, что человеку нужен человек, и что работать надо как раз-таки с людьми... а не с мартыхами в обезьяннике, как в вашем случае было. И не забудьте Виктора Дольника, «Непослушное дитя биосферы», у него ещё и макаки фигурируют по всей книге (тоже в одиночестве читать надо, желательно зимними вечерами, чтобы не отвлекали).
Программизм тут не поможет никак. Вот он >>503835 прав.
>Фриланс насколько я понял более чем на половину состоит из поиска клиентов, долгого обсуждения с ними проекта.
ЛОЛШТО. Фрилонс ничем не отличается от работы IRL, люди везде одинаковы, читайте Дольника, он хорошо пишет.
Находишь на оДеске фирму с кучей т.н. «связей» и платежеспособных клиентов, она забирает 40% и откатывает из них 50% а разницу оставляет себе.
И эти вопросы задаёт человек из ретейла?
Чем же ты там был занят-то?
Это кстати был не я.
> Там толково поставлена работа,
Где работал я, там толково.
> тоже нужно перебиваться как на фриланс-биржах?
Нет.
> Как это вообще выглядит?
Обычно есть таск-трекер (редмайн/jira), в нем бескрайний список задач которые надо сделать. Бывает что тасктрекером не любят пользоваться, и просто пишут в скайп (я в таких случаях просто копипащу все это в файлик task.txt чтобы не забыть). На одной из работ у нас было еще что-то вроде митинга в скайпе, раз в неделю мы обсуждади текущее положение дел и что будет делать дальше.
Я не помню такого, чтобы задач не было, их всегда было больше чем можно сделать.
> А когда они допрут, что контент, логотип и сео-раскрутка сайта не входят в стоимость, то посылают в голубые дали, а ты теряешь время.
Это твоя вина что ты явно это не пишешь напрмер в комментарии к заказу или во время переговоров.
> Фриланс насколько я понял более чем на половину состоит из поиска клиентов, долгого обсуждения с ними проекта.
Да. Но если ты хорошо работаешь то клиенты могут обращаться к тебе напрямую. А если не очень или им нужен был одноразовый заказ то да. все печально, время уходит и никто за него не платит.
> А что такое удаленка и где ее искать?
Это как обычная работа только без присутствия в офисе. Искать по слову «удаленно», плохо что ты сам не догадался зайти на geekjob/brainstorage/hh.ru/fl.ru и попробовать воспользоваться поиском. Иди и попробуй (например на geekjob отдельный тег есть: http://geekjob.ru/vacancies/remote/ ).
Также, иногда «удаленная работа» значит что ты N дней работаешь в офисе, а M дней можешь работать из дома.
Не оставляй тогда пустую строку в начале поста.
Тут так только оп делает.
>>503850
Пошел нахуй, пудель, ты блять пойди попробуй поработать продавцом, потом по-другому запоешь.
Въеби Мольера, паскуда.
Г-н Журден. А, господин философ! Вы как раз вовремя
подоспели с вашей философией. Помирите как-нибудь этих господ.
Учитель философии. В чем дело? Что случилось, господа?
Г-н Журден. Повздорили из-за того, чье ремесло лучше,
переругались и чуть было не подрались.
Учитель философии. Полноте, господа! Как можно доводить
себя до такой крайности? Разве вы не читали ученого трактата
Сенеки о гневе? Что может быть более низкого и более
постыдного, чем эта страсть, которая превращает человека в
дикого зверя? Все движения нашего сердца должны быть подчинены
разуму, не так ли?
Учитель танцев. Помилуйте, сударь! Я преподаю танцы, мой
товарищ занимается музыкой, а он с презрением отозвался о наших
занятиях и оскорбил нас обоих!
Учитель философии. Мудрец стоит выше любых оскорблений.
Лучший ответ на издевательства-- это сдержанность и терпение.
Учитель фехтования. Они имеют наглость сравнивать свое
ремесло с моим!
Учитель философии. Это ли повод для волнения? Из-за
суетной славы и из-за положения в обществе люди не должны
вступать между собою в соперничество: чем мы резко отличаемся
друг от друга, так это мудростью и добродетелью.
Учитель танцев. Я утверждаю, что танцы -- это наука,
заслуживающая всяческого преклонения.
Учитель музыки. А я стою на том, что музыку чтили во все
века.
Учитель фехтования. А я им доказываю, что наука владеть
оружием -- это самая прекрасная и самая полезная из всех наук.
Учитель философии. Позвольте, а что же тогда философия? Вы
все трое -- изрядные нахалы, как я погляжу: смеете говорить в
моем присутствии такие дерзости и без зазрения совести
называете науками занятия, которые не достойны чести
именоваться даже искусствами и которые могут быть приравнены
лишь к жалким ремеслам уличных бортов, певцов и плясунов!
Учитель фехтования. Молчать, собачий философ!
Учитель музыки. Молчать, педант тупоголовый!
Учитель танцев. Молчать, ученый сухарь!
Учитель философии. Ах вы, твари эдакие... (Бросается на
них, они осыпают его ударами.)
Не оставляй тогда пустую строку в начале поста.
Тут так только оп делает.
>>503850
Пошел нахуй, пудель, ты блять пойди попробуй поработать продавцом, потом по-другому запоешь.
Въеби Мольера, паскуда.
Г-н Журден. А, господин философ! Вы как раз вовремя
подоспели с вашей философией. Помирите как-нибудь этих господ.
Учитель философии. В чем дело? Что случилось, господа?
Г-н Журден. Повздорили из-за того, чье ремесло лучше,
переругались и чуть было не подрались.
Учитель философии. Полноте, господа! Как можно доводить
себя до такой крайности? Разве вы не читали ученого трактата
Сенеки о гневе? Что может быть более низкого и более
постыдного, чем эта страсть, которая превращает человека в
дикого зверя? Все движения нашего сердца должны быть подчинены
разуму, не так ли?
Учитель танцев. Помилуйте, сударь! Я преподаю танцы, мой
товарищ занимается музыкой, а он с презрением отозвался о наших
занятиях и оскорбил нас обоих!
Учитель философии. Мудрец стоит выше любых оскорблений.
Лучший ответ на издевательства-- это сдержанность и терпение.
Учитель фехтования. Они имеют наглость сравнивать свое
ремесло с моим!
Учитель философии. Это ли повод для волнения? Из-за
суетной славы и из-за положения в обществе люди не должны
вступать между собою в соперничество: чем мы резко отличаемся
друг от друга, так это мудростью и добродетелью.
Учитель танцев. Я утверждаю, что танцы -- это наука,
заслуживающая всяческого преклонения.
Учитель музыки. А я стою на том, что музыку чтили во все
века.
Учитель фехтования. А я им доказываю, что наука владеть
оружием -- это самая прекрасная и самая полезная из всех наук.
Учитель философии. Позвольте, а что же тогда философия? Вы
все трое -- изрядные нахалы, как я погляжу: смеете говорить в
моем присутствии такие дерзости и без зазрения совести
называете науками занятия, которые не достойны чести
именоваться даже искусствами и которые могут быть приравнены
лишь к жалким ремеслам уличных бортов, певцов и плясунов!
Учитель фехтования. Молчать, собачий философ!
Учитель музыки. Молчать, педант тупоголовый!
Учитель танцев. Молчать, ученый сухарь!
Учитель философии. Ах вы, твари эдакие... (Бросается на
них, они осыпают его ударами.)
>человеку нужен человек
Это сказал Лем в "Солярисе". Уебывай, быдло неграмотное, сын проститутки и членодевки.
>Пошел нахуй, пудель, ты блять пойди попробуй поработать продавцом, потом по-другому запоешь.
Вот это взрыв! Как тебя разнесло-то... ыыыыы
А тем временем, я не всю жисть погромистом, был. После 2008 года на цементном заводе херачил и керамическую плитку продавал, холодными звонками. По итогам (и дробильщиком на чайной фабрике поработал, там сморкался чорными соплями уже) заучил этих двух пейсателей наизусть.
>Учитель философии. Ах вы, твари эдакие... (Бросается на них, они осыпают его ударами.)
Мольер, я смотрю, вообще охуенен.
>Не оставляй тогда пустую строку в начале поста.
Ахуеть. Какой ОП общительный однако, умудряется в куче тредов на Дваче сидеть сразу!
Вообще, предлагаю ОП-у ставить галочку "ОП треда", чтобы путаницы не было, вот и все.
Отстань, зануда, я устал и мне нужно отдохнуть.
У тебя с детектором саусэм беда.
Что ты нашел здесь, на фронте, сержант, откуда эта спокойная уверенность, что именно здесь твое место и твоя судьба? Быть может, ею тебя одарила братская рука, приподнявшая твою сонную голову, быть может - улыбка, полная той нежности, в которой не сочувствие, но равенство? "Эй, товарищ!.." Когда кому-то сочувствуешь, вас еще двое. Вы еще врозь. Но бывает та высота отношений, когда благодарность и жалость теряют смысл. И, поднявшись до нее, дышишь легко и радостно, как узник, вышедший на волю.
Отчего бы тому, кто готовил тебя к смерти, жалеть тебя, сержант? Все вы готовы были умереть друг за друга. В такую минуту людей соединяют узы, которым уже не нужны слова. И я понял, почему ты пошел воевать. Если в Барселоне ты был бедняком, и тебе после работы бывало одиноко, и не было у тебя теплого пристанища, то здесь ты поистине стал человеком...
А вот средний пейсатель сайтов человеком ещё нескоро станет. А всё почему?
Почему средняя похапе-макака так и не становится человеком.
Всё потому, что рядом с ней другого человека нет.
Ой, какая страшная картинка. Это убедит меня перестать писать.
Людям просто скучно, поэтому хочется поболтать и подурачиться. Нужно быть умственно отсталым дауном с синдромом дауна, чтобы воспринимать происходящее на сосачах всерьез.
Что касается троллей, то их нужно не кормить, то есть игнорировать.
>>503898
Любой яой.
У тебя в средине выполняются какие то действия, цикл, а потом в конце просто выводится на экран переменная из начала скрипта без каких-либо действий или выбора.
>>503950
Я думаю, что вы прочитали пост про "платиновые вопросы" >>503635
и решили приколоться, повторив их. Хвалю, я люблю шутки, в отличие от всяких зануд.
>>503946
Если это первый язык, то минимум полгода. Нужно учиться не столько языку, сколько изучать программирование в целом.
>>503950
Значок доллара потерял вот здесь
for ($i = 0; $i <= halfLength; $i++)
По своему опыту скажу - мне хватило знаний чтобы пройти на интернатуру за 1.5 месяца обучения. Но у меня был сильный бэкграунд матан, плюс очень хорошо знаком c работой серверов и всё такое, потому что сидел на линуксах и поднимал сервера всякие частенько, ставил скриптики
Думаю реально 3-6+ месяцев это средняя планка на тяп-ляп джуна, если нормально заниматься. Например средняя интернатура ЕПАМ-а или подобной компании идёт около 6-7 месяцев, после чего тебя переводят на джуна. Но стоит учитывать, что кроме программирования там очень много всякой хуиты вроде умения работать по агилам, скрамам, все эти митинги и подобные радости, короче учат ещё работать в команде и компании.
Ну, как-то вот так. Я правда по питону и жс. Но могу сказать, что больше всего опыта мне принесло чтение чужого кода во время написания своего. Нет особого смысла тужится над решением задачи, если ты можешь найти хорошее решение и понять его ну и запомнить, что важно. Программирование всё таки о решении задач в первую очередь.
чем быстрее научишься искать ответы на стаковерфлоу и подобных сайтах тем лучше, это пожалуй самое главное, если не умеешь в поиск информации - будет очень хуево
Какой хоткей поставить на reindent?
А то стандартного почему-то нет, в гугле советуют хуйню.
Желательно с оглядкой на большие IDE вроде phpstorm или NetBeans. Вдруг я на них перекачусь в будущем, вдруг там уже есть подобный хоткей?
Хоткеи в других IDE: https://gist.github.com/codedokode/8759492
Учти что Ctrl + Shift + F это поиск по проекту, очень нужная фича.
Алсо, у самого ЦП офис конечно минималистичный.
спс, присмотрел ctrl + alt + L, как в шторме.
Насчет CodeFormatter для саблайма не понял, зачем он нужен.
CodeFormatter is a Sublime Text 2/3 plugin that supports format (beautify) source code.
Ну какой-то плагин для форматирования. Чем знаменит?
Я когда копирую код из других редакторов, он расползается, я нажимаю Edit->Line->Reindent, и оно само выравнивается. Мне хватает.
Не хочу лишний плагин, sublime и так ими обмазан.
Мне больно смотреть на фото, они там друг другу в лицо дышат.
Метрах в пяти хотя бы рассадить.
https://github.com/V3N0m21/StudentList
Переделал по твоим замечаниям, по поводу регистрозависимого поиска, у меня такой проблемы как у тебя не было, но все-равно добавил collate в запрос, должно работать.
Насчет форматирования кода, я использую Sublime Text 2, почитаю что там у них есть для автоматизации форматирования, и как лучше этим пользоваться. Если кто-то еще пользуется сублаймом, напишите что у вас там установлено и какие удобности вы юзаете.
>>503590
Ну а с файлообменником ебли походу будет на порядок больше чем я думал.
Я там использую Paris ORM, вопрос, стоит его использовать, или лучше просто сделать класс с запросами PDO?( на студентах юзал mysli, но PDO походу на порядок удобнее)
Я в саблайме пользуюсь множественными курсорами (что-то вроде автозамены по всему файлу в режиме реального времени), поиском, некоторыми клавишами типа ctrl + shift + D для редактирования строк, плагин emmet. Пока все, но без этого уже трудно себе представить работу.
По возможностям sublime есть видеообзоры от tuts+ и pluralsight на рутрекере.
Надо будет тоже еще разок пересмотреть, может еще что-то новое смогу запомнить.
Уже все мануалы из инет испробовал везде стоит ЮТФ-8.
В чем выражается "НЕ РАСПОЗНАЕТ???"
Ты смотришь базу в каком-нибудь phpmyadmin или в консоли?
Или ты пытаешься вывести данные из базы на страницу и выдает кракозябры?
Ну например когда файл успешно загружен, нужно вывести пользователю такую зеленую табличку с сообщением об успешной операции.
А если ошибка, то соответственно сообщение об ошибке.
Так вот, насколько я помню ты советовал не использовать флеш-сообщения типа слимовских, основанных на сессиях и куках, а передавать эти месседжи через квери стринг.
Вроде неплохое решение, но меня напрягает момент, когда пользователь начнет обновлять страницу, а сообщение никуда не денется. Или еще хуже вместе с гет-параметрами положит в закладки.
Как этого избежать?
>phpmyadmin
this. в базе пустая строчка - там где должно быть сообщение в кириллице (латинницу читает). не записывает кириллицу.
Ну за вечер для полного дауна в погромировании уже успех.
Пацаны, только не бейте, но я даже дефолтную прогу hello world открыть не могу, денвер ставил как в инструкции, запихнул вроде тож куда надо, пробовал даже в другие директории, локальная страничка денвера норм запускается и работает, а hello world или что-то другое я уже перепробовал разными способами, но все равно открывает либо пустое окно браузера, девственно чистое,либо фрагмент кода какой-то отображается типа <?echo
Что я делаю не так?
Пости свой код на ideone.com
там как я понял, о том как писать код круто, да?
> но меня напрягает момент, когда пользователь начнет обновлять страницу, а сообщение никуда не денется.
Это может быть полезно, например если при обрыве связи страница не догрузилась, то пользователь обновляет ее и хочет увидеть уведомление. В случае с флеш уведомлениями он их не увидит.
> Или еще хуже вместе с гет-параметрами положит в закладки.
Тогда уведомление останется, и тут надо радикально усложнять систему, чтобы оно не показывалось второй раз, например придумывать уникальные идентификаторы для сообщений и куда-то запоминать список уже показанных. Или яваскриптом после загрузки менять URL страницы, удаляя оттуда параметры.
По моему, оно того не стоит. Да и если пользователь сохраняет в закладки страницу с сообщением, мне кажется, вполне нормально его увидеть при открытии закладок (конечно если воспринимать страницу не как статичную страницу, а как приложение, то нелогично видеть старое уведомление. Но приложения ведь нельзя помещать в закладки).
Кне кажется квери стринг лучше кук тем, что она не влияет на соседние вкладки и тем что при проблемах со связью сообщение не исчезает.
Покажи простой пример кода, в несколько строчек, которым ты что-то вставляешь в базу, чтобы видны быди параметры соединения. Кодировку при соединении указываешь? файлы в utf-8 сохранены?
>>504113
Что в адресной строке браузера?
Алсо денвер для опытных программистов и к тому же это старье, начинающим лучше ставить Апач или PHP руками. Есть туториалы:
https://gist.github.com/codedokode/10774100
https://gist.github.com/codedokode/7054af4a03865c4cc863
https://gist.github.com/codedokode/10539568
>>504126
Они платные? Если ты начинающий то может быть полезно их пройти, судя по содержанию, они там пытаются научить функциональщине. Этому конечно удобнее учиться на примере языка типа Хаскелл, в PHP код более топорный и некрасивый получится.
Вообще, главное чтобы ты знал какие есть методы реализации и какие у них преимущества/недостатки, чтобы мог выбрать подходящий.
Там еще есть функции «перейти к » с нечетким поиском, очень полезные:
F12 перейти к определению функции/класса под курсором
Ctrl + P — перейти к файлу
Ctrl + R — к функции в текущем файле
Ctrl + Shift + R — к функции/классу в проекте
Ctrl + Shift + P — поиск по командам
Ctrl + Alt + P — переключиться на другой проект
> по поводу регистрозависимого поиска, у меня такой проблемы как у тебя не было,
Можешь сделать запросы:
SELECT VERSION();
SELECT COLLATION(BirthDate) FROM Students;
SELECT COLLATION(CONCAT(Name,BirthDate)) FROM Students;
SHOW VARIABLES LIKE '%collat%';
? надо бы разобраться, в чем дело, может дело в версии БД например.
Запросы можно делать из командной строки mysql или программ типа phpmyadmin.
Сделай в таблице уникальный ключ по email и по password (и наверно по photo). Чтобы база данных не разрешала вставлять повторяющиеся значения и чтобы тому что читает sql дамп было очевидно что колонки уникальные.
> $loadedImage = $image->checkImage($_FILES);
Я думаю, надо передавать в функцию имя файла в массиве _FILES. Сейчас оно у тебя там жестко прописано, и так мы сделаем функцию более универсальной. Было бы хорошо если класс работы с изображениями был универсальным и его можно было использовать в другом проекте.
Также, давай подумаем, как должен быть устроен этот класс? Очевидно, там должна быть функция проверки файла и сохранения файла:
— checkImage(массив из FILES или имя элемента в нем)
— savePhoto(массив из FILES)
Эти функции работают с загруженным через форму файлом, информация о котором в FILES. Но что если мы хотим например скриптом прописать аватарку из файла на диске? Тогда очевидно нам понадобятся 2 более базовых функции, которые работают не с файлом из _FILES, а с любым файлом на диске:
— проверить файл
— сохранить файл
А те функции, что выше, вызывают их.
Чтобы класс был универсальным, все настройки, вроде пути сохранения файлов и максимального размера, надо вынести в поля класса.
Далее, нам надо как-то генерировать путь, куда будет сохранена картинка. Значит, нам нужна функция, определяющая путь к файлу, куда мы сохрняем картинку.
Теперь еще ошибки:
> if ($image["photo"]["error"] == 4) {
Там есть константы, их надо использовать. Внимтельно прочитай мануал тут: https://secure.php.net/manual/ru/features.file-upload.errors.php
>
$photo['error'] = "Ошибка загрузки: " . $image["photo"]["error"];
Пользователю цифра ничего не говорит. Сделай метод, который выдает понятные сообщения об ошибке, без технических подробностей (файл слишком большой, допустимый размер X, не удалось загрузить, проблемы на сервере и тд)
> if ((($image["photo"]["type"] == "image/gif")
> || ($image["photo"]["type"] == "image/jpeg")
Используй тут if (in_array())
Также, я бы не советовал делать эту проверку так как тип файла передает браузер и злоумышленник может передать там что угодно. Я советую вообще игнорирвать это поле.
А проверять надо расширение файла (чтобы нам не загрузили php скрипт например), а также его содержимое (функция getimagesize умеет определять какого типа картинка независимо от расширения).
Кстати, говоря о безопасности, злоумышленник может попытаться загрузить нам .htaccess файл или php скрипт чтобы взломать наш сервер. Ты должен либо проверять расширение сохраняемого файла по белому списку, либо принудительно ставить ему безопасное расширение.
> && ($image["photo"]["size"] < 200000))
Максимальный размер надо сделать полем в классе, и наверно надо сделать функцию, которая его возвращает, чтобы ты мог в шаблоне написать рядом с полем этот размер.
>
if (file_exists("upload/" . $image["photo"]["name"])) // проверка существования на сервере
> {
> $photo['error'] = 'Это фото уже существует на сервере';
Это неправильная проверка, так как разные студенты могут загрузить файл с одинаковм именем, но разным содержимым. Чтобы имена не повтоярлись, можно приписывать перед именем id студента. Более того, можно вообще принудительно переименовывать файл по типу
photo-12.jpg
Так как в имени файла могут содержаться какие-то символы которые не поддерживаются файловой системой (например под Windows PHP поддерживает только символы в кодироке 1251).
Еще, я не понимаю, почему функция проверки возвращает и ошибки, и имя файла. Это запутывает. Я считаю, она должна только возвращать ошибку или ее отсуствие.
Также, люди загружают фотографии самых разных размеров. Значит, нам нужно их ресайзить и делать уменьшенные копии. Я думаю, это стоит сделать отдельным классом, независимым от ImageUploader, который может сделать из данной картинки картинку другого размера. ImageUploader будет вызывать этот класс, чтобы сделать одну или несколько копий картинки. Имена можно делать примерно по такому принципу:
avatar-original-12.jpg
avatar-100x100-12.jpg
В общем, давай поработаем над классом ImageUploader, его надо переделать.
Сделай в таблице уникальный ключ по email и по password (и наверно по photo). Чтобы база данных не разрешала вставлять повторяющиеся значения и чтобы тому что читает sql дамп было очевидно что колонки уникальные.
> $loadedImage = $image->checkImage($_FILES);
Я думаю, надо передавать в функцию имя файла в массиве _FILES. Сейчас оно у тебя там жестко прописано, и так мы сделаем функцию более универсальной. Было бы хорошо если класс работы с изображениями был универсальным и его можно было использовать в другом проекте.
Также, давай подумаем, как должен быть устроен этот класс? Очевидно, там должна быть функция проверки файла и сохранения файла:
— checkImage(массив из FILES или имя элемента в нем)
— savePhoto(массив из FILES)
Эти функции работают с загруженным через форму файлом, информация о котором в FILES. Но что если мы хотим например скриптом прописать аватарку из файла на диске? Тогда очевидно нам понадобятся 2 более базовых функции, которые работают не с файлом из _FILES, а с любым файлом на диске:
— проверить файл
— сохранить файл
А те функции, что выше, вызывают их.
Чтобы класс был универсальным, все настройки, вроде пути сохранения файлов и максимального размера, надо вынести в поля класса.
Далее, нам надо как-то генерировать путь, куда будет сохранена картинка. Значит, нам нужна функция, определяющая путь к файлу, куда мы сохрняем картинку.
Теперь еще ошибки:
> if ($image["photo"]["error"] == 4) {
Там есть константы, их надо использовать. Внимтельно прочитай мануал тут: https://secure.php.net/manual/ru/features.file-upload.errors.php
>
$photo['error'] = "Ошибка загрузки: " . $image["photo"]["error"];
Пользователю цифра ничего не говорит. Сделай метод, который выдает понятные сообщения об ошибке, без технических подробностей (файл слишком большой, допустимый размер X, не удалось загрузить, проблемы на сервере и тд)
> if ((($image["photo"]["type"] == "image/gif")
> || ($image["photo"]["type"] == "image/jpeg")
Используй тут if (in_array())
Также, я бы не советовал делать эту проверку так как тип файла передает браузер и злоумышленник может передать там что угодно. Я советую вообще игнорирвать это поле.
А проверять надо расширение файла (чтобы нам не загрузили php скрипт например), а также его содержимое (функция getimagesize умеет определять какого типа картинка независимо от расширения).
Кстати, говоря о безопасности, злоумышленник может попытаться загрузить нам .htaccess файл или php скрипт чтобы взломать наш сервер. Ты должен либо проверять расширение сохраняемого файла по белому списку, либо принудительно ставить ему безопасное расширение.
> && ($image["photo"]["size"] < 200000))
Максимальный размер надо сделать полем в классе, и наверно надо сделать функцию, которая его возвращает, чтобы ты мог в шаблоне написать рядом с полем этот размер.
>
if (file_exists("upload/" . $image["photo"]["name"])) // проверка существования на сервере
> {
> $photo['error'] = 'Это фото уже существует на сервере';
Это неправильная проверка, так как разные студенты могут загрузить файл с одинаковм именем, но разным содержимым. Чтобы имена не повтоярлись, можно приписывать перед именем id студента. Более того, можно вообще принудительно переименовывать файл по типу
photo-12.jpg
Так как в имени файла могут содержаться какие-то символы которые не поддерживаются файловой системой (например под Windows PHP поддерживает только символы в кодироке 1251).
Еще, я не понимаю, почему функция проверки возвращает и ошибки, и имя файла. Это запутывает. Я считаю, она должна только возвращать ошибку или ее отсуствие.
Также, люди загружают фотографии самых разных размеров. Значит, нам нужно их ресайзить и делать уменьшенные копии. Я думаю, это стоит сделать отдельным классом, независимым от ImageUploader, который может сделать из данной картинки картинку другого размера. ImageUploader будет вызывать этот класс, чтобы сделать одну или несколько копий картинки. Имена можно делать примерно по такому принципу:
avatar-original-12.jpg
avatar-100x100-12.jpg
В общем, давай поработаем над классом ImageUploader, его надо переделать.
Также, пропусти ImageUploader через phpformatter.com, или разберись как форматирование делается в твоем редакторе, а то тяжело его читать.
И еще. У тебя у поля photo стоит NOT NULL — значит фото обязательно надо приложить при регистрации?
> inspectStudentByPassword
Традиционно такую функцию называют findSomethingBySomething()
> function setClassOfElement($activeElement='') {
Это удобнее сделать так:
<li <?= ($active == 'register') ? ' class="active" ' : '' ?>>
или так:
<li <?php if ($active == 'register'): ?> class="active" <?php endif ?>>
Второй вариант по моему чище смотрится.
> scripts/image_preview.php
Этот скрипт генерирует картинку при каждом обращении. Это довольно неэффективно, так как создает лишнюю нагрузку на процессор, представь 1000 человек зашло и скрипт 1000 раз одну и ту же картинку уменьшает.
Выгоднее сделать по-другому:
— либо генерировать и сохранять уменьшенные картинки при загрузке аватарки
— либо генерировать превьюшку при первом обращении к ней. Это можно сделать так, мы с помощью htaccess настраиваем, что при обращении к несуществующему файлу в папке /upload/preview/ вызывается РHP скрипт, который генерирует превьюшку, сохраняет на диск и отдает в браузер. При втором обращении файл уже будет на диске и Апач отдаст его сразу. не вызывая PHP.
> https://github.com/Si0n/register3/blob/197dbc9b781f2df5b4282d740a8a947a227a7674/template/edit.php#L6
неправильно расставлены теги <p>
> scripts/image_preview.php?photo=<?=htmlProtect($profileByID->getPhoto())?>
Ссылку надо генерировать с помощью функции, а не копипастить сложные конструкции.
Также, при подстановке параметров в ссылку в query string надо использовать urlencode (до htmlprotect)
> https://github.com/Si0n/register3/blob/197dbc9b781f2df5b4282d740a8a947a227a7674/template/list.php#L4
> switch
switch плохо выглядит в шаблоне, не стоит его исопльзовать, используй if/elseif
Не используй магиеские цифры. Вот как я пойму что тут значит цифра 2?
$tablePanelHeadingText = 2;
Это абсолютно непонятно. Ты должен либо использовать константы с понятными именами (TAB_HEADER_NOTHING_FOUND), либо переменные такого вида:
$isSearchMode
например:
<?php if ($isSearchMode && !$result): ?>
Ничего не найдено по запросу ....
Если ты используешь переменные то они должны иметь понятные имена и всегда существовать.
> inspectStudentByPassword
Традиционно такую функцию называют findSomethingBySomething()
> function setClassOfElement($activeElement='') {
Это удобнее сделать так:
<li <?= ($active == 'register') ? ' class="active" ' : '' ?>>
или так:
<li <?php if ($active == 'register'): ?> class="active" <?php endif ?>>
Второй вариант по моему чище смотрится.
> scripts/image_preview.php
Этот скрипт генерирует картинку при каждом обращении. Это довольно неэффективно, так как создает лишнюю нагрузку на процессор, представь 1000 человек зашло и скрипт 1000 раз одну и ту же картинку уменьшает.
Выгоднее сделать по-другому:
— либо генерировать и сохранять уменьшенные картинки при загрузке аватарки
— либо генерировать превьюшку при первом обращении к ней. Это можно сделать так, мы с помощью htaccess настраиваем, что при обращении к несуществующему файлу в папке /upload/preview/ вызывается РHP скрипт, который генерирует превьюшку, сохраняет на диск и отдает в браузер. При втором обращении файл уже будет на диске и Апач отдаст его сразу. не вызывая PHP.
> https://github.com/Si0n/register3/blob/197dbc9b781f2df5b4282d740a8a947a227a7674/template/edit.php#L6
неправильно расставлены теги <p>
> scripts/image_preview.php?photo=<?=htmlProtect($profileByID->getPhoto())?>
Ссылку надо генерировать с помощью функции, а не копипастить сложные конструкции.
Также, при подстановке параметров в ссылку в query string надо использовать urlencode (до htmlprotect)
> https://github.com/Si0n/register3/blob/197dbc9b781f2df5b4282d740a8a947a227a7674/template/list.php#L4
> switch
switch плохо выглядит в шаблоне, не стоит его исопльзовать, используй if/elseif
Не используй магиеские цифры. Вот как я пойму что тут значит цифра 2?
$tablePanelHeadingText = 2;
Это абсолютно непонятно. Ты должен либо использовать константы с понятными именами (TAB_HEADER_NOTHING_FOUND), либо переменные такого вида:
$isSearchMode
например:
<?php if ($isSearchMode && !$result): ?>
Ничего не найдено по запросу ....
Если ты используешь переменные то они должны иметь понятные имена и всегда существовать.
Покажи кусочек кода где ты хочешь поставить return. return выходит из функции и возвращает значение. Я не очень понимаю, как с его помощью можно отдать контент в браузер.
Кстати, не забудь выставить еще правильный Content-Type. Мне кажется, для отдачи JSON стоит сделать функцию которая получает на вход массив данных.
Если ты слишком много будешь смотреть аниме, я не уверен что у тебя останется время на изучение php. А так, я обычно смотрю списки вроде «summer 2015 anime» и по описаниям смотрю что нравится, потом смотрю топы на myanimelist и «похожие», иногда могу в /a заглянуть, иногда на ютубе на что-то интересное наткнуться. Но лучше все же себя ограничивать. Тем более что лето на дворе.
return возвращает значение из функции, а не результат HTTP запроса в браузер.
Также, я не понимаю, какой смысл в этом:
> echo 'Ошибка!';
Ты не можешь это проверить скриптом в браузере, ты не указал кодировку и надпись может отобразиться криво.
Я думаю, что прежде чем изучать аякс запросы надо изучить теорию и общие принципы. А они такие:
— надо обрабатывать сетевые и другие ошибки (если ты используешь jQuery то надо указывать параметр error в функции $.ajax, если пишешь на чистом JS то надо проверять ситуацию когда вернулся код ответа не 200)
— надо показывать пользователю что идет загрузка. Если загрузка запускается какой-то кнопкой, надо блокировать эту кнопку на время загрузки
— надо обрабатывать ситуации когда сервер вернул ответ, но он непраивльный. Обычно это делают так: сервер возвраащет ответ в виде JSON, и если он вернул не JSON или там нет поля с результатом, то это ошибка. Если ты просто загружаешь аяксом кусок HTML то тебе может быть неохота заморачиватья с использованием JSON ради одного поля. Тогда ты должен сигнализировать об ошибке HTTP кодом 5xx, например 503. А не текстом, который скрипт не может прочесть и понять.
— при ошибке пользователь должен увидеть понятное сообщение (если ты используешь бутстрап то там есть готовый класс для оформления сообщений) и иметь возможность повторить запрос.
Если статья по которой ты учился про это не рассказыает, то плохо, значит ее автор сам не очень разбирается в теме.
Я тебе могу дать готовый шаблон кода на JQuery для таких случаев:
function makeRequest()
{
lockButton(true); // блокируем кнопку и показываем индикатор загрузки
$.ajax({
url: ...
type: ...
dataType: ...
data: ...
complete: function () {
lockButton(false); // разблокируем кнопку
},
error: function (....) {
....
},
success: function (result) {
if (!result.success) {
.. покаазть ошибку ..
return;
}
// выводим результат
$('#some-place').html(result.html);
}
});
return возвращает значение из функции, а не результат HTTP запроса в браузер.
Также, я не понимаю, какой смысл в этом:
> echo 'Ошибка!';
Ты не можешь это проверить скриптом в браузере, ты не указал кодировку и надпись может отобразиться криво.
Я думаю, что прежде чем изучать аякс запросы надо изучить теорию и общие принципы. А они такие:
— надо обрабатывать сетевые и другие ошибки (если ты используешь jQuery то надо указывать параметр error в функции $.ajax, если пишешь на чистом JS то надо проверять ситуацию когда вернулся код ответа не 200)
— надо показывать пользователю что идет загрузка. Если загрузка запускается какой-то кнопкой, надо блокировать эту кнопку на время загрузки
— надо обрабатывать ситуации когда сервер вернул ответ, но он непраивльный. Обычно это делают так: сервер возвраащет ответ в виде JSON, и если он вернул не JSON или там нет поля с результатом, то это ошибка. Если ты просто загружаешь аяксом кусок HTML то тебе может быть неохота заморачиватья с использованием JSON ради одного поля. Тогда ты должен сигнализировать об ошибке HTTP кодом 5xx, например 503. А не текстом, который скрипт не может прочесть и понять.
— при ошибке пользователь должен увидеть понятное сообщение (если ты используешь бутстрап то там есть готовый класс для оформления сообщений) и иметь возможность повторить запрос.
Если статья по которой ты учился про это не рассказыает, то плохо, значит ее автор сам не очень разбирается в теме.
Я тебе могу дать готовый шаблон кода на JQuery для таких случаев:
function makeRequest()
{
lockButton(true); // блокируем кнопку и показываем индикатор загрузки
$.ajax({
url: ...
type: ...
dataType: ...
data: ...
complete: function () {
lockButton(false); // разблокируем кнопку
},
error: function (....) {
....
},
success: function (result) {
if (!result.success) {
.. покаазть ошибку ..
return;
}
// выводим результат
$('#some-place').html(result.html);
}
});
Да блин, я просто не совсем корректно работу AJAX понял. Все, что ты написал у меня и так уже сделано. Ответ я через кастомное модальное окошко вывожу.
Я там ещё пригвоздил за утро стену с сообщениями к профилям, а тут ещё столько всего по картинкам :<
Ну это же учебный проект. Здесь важнее получить знания, а не сделать как можно быстрее.
Поэтому оп подталкивает к изучению многочисленных техник, иногда нафиг не нужных в конкретном проекте, или даже как сделать одно и то же разными способами, проанализировать преимущества и недостатки каждого подхода.
Я тоже сделал костяк файлообменника за три дня. А оп четвертую неделю гоняет с указаниями "почитай про вот это", "а здесь можно сделать проще", "это перенести в другой класс" и т.д.
Наверное, класс программиста определяется именно безукоризненностью его работы. Сделать простое приложение "лишь бы работало" может любой быдлокодер за пару дней. Нам нужно оттачивать мастерство, внимательно изучая все казалось бы "мелочи". Мелочи на самом деле гораздо важнее стандартного куска кода, где что-то записывается/выбирается из базы и выводится на экран.
------------------------------------------------
Я заканчиваю файлообменник (или думаю, что заканчиваю), теперь не знаю, браться ли за последний большой квест на сайт с тестами.
Подозреваю, что работа над ним растянется минимум на 2-3 месяца. А мне как бы кушать хочется, я без работы уже год сижу.
Так что наверное я таки лучше изучу хорошенько фреймворки (Yii и сколько успею Симфони), сделаю на них пяток простых приложений и пойду наконец по собеседованиям.
А в свободное от работы время буду уже делать это большое задание.
Нет, он проверяет наличие значения в массиве, никаких сравнений не делает.
http://php.net/manual/ru/function.in-array.php
Используй foreach.
У меня в городе видел объявы стажеров за еду с базовыми знаниями, подтягивают до джуниора и берут.
Застрял на задачке про рост, если ставлю условие(if) при переборе что a>b, подсчет останавливается после первого же достигнутого значения, можно конечно писать сравнение для каждого числа в массиве, но это ж лапша получится.
Я там с исходными числами поигрался, чтобы удостоверится что работает. http://ideone.com/Xo18zk щас нагляднее.
Это или наебщики, которые предложат тебе платные "курсы", или ты будешь заниматься черновой бессмыссленной работой, никаких "подтягиваний" не будет.
Я в одно такое место пошел, заставили поправлять вордпресс, потом вообще шокировали заданием "скопировать контент сайта". Ну кароче открываешь исходный код страницы, копируешь в блокнотик и сохраняешь)) Только ссылочки потом надо переписать, чтобы пути к картинкам и css не поломались. Вы ебанутые что ли? На линуксе это одной строкой wget делается! Бля, дайте мне хоть установить какую-нибудь иде, чтобы заменить все эти битые ссылки, я же не даун это руками исправлять! "Чо такое иде? Не, мы тебе не можем пока разрешить что-то устанавливать на этот компьютир. Вдруг ты что-то поломаешь, ты же неопытный, и нам придется вызывать мастера переустанавливать Виндоус".
Обязательно спрашивай, как будешь собеседоваться, чем занимается контора, какие технологии использует. Если они занимаются "поддержкой проектов", это значит скорее всего они чистят говно на cms. Контора обязана вести собственные проекты. Это интересно, надежно, и многому можно научиться у коллег-программистов, а не шимпанзе-копипастеров.
Да, то что ты описал, это дноконтора которая видимо просто ищет желающих поработать за еду, ее лучше избегать. Глупо тратить свое время на рутину.
>Обязательно спрашивай, как будешь собеседоваться, чем занимается контора, какие технологии использует. Если они занимаются "поддержкой проектов", это значит скорее всего они чистят говно на cms. Контора обязана вести собственные проекты. Это интересно, надежно, и многому можно научиться у коллег-программистов, а не шимпанзе-копипастеров.
Всё правильно написал. Обычно если это интернатура, то там сразу говорят сколько она будет идти, программу и всё такое и информация есть на их сайте или на порталах для программистов/студентов. А абстрактное "подтянем" звучит довольно подозрительно, особенно от ноунеймов каких-нибудь.
Мой друг когда устраивался на работу в тупикал аутсорс компани, то там ему выкатили охуетельный план обучения на 5 месяцев с кучей заданий.
теория вроде бесплатная, хотя хз на самом деле. Сервис еще не дорос до того, чтобы платить 10$ в месяц, имхо. Уроки в формате по 3 мин. не торт.
Есть два числа. Нужно проверить введенные данные на число и проверить какое из них больше. Если введено не число просто вывести ошибку и перестать выполнять скрипт
$e=is_numeric($a);
$c=is_numeric($b);
if( $e == false){ echo "Enter number 1"; }
if( $c == false ){ echo "Enter number 2";}
if( $a < $b){
echo $a;
}else {
echo $b;
}
у меня скрипт продолжает работать после проверки
Переменные типа $e и $c (что за дурацкие названия?) не нужны.
Можно сразу написать if(!is_numeric($a)).
Оберни это все в функцию, и в нужных местах проставь return false, который ее прервет.
>>504303
Break выбрасывает только из циклов.
http://php.net/manual/ru/control-structures.break.php
Вместо if использовать swith?
Ан нет, break может прервать не только цикл, но и скрипт.
Об этом пишет в каментах steve at electricpocket
http://php.net/manual/ru/control-structures.break.php#109050
if(true) break тоже работает.
Кстати про циклы, если в цикле несколько условий, то применяются они поочередно или сразу вместе, я знаю что без continue условие применяется 1 раз вначале цикла и все.
Я ничего не понял, что ты сказал.
У цикла не может быть нескольких условий. Условие только одно, оно проверяется на каждой итерации.
Например у цикла for($i=0; $i < 100; $i++)
условием будет $i < 100.
Первое выражение $i=0 отрабатывает только один раз перед началом цикла. Можно его даже вынести наружу перед циклом
$i = 0;
for( ; $i < 100; $i++)
В цикле while только так и можно инициализировать счетчик.
Третья часть выполняется в конце каждой итерации после тела цикла. Поэтому можно записать ее например в теле цикла
for ( ; $i < 100; ) {
$arr[$i] = $i;
$i++;
}
Несколько условий может быть ты имеешь ввиду что-то типа ($i < 100 and $j > 0 or $k!=20).
Естественно все выражение будет приведено к true/false.
Я имел ввиду внутри цикла через if, немного не так написал.
Спасибо, работает! Можно ещё лучше сделать?
function numb($a, $b) {
if(!is_numeric($a)) {
echo "Enter number 1";
return false;
}
if(!is_numeric($b)){
echo "Enter number 2";
return false;
}
if( $a > $b){
echo $a;
}else {
echo $b;
}
}
numb($_POST['a'], $_POST['b']);
>>504314
Break вызывает ошибку Cannot break/continue 1 level
Сейчас решил взяться еще раз за задачу и заметил, что мне предложили решить другую задачу вместо той, а конкретно эту. http://arhivach.org/thread/88638/#489368
Я ее открыл и мой мозг взорвался с новой силой. Дело в том, что в неправильных номерах я увидел только ссылку на то что либо цифр больше, либо буква присутствует, но вот на симвлы ничего. То есть такие номера как "8(123-812-12-12" или "8123)812-12-12" он засчитает правильными, а они, собственно, неправильные. Так почему там дается заведомо неправильная регулярка ^(8)[\s(-]{0,3}[0-9]{3}[\s)-]{0,3}[0-9]{3}[\s-]{0,3}[0-9]{2}[\s-]{0,3}([0-9]{2})$ и к чему вообще задача, если там будут пропускаться неправильные номера, а условия в задаче чтобы исправить эту регулярку нету.
> То есть такие номера как "8(123-812-12-12" или "8123)812-12-12" он засчитает правильными,
Ну в принципе они и есть правильные, скобку просто забыли поставить, а так то он праивльный. Ты же на телефоне все равно скобки не набираешь.
Сделай для начала хотя бы чтобы номера из примеров в том посте правильно распознавались.
>Так почему там дается заведомо неправильная регулярка
Где там? В задаче не дается готовых регулярок, это ты ее откуда-то в другом месте взял.
>скобку просто забыли поставить
Но разве не нужно собирать базу из номеров которые именно правильно записаны?
Или тут смысл в том, что человек просто рандомно со всякими пробелами со скобками, которые может и не закрывать, записывает свой номер, который начинается на 8 или +7 и имеет еще 10 цифр, а потом из всех этих правильных и неправильных конструкций уже вычленять просто номер вида "89221231231", но это как бы уже за гранью задачи, а в задаче нужно в любой форме получить правильные номера?
>>504375
Третья строчка.
>Вот твоя регулярка: https://regex101.com/r/lM3sA5/1
Сейчас учу в мануале php, но до этого, с того сайта все прочитал.
И у меня вопрос был как бы логического характера что-ли а не технического.
Пиздец, ты совсем даун или второй день на дваче?
Это http://arhivach.org/thread/88638/#489368 ссылка на пост, который является ответом на другой пост.
>Вот твоя регулярка
Это не тебе написано, это ответ другому человеку.
Задача начинается во второй части поста со слов >Задачу про номера телефонов надо проверить на большом числе телефонов, чтобы убедиться что твой код правильный.
Я тебе скинул ссылку на архивач, потому что хуй знает, как найти это задание в задачнике опа.
Какую "базу"?
Смысл регулярных выражений в том, чтобы составить шаблон, общую схему, по которой будут проверяться строки на валидность.
Например, возраст человека может быть от 0 до 99 лет. Ну иногда живут дольше ста лет, но допустим что не живут.
Регулярка будет составляться исходя из соображений: в строке может быть от одного до двух символов, и это могут быть только цифры.
Значит пишем /^\d{1,2}$/
Естественно, никто возраст регуляркой не проверяет, я просто не знаю, какой совсем простой пример можно привести.
>>504380
Замечательно, значит ты уже знаешь, что означают фигурные скобки, \d, ^ и $.
В чём суть каждого языка? Я всё решиться не могу.
C# и Unity.
А если серьезно - 95% игр делают на С++, сам как думаешь? Python в этом плане только для всяких индиигрушек простейших с использованием всяких Kivy, короче, фор фан онли. Ну и для визуальных новелок на PyRen :з
мимикрок
>Алсо денвер для опытных программистов и к тому же это старье, начинающим лучше ставить Апач или PHP руками. Есть туториалы:
Денвер очень прост в установке и уже идет вместе с апачем, там ведь просто ран или стоп нажать
Я, просто, читал что кол-во С++ программистов драматически уменьшается, да и сами программисты не любят этот язык.
Давай обходиться без резких выражений.
>>504379
Нет, в задаче требуется просто проверить с помощью регулярки, правильный дан номер или нет. Список номеров, правильных и непраивльных, дан для того чтобы ты мог проверить свою регулярку.
Регулярку ты должен написать сам. Если ты где-то нашел готовую, она может оказаться неправильной.
> Или тут смысл в том, что человек просто рандомно со всякими пробелами со скобками, которые может и не закрывать, записывает свой номер, который начинается на 8 или +7 и имеет еще 10 цифр, а потом из всех этих правильных и неправильных конструкций уже вычленять просто номер вида "89221231231", но это как бы уже за гранью задачи, а в задаче нужно в любой форме получить правильные номера?
для начала надо просто проверить правильный ли номер. А уже потом надо будет удалить из него лишний мусор и привести номера к общему формату.
Проверять расстановку скобок не надо. Главное, чтобы в начале были +7 или 8, за ними ровно 10 цифр, между которыми могут быть скобки/дефисы/пробелы.
По производительгости Си++ конечно намного быстрее, потому все топовые игры на Си++. Но на нем медленно писать и нужна большая команда разработчиков. Все зависит от того, какая игра тебе нужна и под какую платформу и сколько ты готов потратить времени.
Я бы советовал также поискать готовый движок а не писать с нуля.
Ну, я бы хотел попробовать сначала какие-нибудь думы написать, змейки етц. Т.е. простенькие игры с минимумом графики.
И такие 8(922-123-12-12 допускаются?
Последний вопрос по этой теме задаю, больше не буду спрашивать. Пойду до дыр зачитывать мануал.
Тогда Питона хватит, там вроде PyGame есть для простых игр. Также, C# и Unity неплохая платформа, на ней можо и 2д и 3Д игры под ПК и андроид делать (хотя я не знаю как там с лицениями). Ну и еще яваскрипт, змейку можно вообще в браузере сделать.
Но я бы хотел, потом, перейти на что-нибудь сложное. У меня в голове есть игровая механика для стратегии со складами, жителями, етц...
Я слышал что Банишд разработал 1 человек.
Тогда C# или Си++. Си++ быстрее но сложнее и куча времени уйдет на утечки памяти, нулевые указатели и прочие прелести. Плюс, там заковыристый ООП.
Ну теперь все встало на свои места. Это я уже понимаю как сделать.
А то я думал, что нужно отбрасывать все, которые не подходят под общепринятые форматы, такие как 8 (922) 555 44 22 и т.д.
Вообще, С++ тяжелый и мутный язык?
Пхп, например, довольно простой, как по мне, но я его поверхностно знаю.
http://archive-ipq-co.narod.ru/l1/regexp.html
> Дан текст, который по идее должен быть номером телефона в виде 8-(911)-506 56 56 (т.е. человек может ввести не только цифры, но и скобки, минусы, может что-то еще). Но в реальности, пользователь может вместо номера написать что угодно. Напиши скрипт для проверки правильности введенного номера («8(911)-506 56 56» — правильный номер, «8-911-50-656-56» — правильный, «89115065656» — праивльный, «02» — неправильный, «89115065656 позвать Люду» — неправильный).
Дополнение:
Задачу про номера телефонов надо проверить на большом числе телефонов, чтобы убедиться что твой код правильный. Но руками подставлять номера — долго и скучно. Пусть работает робот, а не человек!
Для этого давай добавим в программу тесты, чтобы сразу было видно, верно все работает или нет. Сделай 2 списка номеров (правильные и нет), добавь их в программу и напиши цикл, который их по очереди прогоняет через регулярку и проверяет что они определяются как надо (если нет — надо вывести какой именно номер не распознается правильно).
Вот список номеров:
Правильные: array('84951234567', '+74951234567', '8-495-1-234-567', ' 8 (8122) 56-56-56', '8-911-1234567', '8 (911) 12 345 67', '8-911 12 345 67', '8 (911) - 123 - 45 - 67', '+ 7 999 123 4567', '8 ( 999 ) 1234567', '8 999 123 4567');
Неправильные: array('02', '84951234567 позвать люсю', '849512345', '849512345678',
'8 (409) 123-123-123', '7900123467', '5005005001', '8888-8888-88',
'84951a234567', '8495123456a',
'+1 234 5678901', // неверный код страны
'+8 234 5678901', // либо 8 либо +7
'7 234 5678901' // нет +
);
Индексация массива начинается с нуля, поэтому номер последнего элемента не равен его длине, а (длина - 1).
Я недавно решал эту задачу, у меня гораздо короче получилось.
Могу показать, если тут принято готовые решения показывать)
если у меня из базы возвращается строка типа '123', то нужно ли ее насильно преобразовать в интеджер, или положиться на php при сравнении '123' > 100?
Кстати, в базе integer, а фетчится PDO::fetch() в виде строки. Может в pdo есть опция, чтобы он корректно возвращал тип?
Он работает и с ним и без него, но есть нужно повторение рандоме почему бы и не запихнуть.
А то есть такие вот студии:
http://www.extyl-pro.ru/vacancy/
Это самое дно. Только если совсем нет вариантов и нужно хоть что-то есть и записать в трудовую.
1. Я решил использовать пространства имен и автозагрузку в соответствии с PSR-4, а потому воспользоваться composer.
2. В мануале написано про hydration, т.е. заполнение свойств объекта из базы, но ведь свойства уже заполнены при отправке формы. Зачем мне снова их заполнять?
3. Нормально ли то, что в форме POST-метода в качестве обрабатывающего скрипта (action="FormHandler") указывается файл класса, находящегося в папке app?
В чем смысле повторять генерацию слов? Ты при этом никак не используешь старые слова и просто затираешь их. Это явно ошибка.
Вот если бы ты генерировал несколько четверостиший, цикл имел бы смысл. Но ты генерируешь одно и цикл там ничего не делает.
У меня ощущение что ты не очень понял как выполняется эта программа.
Можно преобразоыввать, можно понадеяться на php. Если есть сомнения, то лучше преобразовывать явно.
> Может в pdo есть опция, чтобы он корректно возвращал тип?
Нет. Там вроде бы можно привязать переменную через bindParam, и можно указать тип, но я не видел чтобы так делали.
>>504463
> В мануале написано про hydration, т.е. заполнение свойств объекта из базы, но ведь свойства уже заполнены при отправке формы.
hydration это когда ты заполняешь пустой объект данными из базы. Например когда ты хочешь вывести информацию о студенте.
> Нормально ли то, что в форме POST-метода в качестве обрабатывающего скрипта (action="FormHandler") указывается файл класса, находящегося в папке app?
Нет. Файл с классом не может обрабатывать данные от формы. Также в файле с классом не должно быть постороннего кода.
Скрипт-обработчик должен быть в корне проекта. Иначе бардак получается.
принцессу таки превратил в шлюху?
https://ideone.com/GM7Uyd
Усложненная версия в процессе, но пока не знаю как ее сделать.
\t\t
\t\t$retval = mysqli_query($connect, "CREATE TABLE board( ".
"id INT NOT NULL AUTO_INCREMENT, ".
"message TEXT(100) NOT NULL, ".
"name VARCHAR(40) NOT NULL, ".
"date_time TIMESTAMP, ".
"ip VARCHAR(40) NOT NULL," .
"PRIMARY KEY ( id ));");
\t
\t\t
\t
\t
\t\tif(isset($_POST["submit"])) {
\t\t\t$message = preg_replace("/[^a-z0-9]/i", "", $_POST["message"]);
\t\t\t$date_time=date("Y-m-d h:i:sa");
\t\t\t$ip=$_SERVER['REMOTE_ADDR'];
\t\t\t$file = $_FILES['image']['tmp_name'];
\t\t\tif (isset($file))
\t\t\t\t$target_dir = "uploads/";
\t\t\t\t$target_file = $target_dir . basename($_FILES["image"]["name"]);
\t\t\t\t$uploadOk = 1;
\t\t\t\t$name=$_FILES['image']['name'];
\t\t\t\t$imageFileType = pathinfo($target_file,PATHINFO_EXTENSION);
\tif (move_uploaded_file($_FILES["image"]["tmp_name"], $target_file))
\t
\t$query=mysqli_query($connect,"INSERT INTO board VALUES('', '$message', '$name', '$date_time', '$ip')") or die(mysqli_error());
\telse {
\t
\t\t\t$query=mysqli_query($connect,"INSERT INTO board VALUES('', '$message', '', '$date_time', '$ip')") or die(mysqli_error());\t
\t\t\t
\t\t}\t\t
}
Указывать ютф-8 при создании таблицы тоже пробовал.
\t\t
\t\t$retval = mysqli_query($connect, "CREATE TABLE board( ".
"id INT NOT NULL AUTO_INCREMENT, ".
"message TEXT(100) NOT NULL, ".
"name VARCHAR(40) NOT NULL, ".
"date_time TIMESTAMP, ".
"ip VARCHAR(40) NOT NULL," .
"PRIMARY KEY ( id ));");
\t
\t\t
\t
\t
\t\tif(isset($_POST["submit"])) {
\t\t\t$message = preg_replace("/[^a-z0-9]/i", "", $_POST["message"]);
\t\t\t$date_time=date("Y-m-d h:i:sa");
\t\t\t$ip=$_SERVER['REMOTE_ADDR'];
\t\t\t$file = $_FILES['image']['tmp_name'];
\t\t\tif (isset($file))
\t\t\t\t$target_dir = "uploads/";
\t\t\t\t$target_file = $target_dir . basename($_FILES["image"]["name"]);
\t\t\t\t$uploadOk = 1;
\t\t\t\t$name=$_FILES['image']['name'];
\t\t\t\t$imageFileType = pathinfo($target_file,PATHINFO_EXTENSION);
\tif (move_uploaded_file($_FILES["image"]["tmp_name"], $target_file))
\t
\t$query=mysqli_query($connect,"INSERT INTO board VALUES('', '$message', '$name', '$date_time', '$ip')") or die(mysqli_error());
\telse {
\t
\t\t\t$query=mysqli_query($connect,"INSERT INTO board VALUES('', '$message', '', '$date_time', '$ip')") or die(mysqli_error());\t
\t\t\t
\t\t}\t\t
}
Указывать ютф-8 при создании таблицы тоже пробовал.
>Может в имени файла русские буквы или пробелы есть?
Кстати, что делать с таким названием файлов? Удалять пробелы через trim? Конвертировать ру.алфавит в англ?
На пике код контроллера. $mapper и $app - элементы модели.
Это нормально, что по сути контроллер решает, обновлять ли БД или нет? Пусть даже и на основе данных, предоставленных моделью.
Или лучше вызывать валидатор из маппера?
Канеш пиздец, контроллер не должен ничего решать, он должен выполнять действие и возвращать какой-то результат. Представь - если у тебя будет дополнительный API к этим моделям, ты и там будешь ещё раз валидировать? Об этом как раз модель должна заботиться, чтоб никто и не откуда не смог использовать её "неправильно".
Нормально, хотя мне не нравится что ты много раз создешь класс со странным названием App (которое ничего не значит и которое стоит поменять). Я думаю, надо создаваь его 1 раз.
>>504583
Ты что-то путаешь.
> Об этом как раз модель должна заботиться, чтоб никто и не откуда не смог использовать её "неправильно".
Это можно, но это усложнит метод (надо как-то возвращать ошибки). Ничего плохого если мы валидацию сделаем внучную.
Алсо смотри алгоритм работы с формами отсюда: https://github.com/codedokode/pasta/blob/master/forms.md
Повторю вопрос: mysqli_set_charset вызываешь? В твоем коде я не вижу где идет соединение с базой, ты это почему то не запостил.
> делал уже по мануалам
По тем, что я скинул или по каким-то другим? Что именно ты делал?
Из тебя подробности приходится клещами вытягивать, старайся больше подробностей сразу писать.
Повторяю для особенных: только что вызвал и до этого вызывал - не помогает.
\t$connect = mysqli_connect("localhost", "u806317792_ty", "whight") or die(mysqli_error());
\t\tmysqli_set_charset($connect, "utf8");
\t
\t
\t\tmysqli_select_db($connect, "u806317792_ty");
\t
\t\t
\t\t$retval = mysqli_query($connect, "CREATE TABLE board( ".
"id INT NOT NULL AUTO_INCREMENT, ".
"message TEXT(100) NOT NULL, ".
"name VARCHAR(40) NOT NULL, ".
"date_time TIMESTAMP, ".
"ip VARCHAR(40) NOT NULL," .
"PRIMARY KEY ( id ));");
\t
\t\t
\t
\t
\t\tif(isset($_POST["submit"])) {
\t\t\t$message = preg_replace("/[^a-z0-9]/i", "", $_POST["message"]);
\t\t\t$date_time=date("Y-m-d h:i:sa");
\t\t\t$ip=$_SERVER['REMOTE_ADDR'];
\t\t\t$file = $_FILES['image']['tmp_name'];
\t\t\tif (isset($file))
\t\t\t\t$target_dir = "uploads/";
\t\t\t\t$target_file = $target_dir . basename($_FILES["image"]["name"]);
\t\t\t\t$uploadOk = 1;
\t\t\t\t$name=$_FILES['image']['name'];
\t\t\t\t$imageFileType = pathinfo($target_file,PATHINFO_EXTENSION);
\tif (move_uploaded_file($_FILES["image"]["tmp_name"], $target_file))
\t
\t$query=mysqli_query($connect,"INSERT INTO board VALUES('', '$message', '$name', '$date_time', '$ip')") or die(mysqli_error());
\telse {
\t
\t\t\t$query=mysqli_query($connect,"INSERT INTO board VALUES('', '$message', '', '$date_time', '$ip')") or die(mysqli_error());\t
\t\t\t
\t\t}\t\t
Повторяю для особенных: только что вызвал и до этого вызывал - не помогает.
\t$connect = mysqli_connect("localhost", "u806317792_ty", "whight") or die(mysqli_error());
\t\tmysqli_set_charset($connect, "utf8");
\t
\t
\t\tmysqli_select_db($connect, "u806317792_ty");
\t
\t\t
\t\t$retval = mysqli_query($connect, "CREATE TABLE board( ".
"id INT NOT NULL AUTO_INCREMENT, ".
"message TEXT(100) NOT NULL, ".
"name VARCHAR(40) NOT NULL, ".
"date_time TIMESTAMP, ".
"ip VARCHAR(40) NOT NULL," .
"PRIMARY KEY ( id ));");
\t
\t\t
\t
\t
\t\tif(isset($_POST["submit"])) {
\t\t\t$message = preg_replace("/[^a-z0-9]/i", "", $_POST["message"]);
\t\t\t$date_time=date("Y-m-d h:i:sa");
\t\t\t$ip=$_SERVER['REMOTE_ADDR'];
\t\t\t$file = $_FILES['image']['tmp_name'];
\t\t\tif (isset($file))
\t\t\t\t$target_dir = "uploads/";
\t\t\t\t$target_file = $target_dir . basename($_FILES["image"]["name"]);
\t\t\t\t$uploadOk = 1;
\t\t\t\t$name=$_FILES['image']['name'];
\t\t\t\t$imageFileType = pathinfo($target_file,PATHINFO_EXTENSION);
\tif (move_uploaded_file($_FILES["image"]["tmp_name"], $target_file))
\t
\t$query=mysqli_query($connect,"INSERT INTO board VALUES('', '$message', '$name', '$date_time', '$ip')") or die(mysqli_error());
\telse {
\t
\t\t\t$query=mysqli_query($connect,"INSERT INTO board VALUES('', '$message', '', '$date_time', '$ip')") or die(mysqli_error());\t
\t\t\t
\t\t}\t\t
ой сука, с паролем отправилось ><
правильно или нет.
Я конечно сделал но сути не понял и почему приходится в цикл вставлять только if а с else не работает.
Не правильно ты сделал. Посмотри на свой цикл, у тебя на каждом шаге сравнивается первый и последний символ и , если они равны, то сразу выводится палиндром, но ведь никто не гарантирует, что остальные символы должны тоже быть равны. Например, строка "АволодяА"
не является палиндромом, а у тебя выведет ответ, что это палиндром. Подумай, как тебе обрабатывать абсолютно все символы строки и только потом выдавать конкретный ответ.
Да, весьма тяжелый и мутный. Очень много вещей надо самому указывать и учитывать, и всё равно постоянно мелькают новости про утечки памяти и другие радости.
Лучше всего тебе будет С#, язык мощный и гибкий, писать на нём код легко, работает с юнити. Да и работы на нем как на джаве - вакансий очень много.
я правильно сделал?
https://github.com/ForbesLindesay/regexplained.co.uk
Попробовал и так. Я так понимаю, ошибка именно в этом файле. https://github.com/ForbesLindesay/regexplained.co.uk/blob/master/server.js
Класс App я создал для различных вспомогательных методов. На скриншоте это валидация и генерирование кода для куки.
Как обычно называют классы подобного назначения? Application - первое, что мне показалось подходящим.
>Ничего плохого если мы валидацию сделаем внучную.
Можешь объяснить, почему? Пока мне более понятен этот вариант: >>504583.
В контроллере вызывается $mapper->save(...), из маппера вызываем валидатор, получаем результат проверки, который записывается в переменную в контроллере.
Но анон же остается должен, а на долг все также набегают проценты+деньги за обслуживание.
http://ideone.com/aAjp1g
Это задание минимум, а пока я думаю как его форкануть на максимум, поглядите на него одним глазом и может дайте какие то рекомендации\советы как можно было бы сделать легче\проще.
Все правильно понимаешь, ручные валидации нинужны. Только save не должен возвращать ошибки, он должен вернуть true/false - сохранилось или нет, а ошибки нужно собрать в instance-переменную(errors, например) этого объекта модели и использовать их в контроллере при неудачном сейве.
можно ли использовать каким-нибудь образом getimagesize() до загрузки файла (в метод проверки изображения перед загрузкой) или вставить проверку на расширение уже в метод к загрузке и если расширение неподходящее - удалить картинку и вернуть ошибку?
А то я ещё наткнулся на статью http://habrahabr.ru/post/224351/
Когда баланс кредита < 5000, ты должен месячный платеж приравнять к балансу и тогда ты погасишь кредит.
мимо 2 дня уроков, философ-кун.
>Но мало просто загрузить код на сервер — нужно заставить его (сервер) выполнить этот код.
Блджад, когда же хабрапидорахи успокоятся наконец.
Какие-то юродивые, чесслово.
Или, если хочется чтоб вообще было всё по канонам: делай form object, который будет валидировать именно эту форму и обновлять модель. Но тогда важно помнить, что нельзя её изменять из пользовательских данных напрямую - теперь только посредством form object'а.
Во-первых, mysqli_set_charset может выдать ошибку и надо проверять ее результат через if или or die(), читай мануал: http://php.net/manual/ru/mysqli.set-charset.php
Во-вторых, при создании таблицы я не вижу в конце CREATE TABLE ( ...) DEFAULT CHARSET=utf8 — это задает кодировку для таблицы и колонок в ней. Я думаю, надо удалить таблицу и пересоздать с указанием кодировки.
Далее, у тебя какой-то сложный и адский код и искать причину ошибки в нем можно очень долго. Сделай более простой скрипт, который просто выполняет вписанный в нем запрос, без всяких переменных и прочей ерунды:
// соединение с базой
$r = mysqli_query("INSERT INTO ... VALUES ('Привет мир')");
if (!$r) {
...
}
Не забудь сохранить файл со скриптом в кодировке utf-8 без BOM. Если ты все сделаешь как я написал, то все должно сохраниться правильно.
Ну и не знаю, интересно ли мое мнение по поводу кода, но он очень плохой, видимо ты учился по какому-то древнему учебнику. Мне кажется его надо переписывать. Вместо die надо выбрасывать исключения, переменные нельзя вставлять прямо в запрос, надо использовать плейсхолдеры и подготовленные запросы, в общем, я советую тебе посмотреть для начала код из мануала и делать как там:
http://php.net/manual/ru/mysqli.quickstart.prepared-statements.php
Через шесть месяцев планирую устроиться пхп-макакой.
Какие подводные камни?
На что заменить символ.
>>504678
Это из-за того что ты не ичтал инструкцию по установке (ок, ее там нет, жаль). Причина ошибки написана белым по черному: код пытается подключить модуль express и не находит. Я подозореваю, ты не установил требуемые для него пакеты менеджером npm.
Там есть файл packgage.json, в нем перечислены зависимости. Ты должен выполнить какую-то команду (npm install может? почитай мануал по npm) чтобы npm их установил.
>>504675
Это не PHP код, с чего бы он стал работать под апачем и денвером?
Имей в виду также, что там используются JS выражения, а не PCRE (которые используются в PHP), они на 80% похожи, но в JS гораздо меньше навороченных фич, которые ест в PCRE.
>>504679
StudentValidator
> Application - первое, что мне показалось подходящим.
Получается единстенное что делает твое приложение это проверка правильности данных и генерация кук? Я уверен, оно делает больше.
> В контроллере вызывается $mapper->save(...), из маппера вызываем валидатор,
В прицнипе можно вкрутить в маппер вызов валидатора, но тогда получается нехорошая взаимная зависимотсть, мапперу нужен валидатор, а валидатору маппер (чтобы проверять уникальность email).
Если ты хочешь автоматически валидировать данные при сохранении, тебе нужен более высокоуровневый класс, например сервис, который будет вызывать валидатор и маппер. Более того, валидацию можно встроить в него и тогда ты будешь вызывать $studentService->save() а он делать валидацию и дергать маппер для вставки либо обновления данных.
На что заменить символ.
>>504678
Это из-за того что ты не ичтал инструкцию по установке (ок, ее там нет, жаль). Причина ошибки написана белым по черному: код пытается подключить модуль express и не находит. Я подозореваю, ты не установил требуемые для него пакеты менеджером npm.
Там есть файл packgage.json, в нем перечислены зависимости. Ты должен выполнить какую-то команду (npm install может? почитай мануал по npm) чтобы npm их установил.
>>504675
Это не PHP код, с чего бы он стал работать под апачем и денвером?
Имей в виду также, что там используются JS выражения, а не PCRE (которые используются в PHP), они на 80% похожи, но в JS гораздо меньше навороченных фич, которые ест в PCRE.
>>504679
StudentValidator
> Application - первое, что мне показалось подходящим.
Получается единстенное что делает твое приложение это проверка правильности данных и генерация кук? Я уверен, оно делает больше.
> В контроллере вызывается $mapper->save(...), из маппера вызываем валидатор,
В прицнипе можно вкрутить в маппер вызов валидатора, но тогда получается нехорошая взаимная зависимотсть, мапперу нужен валидатор, а валидатору маппер (чтобы проверять уникальность email).
Если ты хочешь автоматически валидировать данные при сохранении, тебе нужен более высокоуровневый класс, например сервис, который будет вызывать валидатор и маппер. Более того, валидацию можно встроить в него и тогда ты будешь вызывать $studentService->save() а он делать валидацию и дергать маппер для вставки либо обновления данных.
Нет, я не согласен. Какой смысл сохранять куда-то ошибки если можно вернуть их сразу? Какая в этом выгода? Это по моему ненужное усложнение.
Так гораздо логичнее:
$errors = $studentService->trySave($student);
>>504729
Где ты это взял? По моему ты ошибаешься.
Так называемый form object есть в фреймворках (Yii, Symfony) для того, чтобы избежать написания однотипного кода для работы с формами (проверка данных, вывод формы в шаблоне). У нас одна форма и проблемы написания однотипного кода нету (хотя я не против использования класса для форм, но это реально усложнит приложение, так как нам нужен класс для формы, классы дял валидации полей и тд, это большой объем работы)
> Но тогда важно помнить, что нельзя её изменять из пользовательских данных напрямую - теперь только посредством form object'а.
Это неверно. Почему ты решил что модель можно обновлять только через форму? В Симфони мы можем просто сделать
$user->setName('asdasda');
$em->flush();
Аналогично в Юи:
$user->name = 'asdasdad';
$user->save();
Для отладки нужно 2 вещи:
1) установленное и настроенное (настройка сводится к добавлению пары опций в php.ini) расширение xdebug
Проверить его наличие можно в phpinfo()
2) программа-клиент для отладки, в которой ты смотришь код, ставишь точки останова, выполняешь код пошагово, смотришь значения переменных.
Поддержка отладки есть в IDE, например в PhpStorm (платный), вроде есть в Netbeans и Eclipse. Есть сторонние программы-отладчики, если погуглить.
Список есть тут: http://xdebug.org/docs/remote
В IDE тоже надо какие-то опции включить в настройках.
Механизм там такой: когда ты начинаешь отладку, твоя IDE открывает страницу в браузере с дописанным параметром вроде:
/index.php?XDEBUG_SESSION_START=name
xdebug видит этот параметр, останавливается и пытается подсоединиться на указанный в конфиге адрес и порт (который слушает IDE если все правильно настроено). После того как соединение установлено, IDE и xdebug могут общаться по специальному протоколу, и IDE может управлять выполнением скрипта, просматривать значения переменных, итд.
Для CLI скриптов там можно добавить переменную окружения по моему или аргумент, не помню уже, чтобы включить режим отладки.
Все это описано в мануале: http://xdebug.org/docs/remote который надо прочесть и понять. Если ты вместо мануала будешь читать статьи вида «нажмите кнопку» то будешь потом долго пытаться понять почему у тебя что-то не работает.
Если ты хочешь отлаживать код на удаленном сервере (глупая идея), придется пробрасывать порты через SSH так как с сервера вряд ли можно подключиться к твоему компу, если у тебя нет белого IP и ты за NAT.
Проверить, слушает ли IDE порт, можно командой netstat -abn, она показывает все открытые на компьютере порты и соединения.
Я советую науиться пользоваться отладчиком, так как это может иногда помочь понять почему скрипт делает те или иные вещи. хотя иногда конечно оладка через var_dump удобнее.
Также xdebug умеет профилировать скрипт, то есть логгировать время выполнения каждой функциии, это полезно для поиска проблем с производительностью. Тоже неплхо бы уметь. Для этого нужен только xdebug и программа просмотра логов вроде WebCacheGrind, IDE не нужна.
Для отладки нужно 2 вещи:
1) установленное и настроенное (настройка сводится к добавлению пары опций в php.ini) расширение xdebug
Проверить его наличие можно в phpinfo()
2) программа-клиент для отладки, в которой ты смотришь код, ставишь точки останова, выполняешь код пошагово, смотришь значения переменных.
Поддержка отладки есть в IDE, например в PhpStorm (платный), вроде есть в Netbeans и Eclipse. Есть сторонние программы-отладчики, если погуглить.
Список есть тут: http://xdebug.org/docs/remote
В IDE тоже надо какие-то опции включить в настройках.
Механизм там такой: когда ты начинаешь отладку, твоя IDE открывает страницу в браузере с дописанным параметром вроде:
/index.php?XDEBUG_SESSION_START=name
xdebug видит этот параметр, останавливается и пытается подсоединиться на указанный в конфиге адрес и порт (который слушает IDE если все правильно настроено). После того как соединение установлено, IDE и xdebug могут общаться по специальному протоколу, и IDE может управлять выполнением скрипта, просматривать значения переменных, итд.
Для CLI скриптов там можно добавить переменную окружения по моему или аргумент, не помню уже, чтобы включить режим отладки.
Все это описано в мануале: http://xdebug.org/docs/remote который надо прочесть и понять. Если ты вместо мануала будешь читать статьи вида «нажмите кнопку» то будешь потом долго пытаться понять почему у тебя что-то не работает.
Если ты хочешь отлаживать код на удаленном сервере (глупая идея), придется пробрасывать порты через SSH так как с сервера вряд ли можно подключиться к твоему компу, если у тебя нет белого IP и ты за NAT.
Проверить, слушает ли IDE порт, можно командой netstat -abn, она показывает все открытые на компьютере порты и соединения.
Я советую науиться пользоваться отладчиком, так как это может иногда помочь понять почему скрипт делает те или иные вещи. хотя иногда конечно оладка через var_dump удобнее.
Также xdebug умеет профилировать скрипт, то есть логгировать время выполнения каждой функциии, это полезно для поиска проблем с производительностью. Тоже неплхо бы уметь. Для этого нужен только xdebug и программа просмотра логов вроде WebCacheGrind, IDE не нужна.
Спасибо большое.
если мне нужно отформатировать некоторую информацию, возвращаемую из базы (например я хочу обрезать длинное имя, если оно больше 50 символов, или перевести размер файла из байт в кб/мб/гб), то к какому объекту будут относиться эти методы форматирования? К мапперу (я использую датамаппер) или к объекту описывающему таблицу бд (в моем случае File)?
И если бы я выбрал ActiveRecord, то насколько я понял этот паттерн тупо объединяет DataMapper и объект описания таблицы (не знаю как он называется)?
В ActiveRecord ты прямо в классе пишешь метод валидации, ведь для каждого типа данных у тебя, скорее всего, будет собственная валидация, так почему бы её не разместить внутри класса. Это удобно, если у тебя нет большой работы с базой: взял пост, обрезал, вставил. Если же суть твоего приложение - именно работа с большими объёмами информации, то DataMapper может предоставить более удобный функционал. Как правило, в 95% хватает ActiveRecord.
Это не валидация. Валидация - проверка данных, полученных от пользователя, на соответствие некоторым правилам.
Здесь речь идет о представлении данных в том или ином виде.
Значит, эти методы можно разместить прямо в маппере или AR?
Кстати, еще мне нужен метод для формирования ссылок. Написать что ли отдельный класс типа HtmlHelper, как в yii.
Форматирование не противоречит определению валидации.
>Написать что ли отдельный класс типа HtmlHelper, как в yii.
Лучше сделай REST-сервис, и по API отправляй пакеты данных. Хотя лучше через сокеты, конечно же. Для этого неплохо бы поднять собственный сервак.
Ясно с тобой все.
> например я хочу обрезать длинное имя, если оно больше 50 символов, или перевести размер файла из байт в кб/мб/гб
Это принято делать в шаблоне при выводе, можно сделать функции для этого. В самой модели надо хранить исходные данные.
Маппер занимается только преобразованиями из формата данных БД в PHP. Например он может преобразовывать даты, полученные из базы, в число-timstamp или объект DateTime.
>>504815
ActiveRecord способствует тому, что в одном классе собрано слишком много. В том же руби он рельс из-за этого полчаются модели на несколько тысяч строк.
>>504817
Форматировать данные для вывода принято в шаблоне (то есть во View)
>>504822
Противоречит.
Если ты используешь шаблонизатор типа twig то там можно добавлять свои функции. Если не используешь, то можешь сделать просто функцию или класс со статиескими методами и использовать так:
<?= html(trimLength($user->name, 50)) ?>
>В том же руби он рельс из-за этого полчаются модели на несколько тысяч строк.
Тогда, наверное, имеет смысл сделать отдельные классы для моделей, которые будут обрабатывать данные. Не люблю длинные файлы с кодом, мне кажется нормой, когда до любого места можно быстро доскролить.
>>504828
Тогда я напишу класс типа ViewHelper, где будут стат.методы для формирования ссылок, преобразования данных из базы на вывод.
Опасаюсь только превращения этого класса в мусорку, т.е. когда там накопится слишком много разных методов, потеряется общая между ними связь, которой является класс по определению.
>можешь сделать просто функцию
У меня как-то сложилось впечатление, что при ООП-подходе вообще некомильфо использовать левые функции, все должно быть логически упаковано в классы.
Или один раз не считается?
Так как форматирование данных, по-сути, уникально для каждого типа, то делать отдельный класс для этого - усложнение ради усложнения. Почти любой шаблонизатор имеет функции на 90% случаев. А если ты собрался форматировать ссылки, то использование шаблонизатора просто мастхев.
Я тут глянул сайт Idiorm/Paris и я не очень понимаю, что они сделали.
Вот это вот плохой пример:
$tweets = ORM::for_table('tweet')
->select('tweet.×')
->join('user', array(
'user.id', '=', 'tweet.user_id'
))
->where_equal('user.username', 'j4mie')
Паттерн Query Builder используют когда у нас запрос собирается по частям с учетом условий, а в данном случае гораздо удобнее использовать SQL чем городить кучу скобок, кавычек, стрелочек. на мой взгляд этот код хуже читается, чем SQL. Я видел SQL запросы по 10-20 строк и в таком виде они будут вообще нечитаемы.
Я не очень понимаю, почему автор так делает.
Вот это имеет смысл:
$person = ORM::for_table('person')->find_one(5);
Так как позволяет чуть короче писать.
Далее, мне не нравится вот это:
$person = ORM::for_table('person')->create();
Почему нельзя написать $person = new Person() как это делается в нормальных DataMapper или AR? Почему они переизобретают new?
Далее, как я понимаю ты не можешь с ней мапить данные на свои классы, этот ORM возвращает тебе объект который больше напоминает массив, в том плане, что у него не определен список полей и нельзя добавлять свои методы.
Это важно, так как ты не можешь делать свои классы для моделей. Это неудобно, так как ты не можешь сделать функцию вроде validate(Student $student), ты получаешь на вход объект из этого ORM с неизвестным набором полей. В общем, много теряешь.
В документации я не вижу пояснений, какие данные там экранируются и как. Непонятно куда можно передавать данные от пользователя.
Вообще, это мне напоминает классы Zend_Db из ZF1, там примерно такой же подход исплоьзовался.
У меня такое ощущение что автор делал эту библиотеку для себя и он велосипедист, который изобретает какие-то свои странне подходы, вместо того чтобы посмотреть вокруг. Документация слабая и многое не поясняет.
Если ты хочешь использовать ORM, почему бы не посмотреть на другие библиотеки? Самая крутая это конечно Doctrine 2, но она может быть достаточно большой и сложной для твоего приложения.
Также, есть Propel (ActiveRecord), он тоже умеет мапить таблицы на твои классы.
Вот пост про ORM: http://stackoverflow.com/questions/108699/good-php-orm-library
Мне кажется, этот Paris очень странно смотрится в твоем коде, так как он предполагает что ты используешь его напрямую. А ты вместо этого делаешь мапперы, копируешь свойства, с таким же успехом ты можешь данные из массива который вернул PDO копировать.
То есть если ты хочешь его использовать, лучше напрямую его и использовать.
Также, я посмотрел доки по Propel, он тоже не минималистичный (и наверно он слишком большой для твоего приложения), там есть конфиги и XML схема. У него есть такой подвох: там используется подход, когда ты описываешь свои модели в XML файле, а потом из них генерируешь БД. По моему опыту, это не всегда хорошо так как вручную писать SQL код может быть удобнее и ты можешь использовать любые фичи которые есть в БД.
Я тут глянул сайт Idiorm/Paris и я не очень понимаю, что они сделали.
Вот это вот плохой пример:
$tweets = ORM::for_table('tweet')
->select('tweet.×')
->join('user', array(
'user.id', '=', 'tweet.user_id'
))
->where_equal('user.username', 'j4mie')
Паттерн Query Builder используют когда у нас запрос собирается по частям с учетом условий, а в данном случае гораздо удобнее использовать SQL чем городить кучу скобок, кавычек, стрелочек. на мой взгляд этот код хуже читается, чем SQL. Я видел SQL запросы по 10-20 строк и в таком виде они будут вообще нечитаемы.
Я не очень понимаю, почему автор так делает.
Вот это имеет смысл:
$person = ORM::for_table('person')->find_one(5);
Так как позволяет чуть короче писать.
Далее, мне не нравится вот это:
$person = ORM::for_table('person')->create();
Почему нельзя написать $person = new Person() как это делается в нормальных DataMapper или AR? Почему они переизобретают new?
Далее, как я понимаю ты не можешь с ней мапить данные на свои классы, этот ORM возвращает тебе объект который больше напоминает массив, в том плане, что у него не определен список полей и нельзя добавлять свои методы.
Это важно, так как ты не можешь делать свои классы для моделей. Это неудобно, так как ты не можешь сделать функцию вроде validate(Student $student), ты получаешь на вход объект из этого ORM с неизвестным набором полей. В общем, много теряешь.
В документации я не вижу пояснений, какие данные там экранируются и как. Непонятно куда можно передавать данные от пользователя.
Вообще, это мне напоминает классы Zend_Db из ZF1, там примерно такой же подход исплоьзовался.
У меня такое ощущение что автор делал эту библиотеку для себя и он велосипедист, который изобретает какие-то свои странне подходы, вместо того чтобы посмотреть вокруг. Документация слабая и многое не поясняет.
Если ты хочешь использовать ORM, почему бы не посмотреть на другие библиотеки? Самая крутая это конечно Doctrine 2, но она может быть достаточно большой и сложной для твоего приложения.
Также, есть Propel (ActiveRecord), он тоже умеет мапить таблицы на твои классы.
Вот пост про ORM: http://stackoverflow.com/questions/108699/good-php-orm-library
Мне кажется, этот Paris очень странно смотрится в твоем коде, так как он предполагает что ты используешь его напрямую. А ты вместо этого делаешь мапперы, копируешь свойства, с таким же успехом ты можешь данные из массива который вернул PDO копировать.
То есть если ты хочешь его использовать, лучше напрямую его и использовать.
Также, я посмотрел доки по Propel, он тоже не минималистичный (и наверно он слишком большой для твоего приложения), там есть конфиги и XML схема. У него есть такой подвох: там используется подход, когда ты описываешь свои модели в XML файле, а потом из них генерируешь БД. По моему опыту, это не всегда хорошо так как вручную писать SQL код может быть удобнее и ты можешь использовать любые фичи которые есть в БД.
Вроде всё пофиксил, убрал функцию уменьшения изображения при каждом открытии профиля (добавил создание уменьшенной копии при загрузке на сервер), добавил переименование файла и проверку через getimagesize() и расширения. Вынес сохранение фото в inspect.php так на мой взгляд будет лучше и удобнее, + не придется в reg.php отправлять запрос на создание ещё одного экземпляра объекта студент чтобы оттуда вернуть назад ID и сохранить фото этому же студенту.
Вроде ещё всё пофиксил из остального, хотя может что-то пропустил так как всегда делаю выборочно из твоих рекомендаций. Голова уже ничего сегодня не соображает.
https://github.com/Si0n/register3
Задача в общем решена, вот пара мелких замечаний.
Здесь надо использовать константы. Также, можно у студента сделать статический метод вернутьВозможныеЗначенияПола()
Забыл отладочный код убрать
Кстати после того, как ты добавил COLLATE у меня вообще поиск вылетает с искючением:
> Exception: COLLATION 'utf8_general_ci' is not valid for CHARACTER SET 'binary' in venom\lib\StudentMapper.php on line 193
Я потом разберусь почему так, я думаю, дело в разных версиях mysql, у тебя наверно 5.7.
И что насчет мини-задаки про экранирование? Я помню, у тебя там было не совсем верное решение.
Пробовал вот так
<?php if ($ID == 'self') : ?>
<form action="mess_action.php" method="post">
<input type="hidden" name="redirect" value="<?=htmlProtect(getPagiForMessage($p, $ID)) ?>">
<input type="hidden" name="id_target" value="<?=htmlProtect($ID) ?>">
<input type="hidden" name="id_author" value="<?=htmlProtect($student->getID()) ?>">
<textarea class="form-control" rows="3" name="text" placeholder="Ваше сообщение"></textarea></p>
<button type="submit" name="submit" class="btn btn-info">Отправить сообщение</button>
</form>
<?php endif ?>
но ничего не дает, мне надо чтобы в случае $ID == 'self' форма отображалась, во всех других случаях - нет.
Кроме того, лучше вынести форму в отдельный шаблон и инклюдить только при необходимости. Зачем гонять лишние байтики?
>StudentValidator
Не хочется создавать отдельный класс для единственной функции, которая, к тому же, не особо влияет на логику всей системы. Я бы вынес все такие функции в один служебный класс.
>Получается единстенное что делает твое приложение это проверка правильности данных и генерация кук? Я уверен, оно делает больше.
Ну пока оно делает лишь это. Потом добавятся ещё методы.
Я только начал делать задачу.
>Если ты хочешь автоматически валидировать данные при сохранении, тебе нужен более высокоуровневый класс, например сервис, который будет вызывать валидатор и маппер. Более того, валидацию можно встроить в него и тогда ты будешь вызывать $studentService->save() а он делать валидацию и дергать маппер для вставки либо обновления данных.
Вот это мне нравится. И код маппера тогда получится более "чистым".
А в сервис я запихну и валидацию, и генерацию кук, и другие служебные методы.
У меня шаблонизатор сначала рендерит frame (в котором хедер с футером), во frame инклюдится content, где в свою очередь подключается тот или иной виджет, который иногда еще подгружает вспомогательный шаблончик.
Три-четыре-пять... уровней вложенности не много ли?
Они никуда не гоняются. Выносить имеет смысл только если форма большая или подключается в нескольких местах.
>>504858
Не обязательно, если там идет ?>
>>504861
Сделай тогда класс Util, хотя валидация все же важная штука и для нее отдельный класс вполне допустим.
Если тебя так пугает большое число классов (почему? что плохого?) то засунь валидацию в маппер, но мне кажется отдельный класс лучше.
> Ну пока оно делает лишь это. Потом добавятся ещё методы.
Нет, не надо так делать ибо ты идешь к God Object: https://ru.wikipedia.org/wiki/%D0%91%D0%BE%D0%B6%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82
Надо уметь правильно разносить код по классам, а не сваливать все в кучу.
> А в сервис я запихну и валидацию, и генерацию кук, и другие служебные методы.
Только не все подряд, а то что относится к работе со студентами.
>>504863
По моему лучше просто в начале каждого шаблона инклудить шапку, а в конце футер. Зачем этот frame?
Да, это мне нравится, так и сделал.
>Они никуда не гоняются.
Да, тут я обосрался. Php ведь не отдаст серверу тот кусок html, который внутри той части условной конструкции, которая не тру.
Но вынести в файлик все равно красивее, чем помещать кусок html в условие.
>лучше просто в начале каждого шаблона инклудить шапку, а в конце футер. Зачем этот frame?
Смотри, у меня в этом файле каркас, то есть открывающий и закрывающий html, head, body. Внутри боди уже инклюдится тот или иной контент. В результате каркас повторяется ровно один раз.
У меня сейчас:
<!DOCTYPE html>
<html>
<head>
все стили и js
</head>
<body>
<header>
содержимое шапки
</header>
<?php require $template;?>
<footer>
подвал
</footer>
</body>
</html>
Если же сделать наоборот, то придется в каждом большом шаблоне писать все эти теги вместе со скриптами, что является повтором. Хотя с другой стороны так читабельнее, и действительно я видел так чаще делают:
<!DOCTYPE html>
<html>
<head>
все стили и js
</head>
<body>
<?php include $header; ?>
<div id="content">
содержимое конкретного шаблона
</div>
<?php include $footer; ?>
</body>
</html>
Но второй способ пожалуй читабельнее, хотя и заставляет повторять head и прочую мишуру в каждом шаблоне. Да, придется переделывать так.
>Они никуда не гоняются.
Да, тут я обосрался. Php ведь не отдаст серверу тот кусок html, который внутри той части условной конструкции, которая не тру.
Но вынести в файлик все равно красивее, чем помещать кусок html в условие.
>лучше просто в начале каждого шаблона инклудить шапку, а в конце футер. Зачем этот frame?
Смотри, у меня в этом файле каркас, то есть открывающий и закрывающий html, head, body. Внутри боди уже инклюдится тот или иной контент. В результате каркас повторяется ровно один раз.
У меня сейчас:
<!DOCTYPE html>
<html>
<head>
все стили и js
</head>
<body>
<header>
содержимое шапки
</header>
<?php require $template;?>
<footer>
подвал
</footer>
</body>
</html>
Если же сделать наоборот, то придется в каждом большом шаблоне писать все эти теги вместе со скриптами, что является повтором. Хотя с другой стороны так читабельнее, и действительно я видел так чаще делают:
<!DOCTYPE html>
<html>
<head>
все стили и js
</head>
<body>
<?php include $header; ?>
<div id="content">
содержимое конкретного шаблона
</div>
<?php include $footer; ?>
</body>
</html>
Но второй способ пожалуй читабельнее, хотя и заставляет повторять head и прочую мишуру в каждом шаблоне. Да, придется переделывать так.
>Надо уметь правильно разносить код по классам, а не сваливать все в кучу.
>
>> А в сервис я запихну и валидацию, и генерацию кук, и другие служебные методы.
>Только не все подряд, а то что относится к работе со студентами.
Ну это само собой. Я имел в виду, что туда добавятся всякие мелкие вещи, используемые в одном контексте, которые не вписываются в создание отдельной сущности.
А? Ты предлагаешь разрывать теги? Я об этом не подумал.
header.php
<!DOCTYPE html>
<html>
<head>
все стили и js
</head>
<body>
footer.php
<footer>
подвал
</footer>
</body>
</html>
first_view.php
<?php require "{$path_to_tempeates}/header.php"; ?>
<div id="content">содержимое</div>
<?php require "{$path_to_tempeates}/header.php"; ?>
Так лучше? Мне по-барабану, но хочется уже на каком-то варианте остановиться, а то я уже запутался переписывать.
Зачем вообще нужен шаблонизатор я понял (хоть и не до конца).
Но зачем мне заучивать, что есть какой-то модификатор escape, который экранирует строки, если я могу с таким же успехом написать в шаблоне htmlspecialchars?
Это делается для того, чтобы шаблонизатор не был привязан к конкретному языку и для удобства верстальщиков?
Блять, вот че ты изобретаешь велосипед? Я транслирую напрямую то, что давно уже есть искаропки в рельсах. Это четко работает, не надо выдумывать никаких trySave и т.п. ерунду. И читай внимательно: без form object'а нельзя обновлять из пользовательских данных, из параметров запроса то есть.
Знание php
Желательно опыт работы с фраемворками
JS, CSS, HTML
Обязанности:
1. разрабатывать крупный интересный проект на YII (возможно обучение)
2. разрабатывать корпоративные веб-сайты, дорабатывать сайты
Если такие условия ставит работодатель и при этом дают возможность работать джуниором то на каком примерно уровне надо владеть пехепе, чтобы приняли? Студентота с неочень дипломом и ленивым багажом знаний.
я уже заебался. ничо не помогает. писал уже что все это пробовал.
\t\tmysqli_set_charset($connect, "utf8") or die();
\t\tif(!mysqli_set_charset($connect, "utf8")) {
\t\techo "Not set";
\t\t}
\t\tmysqli_select_db($connect, "u806317792_ty");
\t
\t\t
\t\t$retval = mysqli_query($connect, "CREATE TABLE board( ".
"id INT NOT NULL AUTO_INCREMENT, ".
"message TEXT(100) NOT NULL, ".
"name VARCHAR(40) NOT NULL, ".
"date_time TIMESTAMP, ".
"ip VARCHAR(40) NOT NULL," .
"PRIMARY KEY ( id ) ) ENGINE=MyISAM DEFAULT CHARSET=utf8");
хуйца соснешь.
Слишком неопределенный вопрос (выражаясь цензурно).
Просто посмотреть какой-то курс недостаточно. Нужно выучить наизусть все важные материалы, написать несколько проектов для закрепления. Какие проекты ты уже написал?
В этом треде оп-сенсей предлагает множество примитивных задачек на закрепление теории и два-три крупных задания, например написать простой сайт с регистрацией для абитуриентов вуза, а также задание на файлообменник.
Этого будет достаточно для того чтобы претендовать на вакансию джуниора (младшего разработчика). С меньшим багажом знаний тоже могут взять, но зарплата и задачи будут соответствующими: грязная работа по "доработке сайтов", то есть поправлять покосившуюся верстку и менюшки.
Кроме php веб-разработчик обязан знать джаваскрипт (обязательно) + js-фреймворки типа jquery (что вторично), отлично знать sql и mysql в частности (а желательно и другие субд), уметь писать сложные запросы. Html и css как само собой разумеется. Основные настройки веб-сервера (обычно apache, очень желательно nginx).
Знать систему контроля версий (сейчас используют git, но бывает всякое).
Остальное зависит от конторы.
Выполняй задания из оп-поста, начиная с самых простых, постепенно переходя к более сложным (ничего не пропускать!).
Оп заходит 1-2 раза в день, отвечает на вопросы, проверяет задачи.
Если выучишь всю теорию и сделаешь все задания из оп-поста, через полгода может и устроишься. Все зависит от тебя, от трудолюбия, умственных способностей, города, чего угодно.
Бампану ка я вопрос.
не слушай этих долбоебов. пытайся найти работу на удаленке, если не из ДС, но это очень сложно, я сам уже почти год изучаю веб, пока еще не одного сложного проекта, кроме множества кусков кода и страниц-лендингов, не сделал, чтобы показать и на удаленке всегда отклоняли.
Через 6 месяцев и спросишь, а то выйдет как обычно "сегодня я утром побегал разок, через полгода буду стройным как атлант."
> Это четко работает, не надо выдумывать никаких trySave и т.п. ерунду.
Ты по моему даже не понял что я написал. Если бы ты поменьше злился и побольше думал головой. ты бы вспомнил что в рельсах используется ActiveRecord, а у нас DataMapper.
И рельсы это точно не пример как делать правильно. Это скорее большой набор антипаттернов.
Название trySave по моему подходит лучше так как из него видно что запись может и не сохраниться. В рельсах используется менее понятный трюк с восклицательным знаком.
> И читай внимательно: без form object'а нельзя обновлять из пользовательских данных, из параметров запроса то есть.
Не понимаю что нам мешает написать
$student->name = $_POST['name']
без всяких там объектов.
Я уверен что ты делал что-то не то. Если ты сделашь так, как я написал в посте, то данные вставятся в корректной кодировке. В твоем посте я вижу код создания таблицы, но я не вижу того INSERT который я упомянул в своем посте.
Почему ты такой упертый и просто не можешь признать, что обосрался со своими советами? могу скинуть тебе файлы - сам загрузи их на хостингер.
Проверка проходит верно. Но меня это не устраивает.
Затруднения вызывают скобки. В моем решении пройдут номера типа 8-4)9)5)-1-234-567
http://ideone.com/IdhiB2
Если бы кол-во цифр в скобках было фиксированным, я бы решил например так (если принять код в скобках ровно из трех цифр):
/^\s?(8|\+\s?7)\s?-?\s?\(?(\s?-?\s?\d){3}\s?\)?(\s?-?\s?\d){7}\s?$/
Можно попытаться сделать альтернативу для кода из 4-х цифр:
/^\s?(8|\+\s?7)\s?-?\s?\(?(\s?-?\s?\d){3,4}\s?\)?(\s?-?\s?\d){6,7}\s?$/
Но тогда может быть ошибка в длине телефона: 1 + 3 + 6, или 1 + 4 + 7 цифр.
Нужно сделать, чтобы если в коде в скобках 4 цифры, тогда кол-во повторов третьей части регулярки 6, если 3 то 7.
Я знаю, что можно при помощи круглых скобок запоминать часть строки, но есть ли в регулярках встроенные функции, как в mysql например для подсчета длины строки?
Скинь, я могу их у себя запустить для начала. Скинь тот, что с тем кодом про который я писал выше, без всяких форм, GET, POST и прочей ерунды, только коннект к базе, выбор кодировки и инсерт.
Погоди-погоди. Прежде чем писать код, сформулируй ясно правила по которым ты собрался его проверять. Сколько скобок и как они должны быть расставлены.
> Нужно сделать, чтобы если в коде в скобках 4 цифры, тогда кол-во повторов третьей части регулярки 6, если 3 то 7.
Проще будет расстановку скобок проверять отдельно, не регуляркой, а специально для этого написанным кодом.
>$student->name = $_POST['name']
Ну, не хочешь - не валидируй ничего, ошибки не собирай и не показывай.
>Название trySave по моему подходит лучше так как из него видно что запись может и не сохраниться. В рельсах используется менее понятный трюк с восклицательным знаком.
Запись может не сохраниться и без восклицательного знака, он всего лишь решает бросать ли при этом исключение. Я вижу, что ты хочешь сделать что-то типа микросервисов, но на деле они далеко не всегда нужны, особенно в игрушечных проектах. Для чего иначе нужна модель, если есть она, микросервис вытирающий жопу по управлению этой моделью(на деле ещё и берущий на себя ответственность form object'а) и отдельный валидатор? Просто мапить поля из базы? Почему бы ей самой не заботиться о собственной валидности? Этот менеджер может пригодиться только в том случае, если есть несколько способов изменить одну и ту же модель, и тогда имеет смысл уже задуматься о том, не берет ли слишком много на себя одна модель и не пора ли выделить ещё одну. Или я всё ещё чего-то не понимаю.
Открывающая скобка имеет право быть после первой цифры (восьмерки или семерки), а закрывающая либо после четвертой цифры, либо после пятой.
Код города или моб.оператора может состоять только из 3-4 цифр ведь?
http://ideone.com/nG8sep
Позиция скобок теперь зашита, но как сделать, чтобы если есть открывающая скобка, то обязательно должна быть закрывающая.
А если открывающей нет, то не должно быть закрывающей.
> без всяких форм, GET, POST и прочей ерунды, только коннект к базе, выбор кодировки и инсерт.
и какой в этом смысл йопт? если ты не сможешь проверить методом пост заносится ли у тебя инфа в базу?
Можно конечно описать номер с кодом в скобках из трех цифр, а потом через альтернативу номер с кодом из четырех цифр. Работать будет, но это уж чересчур громоздко, фактически два регулярных выражения в одном.
Ладно, я завтра на свежую голову.
>>504275
continue не нужен, цикл продолжается в любом случае.
В остальном, все верно.
>>504315
Ты имеешь в виду если в цикле несколько операторов if? Код по умолчанию выполняется сверху вниз, так что все операторы if выполнятся по очереди.
>>504389
Начинающему полезнее разобраться с тем как настраивать конфиги и тд. И в денвере как я знаю древние версии программ и странные настройки вроде кодировки 1251.
Апач легко запускать командами net start/stop, и к нему есть программа с кнопками (Apache Monitor) для тех кто любит более медленный вариант управления.
>>504449
У тебя неправильная логика. У нас цель решить задачу чтобы она не просто работала, а еще код был правильным. представь что надо вывести сумму 2 чисел. Можно сделать так:
$x = $a + $b;
echo $x;
А можно так:
for ($i = 1; $i < 100; $i++) {
$x = $a + $b;
$z = mt_rand(1, 10);
$w = $z + $x;
}
echo $x;
Это правильно? Нет, непраивльно, так как тут много лишнего бессмысленного кода. Как минимум это затрудняет понимание.
Потому весь лишний код надо убрать.
>>504275
continue не нужен, цикл продолжается в любом случае.
В остальном, все верно.
>>504315
Ты имеешь в виду если в цикле несколько операторов if? Код по умолчанию выполняется сверху вниз, так что все операторы if выполнятся по очереди.
>>504389
Начинающему полезнее разобраться с тем как настраивать конфиги и тд. И в денвере как я знаю древние версии программ и странные настройки вроде кодировки 1251.
Апач легко запускать командами net start/stop, и к нему есть программа с кнопками (Apache Monitor) для тех кто любит более медленный вариант управления.
>>504449
У тебя неправильная логика. У нас цель решить задачу чтобы она не просто работала, а еще код был правильным. представь что надо вывести сумму 2 чисел. Можно сделать так:
$x = $a + $b;
echo $x;
А можно так:
for ($i = 1; $i < 100; $i++) {
$x = $a + $b;
$z = mt_rand(1, 10);
$w = $z + $x;
}
echo $x;
Это правильно? Нет, непраивльно, так как тут много лишнего бессмысленного кода. Как минимум это затрудняет понимание.
Потому весь лишний код надо убрать.
Вполне нормальное решение.
>>504478
Квейк на Си++, халф лайф и контер страйк на Си++, а другие игры я не знаю. Но эти игры не один человек и не сразу писал.
>>504488
> $paymentTotal = $paymentTotal + $firstPaid;
Дополнительную выплату надо прибавлять к сумме кредита, чтобы на нее набегали проценты, а у тебя не набегают и меньше сумма получается.
> if ($creditSum < 4000){
Это неправильно. Это ты подогнал под конкретный сулчай, а если мы сумму выплат в месяц поменяем, то он перестанет правильно считать. Более того, возможно что в каком-то из трех случаев из-за этого идет ошибка.
тут надо сделать так:
- прибавляем проценты и комиссию к остатку долга
- если остаток маленький, выплачиваем сколько осталось и уходим
- иначе платим 5000
«Платим» здесь значит уменьшаем долг и увеличиваем общую сумму выплаченного.
Ты проверял эту задачу списком номеров? сделай проверку, а то пока непонятно, вроде похоже на правильный ответ, но может где-то будут ошибки.
Для этого давай добавим в программу тесты, чтобы сразу было видно, верно все работает или нет. Сделай 2 списка номеров (правильные и нет), добавь их в программу и напиши цикл, который их по очереди прогоняет через регулярку и проверяет что они определяются как надо (если нет — надо вывести какой именно номер не распознается правильно).
Вот список номеров:
Правильные: array('84951234567', '+74951234567', '8-495-1-234-567', ' 8 (8122) 56-56-56', '8-911-1234567', '8 (911) 12 345 67', '8-911 12 345 67', '8 (911) - 123 - 45 - 67', '+ 7 999 123 4567', '8 ( 999 ) 1234567', '8 999 123 4567');
Неправильные: array('02', '84951234567 позвать люсю', '849512345', '849512345678',
'8 (409) 123-123-123', '7900123467', '5005005001', '8888-8888-88',
'84951a234567', '8495123456a',
'+1 234 5678901', // неверный код страны
'+8 234 5678901', // либо 8 либо +7
'7 234 5678901' // нет +
);
> Усложненная версия в процессе, но пока не знаю как ее сделать.
Просто удаляй из номера все лишнее через preg_replace и заменяй +7 на 8.
>>504533
Либо транслитом менять на латинницу, либо генерировать имя самому. Пробелы лучше заменять на минусы например, хотя они допустимы в имени файла, просто надо правильно их кодировать когда делаешь ссылку так как в ссылке не может быть пробелов.
>>504537
мне кажется, можно сделать и так, и так (можно в констроллере проверять, можно в сервисе).
>>504567
Может быть. Но если что-то не так то там должна быть ошибка. Смотри логи сервера. если ошибка не выводится на экран либо включи отображение ошибок (display_errors в php.ini).
Из текста ошибки будет ясно в чем дело.
Ты проверял эту задачу списком номеров? сделай проверку, а то пока непонятно, вроде похоже на правильный ответ, но может где-то будут ошибки.
Для этого давай добавим в программу тесты, чтобы сразу было видно, верно все работает или нет. Сделай 2 списка номеров (правильные и нет), добавь их в программу и напиши цикл, который их по очереди прогоняет через регулярку и проверяет что они определяются как надо (если нет — надо вывести какой именно номер не распознается правильно).
Вот список номеров:
Правильные: array('84951234567', '+74951234567', '8-495-1-234-567', ' 8 (8122) 56-56-56', '8-911-1234567', '8 (911) 12 345 67', '8-911 12 345 67', '8 (911) - 123 - 45 - 67', '+ 7 999 123 4567', '8 ( 999 ) 1234567', '8 999 123 4567');
Неправильные: array('02', '84951234567 позвать люсю', '849512345', '849512345678',
'8 (409) 123-123-123', '7900123467', '5005005001', '8888-8888-88',
'84951a234567', '8495123456a',
'+1 234 5678901', // неверный код страны
'+8 234 5678901', // либо 8 либо +7
'7 234 5678901' // нет +
);
> Усложненная версия в процессе, но пока не знаю как ее сделать.
Просто удаляй из номера все лишнее через preg_replace и заменяй +7 на 8.
>>504533
Либо транслитом менять на латинницу, либо генерировать имя самому. Пробелы лучше заменять на минусы например, хотя они допустимы в имени файла, просто надо правильно их кодировать когда делаешь ссылку так как в ссылке не может быть пробелов.
>>504537
мне кажется, можно сделать и так, и так (можно в констроллере проверять, можно в сервисе).
>>504567
Может быть. Но если что-то не так то там должна быть ошибка. Смотри логи сервера. если ошибка не выводится на экран либо включи отображение ошибок (display_errors в php.ini).
Из текста ошибки будет ясно в чем дело.
> почему приходится в цикл вставлять только if а с else не работает.
Покажи код который не работает. Скорее всего ты что-то по невнимательности перепутал.
Также, твой код неправильный, вот тут:
> \tif ($symbol == $symbol2);
Точка с запятой завершает оператор if. Он равносилен такому коду:
if ($symbol == $symbol2) {
// ничего не делаем при совпадении
}
Вернись к уроку про условия и игру в кубики и внимательно посмотри как пишется if. У тебя нету фигурных скобок.
У него фигурных скобок после if нету и это гораздо хуже.
>>504645
Пока нет. У тебя не выводится общая сумма сколько всего выплачено по кредиту.
Должно получиться около 61270.
>>504691
Комментарии тут лучше писать над строкой, а не справа, а то строки длинные получаются.
> unset($key);
> unset($word);
Это лишнее, так как не имеет смысла удалять эти переменные на каждом шаге цикла
Также, твоя регулярка не найдет подмену в самой последней букве слова: http://ideone.com/Vn56zL
А в общем неплохо.
Потому что мы убедимся что с базой все в порядке и мой совет про set_charset верный и что ты меешь сохранять код в utf-8, а убедившись можем продолжать дальше, изучая гапример в какой кодировке страница и в какой кодировке шлются данные из формы.
Алсо вписывать переменные в запрос неправильно как у тебя в любом случае, а я не хочу разгребать неправильный код. Искать проблемы лучше на простых примерах.
>>505075
В маленьких городах бывает 5 цифр в коде города: https://ru.wikipedia.org/wiki/%D0%A2%D0%B5%D0%BB%D0%B5%D1%84%D0%BE%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BF%D0%BB%D0%B0%D0%BD_%D0%BD%D1%83%D0%BC%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%B8#.D0.A0.D0.BE.D1.81.D1.81.D0.B8.D1.8F_.D0.B8_.D0.9A.D0.B0.D0.B7.D0.B0.D1.85.D1.81.D1.82.D0.B0.D0.BD
> Позиция скобок теперь зашита, но как сделать, чтобы если есть открывающая скобка, то обязательно должна быть закрывающая.
Проще всего сделать отдельный код который посчитает сколько цифр перед или после данной скобки и сколько каких видов скобок в номере.
Твоя регулярка слишком сложная, ее тяжело читать и например на глаз трудно даже понять правильная она или нет, тяжело вносить в нее изменения. Такого быть не должно. Проверку скобок надо вынести из нее, а саму регулярку сделать максимально простой.
строки в базе у меня сто процентов в ютф8 - уже кидал скрины. страница в ютф-8 - прописал в хедере. и в какой кодировке могут слаться данные? как это выстаивать, чтобы слались в ютф8?
> Ну, не хочешь - не валидируй ничего, ошибки не собирай и не показывай.
Тут другой подход, мы можем записать все что угодно в модель, но перед сохранением валидируем. Этот подход позволяет нам при ошибке выводить эти данные обратно в форме из модели.
Ошибки мы и собираем и показываем.
Городить полноценные классы форм для этой задачи это лишнее усложнение. Мы не собираемся тут заново переписать половину симфони.
> Я вижу, что ты хочешь сделать что-то типа микросервисов, но на деле они далеко не всегда нужны
Это не микросервисы, микросервисы это когда мы делаем несколько приложений общающихся через апи.
> Для чего иначе нужна модель
Оечивдно модель нужна для хранения информации о студенте. Для чего еще по твоему она может быть нужна? Далее, у нас есть форма регистрации студента и логично что эта форма может хранить введенные данные в модели.
> Просто мапить поля из базы?
Мапит поля DataMapper. По моему у тебя непонимание этого паттерна. Почитай про него у Мартина Фаулера или мой урок: https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md
> Почему бы ей самой не заботиться о собственной валидности?
Потому что:
1) для проверки валидности может потребоваться обращение в базу (или к другим сервисам), а модель не может в нее лезть. Модель это хранилище информации о студенте.
2) это не задача модели
3) модель может быть невалидна. Например когда мы ввели неправильные данные, нам нужна невалидная модель чтобы эти введенные данные отобразить в форме повторно.
Перечитай внимательно мой урок про работу с формами, почитай код у анона, попробуй разобраться. по моему ты не понял как там все сделано.
> Этот менеджер может пригодиться только в том случае, если есть несколько способов изменить одну и ту же модель
Что значит несколько способов? Модель это объект и способ изменить ее только один: записать в его поля новые значения. Просто и логично.
> Ну, не хочешь - не валидируй ничего, ошибки не собирай и не показывай.
Тут другой подход, мы можем записать все что угодно в модель, но перед сохранением валидируем. Этот подход позволяет нам при ошибке выводить эти данные обратно в форме из модели.
Ошибки мы и собираем и показываем.
Городить полноценные классы форм для этой задачи это лишнее усложнение. Мы не собираемся тут заново переписать половину симфони.
> Я вижу, что ты хочешь сделать что-то типа микросервисов, но на деле они далеко не всегда нужны
Это не микросервисы, микросервисы это когда мы делаем несколько приложений общающихся через апи.
> Для чего иначе нужна модель
Оечивдно модель нужна для хранения информации о студенте. Для чего еще по твоему она может быть нужна? Далее, у нас есть форма регистрации студента и логично что эта форма может хранить введенные данные в модели.
> Просто мапить поля из базы?
Мапит поля DataMapper. По моему у тебя непонимание этого паттерна. Почитай про него у Мартина Фаулера или мой урок: https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md
> Почему бы ей самой не заботиться о собственной валидности?
Потому что:
1) для проверки валидности может потребоваться обращение в базу (или к другим сервисам), а модель не может в нее лезть. Модель это хранилище информации о студенте.
2) это не задача модели
3) модель может быть невалидна. Например когда мы ввели неправильные данные, нам нужна невалидная модель чтобы эти введенные данные отобразить в форме повторно.
Перечитай внимательно мой урок про работу с формами, почитай код у анона, попробуй разобраться. по моему ты не понял как там все сделано.
> Этот менеджер может пригодиться только в том случае, если есть несколько способов изменить одну и ту же модель
Что значит несколько способов? Модель это объект и способ изменить ее только один: записать в его поля новые значения. Просто и логично.
>Алсо вписывать переменные в запрос
оо, спасибо, убрал reexp все заработало. странно раньше убирал - и не было смысла.
Если страница в utf-8 то и данные из формы приходят в utf-8. Проверять надо инспектором в браузере а не смотря на код.
И ты так и не ответил, что будет если сделать просто инсерт без работы с формой. Видимо ты не пробовал это сделать, раз так то я вряд ли чем-то смогу помочь пока мы не проверим что вставка в базу работает нормально.
На хостинге кеширование как бы между прочим.
Телеграм же типа ананимный и шифрование.
Да нет же, там пишешь прилагательное, и он тебе фото кота ищет по этому слову.
Это наверно лучше в /b постить, там аудитория больше, а тут три с половиной анона, из которых у одного нету смартфона.
Идеально! 10/10! Анон, ты лучший! Отличная работа. Только две жалобы.
1) один раз бот подвис и минут двадцать игнорил мои посты. Потом починился.
2) пожалуйста, приделай что то типа безопасного поиска, чтобы по некоторым запросам гуро не выдавалось.
А так всё классно.
>что то типа безопасного поиска
done
>один раз бот подвис
Ну тут проблема, телеграм не хочет делать колбек на мой хостинг, поэтому приходится дёргать сам телеграф на наличие обновлений, из-за чего скрипт работает через крон, что вызывает кучу проблем сопутствующих. Причиной называют мой самоподписанный SSL-сертификат, хотя он самый настоящий.
str_replace позволяет заменять такие символы, как "<". А их заменять необходимо, ведь через них могут ввести зловредный <script>в форму. и вот эта функция не позволяет мне вводить криллицу. впрочем как и reg_exp
>и вот эта функция не позволяет мне вводить криллицу
Да каким образом то? str_replace работает с кириллицей же.
Ну если ты фрилансер, то обычно ты ставишь сайты не на свой хостинг. Зачем тебе именно VPS?
Просто гугли топовый хостинг в своей стране, из-за конкуренции они все хороши.
Наслышан о внезапном закрытии дата центров в моей стране, этого стоит опасаться вообще? Есть смысл переплачивать за всякие германии\нидерланды?
И что по конфигу скажешь? Чтоб не загибался от, скажем, 30 движков
Обычно у престашопов не больше 500 уников в сутки, можно хоть 50 запустить, даже виртуальный сервер потянет.
>Есть смысл переплачивать за всякие германии\нидерланды?
Если и будешь платить, плати в америке, у них прекрасные и дешёвые облака.
>этого стоит опасаться вообще?
Если занимаешься магазинами - то нет.
Спасибо анон.
>прекрасные и дешёвые облака
Можно пример? И в чем суть этих облаков вообще? Платишь только за потребляемые ресурсы, и все?
https://www.digitalocean.com/pricing/
За 5$ получаешь облачный аналог VPS со всеми преимуществами. Может это не самый дешёвый вариант, но там сервис и аптайм на высоте.
Забыл сказать - хостинг на SSD, тут без комментарием, работают почти все популярные технологии, вроде Node.js.
Внимание, тупой вопрос. Я же смогу на это облако прилепить безмерно доменов, или только 1?
Сколько пожелаешь, блядь!
Оно то да, но все будут на 1 ip, из-за чего ты не сможешь прикрепить SSL сертификат. Но ты можешь купить дополнительные IP под каждый сайт.
С fetchAll прекрасно работает, с fetch почему-то вылетает ошибка
PDOStatement::fetch() expects parameter 2 to be long, string given[\b]
Первый раз слышу про тип "long".
Или ошибка в другом месте?
#0 [internal function]: Slim\Slim::handleErrors(2, 'PDOStatement::f...', '/home/inside/ww...', 55, Array)
#1 /home/inside/www/example.com/protected/app/Model/FileMapper.php(55): PDOStatement->fetch(8, '\Storage\Model\...')
#2 /home/inside/www/example.com/public_html/index.php(111): Storage\Model\FileMapper->findById('1')
#3 [internal function]: {closure}('1')
#4 /home/inside/www/example.com/protected/vendor/slim/slim/Slim/Route.php(468): call_user_func_array(Object(Closure), Array)
#5 /home/inside/www/example.com/protected/vendor/slim/slim/Slim/Slim.php(1357): Slim\Route->dispatch()
#6 /home/inside/www/example.com/protected/vendor/slim/slim/Slim/Middleware/Flash.php(85): Slim\Slim->call()
#7 /home/inside/www/example.com/protected/vendor/slim/slim/Slim/Middleware/MethodOverride.php(92): Slim\Middleware\Flash->call()
#8 /home/inside/www/example.com/protected/vendor/slim/slim/Slim/Middleware/PrettyExceptions.php(67): Slim\Middleware\MethodOverride->call()
#9 /home/inside/www/example.com/protected/vendor/slim/slim/Slim/Slim.php(1302): Slim\Middleware\PrettyExceptions->call()
#10 /home/inside/www/example.com/public_html/index.php(155): Slim\Slim->run()
#11 {main}
Да нет, это мягко говоря не профессионально.
Мне нужна одна запись, а не массив из одного элемента.
И нужно разобраться, почему не работает, а не удовлетвориться быдлокодерским костылем.
Хм, если перед execute прописать setFetchMode, то работает. Странно.
fetchAll запускался и без этой опции.
Ты в fetchAll переметры передавал в скобках? Я так делал: ->setFetchMode('параметры');
->fetch();
Да, для fetchAll можно передать параметры в скобках и вообще не писать setFetchMode.
А для fetch обязательно сначала вызвать setFetchMode. После чего писать параметры для fetch в скобках не обязательно.
Ок, буду всегда использовать setFetchMode, и для fetch, и для fetchAll. Хотя странно, что в документации об этом нюансе ничего не сказано.
Вот только в каментах чувак отписался по этому вопросу 9 (!) лет назад.
http://php.net/manual/ru/pdostatement.fetch.php#59056
Ну ладно, может вечером оп нарисуется и просветит по этому вопросу. Это баг, или еще что.
php.net, как обычно. Это полный справочник по php.
http://php.net/manual/ru/pdostatement.fetch.php
Прочитай мануал по функции fetch: http://php.net/manual/ru/pdostatement.fetch.php там указаны типы параметров
Для fetch по моему надо через setFetchStyle класс задавать.
>>505331
С оплатой за ресурсы ты будешь по факту платить больше, так как платишь за все: за диск, за обращения к диску, за память, за загрзку процессора, за трафик. Даже если машина простаивает, за диск и память надо платить.
>>505166
Написал бы им в техподдержку, уверен они помогут разобраться. ТОлько проверь сначала информацию о сертификате, можно кликом по нему в браузере, можно как-то из командной строки.
Алсо вместо возни с кроном лучше бы сделать демона, который в цикле проверяет что тебе надо. А чтобы перезапускать при падении, можно использовать supervisord или другой супервизор.
>>505333
только пинг до сша гигантский и сайт будет медленно открываться. Лучше иметь хостинг в СПб/в Москве чтобы пинг был минимален (если клиенты в России).
>Написал бы им в техподдержку, уверен они помогут разобраться.
Таки написал, и в свитере, и в раздел на сайте, пока молчат. У них там какие-то волонтёры отвечают, кажется, не особо стоит надеяться на быстрый ответ.
>ТОлько проверь сначала информацию о сертификате
Вот что странно, я проверил их ответ через http://posthere.io/, туда приходит, на мой сайт - не приходит, но сертификаты у нас абсолютно одинаковые, купленные у одной компании по одному тарифу. Жду ответа саппорта.
Какой запрос, такой и ответ.
ну хз, вот так пишу, смотри, и если ввожу потом кириллицу, то строка пустая.
\t$message1 = $_POST["message"];
$message=str_replace("<", "", $message1);
Ты занимешься ерундой. Надо не вырезать странные символы, а экранировать при выводе.
Почитай мой урок про XSS, там написано что делать: https://github.com/codedokode/pasta/blob/master/security/xss.md
А так, у тебя нельзя вообще знак больше или меньше запостить.
http://ideone.com/bzXsna
Как вывести на странице последующих 5 ссылок на остальные новости?
http://morfy.monstra.org/documentation
>их кол-во не статично..
Порядок вывода по дате добавления записи?
Вот от нее можно и плясать.
Сейчас ночь, у меня получился достаточно сложный запрос. Алгоритм такой:
1) Выбрать столбцы из таблицы, упорядочить по дате, лимит 'число'.
2) Выбрать максимальную дату (самую свежую) из этой выборки.
3) Удалить все записи, у которых дата меньше или равна дате из п.2.
Уверен можно придумать и легче, но я спать очу.
Ты хочешь чтобы мы за тебя прочли документацию? Гм, мне кажется это тебе нужно в первую очередь, а не нам.
Подожди, а зачем вообще удалять из таблицы? Может просто не выбирать лишние данные?
Если тебе нужно ровно 4 страницы по 10 записей на каждой, то и выбирай из бд только нужные записи.
Для первой страницы это
select from table_name order by date desc limit 0, 10;
вторая
select from table_name order by date desc limit 10, 10;
и т.д.
Т.е. формула с одной переменной
select * from table_name order by date desc limit $offset, 10;
Величину $offset передаешь из ссылки методом гет.
Разве я не могу быть узконаправленным пхп-кодером?
потому что дорого кучу человек нанимать когда можно нанять одного который все умеет. Алсо php учится за месяц-два, это смешно, другие люди по 5 лет учатся а ты хочешь за пару месяцев отучиться. Иди на курсы парикмахеров тогда.
Имей в виду, там нет мяуса.
Запах мяуса там — от пережжёных дрожжей.
Так что подумай, узконаправленный похапекодер, подумай!!
>>505648
да, я по гуглу понапихаю куски кода, а через неделю читаю и сам не понимаю, что оно делает.
но у меня сортировка по id, а не по дате.
Во-первых, огромное спасибо за уроки! Все ну очень хорошо сделано, особенно для неофитов вроде меня.
Во-вторых, вопрос: это нормально, что на каждый последующий урок я трачу намного больше времени, чем на предыдущий, или я просто тормоз и программирование не для меня?
Сейчас добрался до массивов и даются они уже намного сложнее. Если на первый урок ушла пара часов со всякими там тестированиями и примерами, то на второй я потратил уже 2 дня, чтобы все осознать и более или менее запомнить. Третий ковырял почти неделю, но вроде как все запонил и выучил + очень много эксперементировал, решал собственные задачи по теме, усложнял приведенные там. Боюсь застрять на массивах на долго.
Мне ничуть не припекает, просто хочется узнать, это нормально или нет.
Просто я гуманитарий до глубины мозга, а тут решил что-то новенькое выучить, не все же сайты на готовых cms клепать. Хочу сам разобраться в том как эти cms устроены, а то и свою когда-нибудь написать.
Скорее всего не собирается, все времени нет. Хотя на однотипные вопросы всегда развернуто отвечает в треде. Явно было бы удобнее один раз написать короткий урок (нубы все равно не любят много букв), а не пересказывать каждый раз одно и то же.
Ну наверное доставляет удовольствие личный контакт, оказание помощи, благодарность и т.д.
Так что пользуйся опом как личным репетитором, задавай вопросы. Этот тред удивительно дохлый, стабильно здесь учится от силы человек пять. Остальные мимокроки.
Лично я в восторге от этого, значит людей которые хотят владеть своим делом на профессиональном уровне крайне мало, и у меня почти не будет конкуренции, когда я докачаюсь до капа.
>Лично я в восторге от этого, значит людей которые хотят владеть своим делом на профессиональном уровне крайне мало, и у меня почти не будет конкуренции, когда я докачаюсь до капа.
Лол, у меня те же мысли.
> И если бы я выбрал ActiveRecord, то насколько я понял этот паттерн тупо объединяет DataMapper и объект описания таблицы (не знаю как он называется)?
Нет, ты не понял. Почитай мой урок про работу с БД: https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md
Также эти паттерны описаны у Фаулера:
http://design-pattern.ru/patterns/active-record.html
http://design-pattern.ru/patterns/data-mapper.html
ActiveRecord это когда объект-модель сама себя сохраняет в базу, Data Mapper когда отдельный класс-маппер сохраняет модель.
> Опасаюсь только превращения этого класса в мусорку
Можно будет разбить на классы по смыслу: FileHelper, UserHelper и тд
> что при ООП-подходе вообще некомильфо использовать левые функции, все должно быть логически упаковано в классы.
Вообще да, но в маленьком приложении типа списка студентов проще функцию добавить.
>>504837
Ты глупости пишешь. Может он сначала с шаблонами на чистом php хочет разобраться. Ты не знаешь что он делает, а уже лезешь с шаблонизаторами. Тем более добавление функции для шаблонизатора займет больше кода чем просто создание обычной функции. Вопрос, какая тогда выгода?
> А если ты собрался форматировать ссылки, то использование шаблонизатора просто мастхев
Чушь какая-то.
Я до сих пор так и не смог найти удовлетворительное решение для задачи под банкомат. Или потребляет неестественно много памяти, либо не покрывает всё множество. Вот интересно, как это в реальных банкоматах сделано.
Тут нормально, ты скорее первый урок быстро прошёл, чем остальные медленно.
>Явно было бы удобнее один раз написать короткий урок
Я уверен, что уже видел подобные уроки в ОП-посте в этих тредах года два назад. По CSS и HTML.
Количества хуев, которые ты пнул за сегодня, с ежедневной статистикой и настраиваемыми графиками.
>Сомневаюсь, что такое реализуемо на пхп.
Обычно на PHP делают выводят набор данных, которые упаковывают в график посредством JS.
Я люблю вот эти использовать http://www.highcharts.com/demo
Так или иначе данные мне все равно придется в ручную вводить, какой же это будет счетчик, который самостоятельно их не собирает?
Делаешь кнопку "только что подрочилпокодил". С неё начинается отсчёт времени, вот это время и показывается. Данные хранятся в куки или в файле, чтобы все могли видеть, какой ты лентяй. Ещё прикрути комменты фейсбучные, чтобы могли тебя говном полить, если на счётчике больше дня.
Хуйня это всё. Лучше всего помогает блок фаерволлом. Когда понадобится - разблокируешь и зайдёшь, а вот от рандомных заходов хорошо помогает.
>знание JS'а
Не нужно.
Пиздец у тебя отговорок. На тебе ещё:
затраты калорий на нажимание клавиш
затраты на держание век поднятыми
затраты на ... да пошёл ты нахер
studentProject
-->app
-->config.php
-->StudentList
-->Student.php и другое
-->bootstrap-3.3.4
-->css
-->fonts
-->js
-->templates
-->header.php
-->main.php
-->registration.php
-->studentList.php
index.php
register.php
Точка входа - файл index.php, внутри которого происходит разбор $_GET метода и др. После всей этой бизнес-логики
происходит включение файла templates/main.php, в котором в свою очередь подключается header.php. Также в этом файле присутствует навбар, т.е. можно перейти на страницу регистрации.
Проблема в том, что если прописывать в templates/header.php в теге <link href="../bootstrap-3.3.4/css/.." две точки, то стили не отображаются в файле index.php. Если прописать <a href="./bootstrap-3.3.4/css/.." одну точку, то стили падают в представлении файла регистрации. Так же проблема с переходами на другие страницы.
Мое решение: в конфиге прописал абсолютные пути: BASE_DIR, CSS_DIR, TEMPLATES_DIR. И подключил этот конфиг в index.php и templates/registration.php (так как там эти константы снова подключаются)
Вопрос: как связать все эти файлы правильно? Не слишком ли топорно я подключаю конфиг, и вообще нужно ли там прописывать эти константы?
вот еще картинка
Ага. Что делать то? Ни разу с таким не встречался. Насколько я понял там какой-то гон со слешами.
Сделай все инклюды с BASE_DIR константой и дописывай уже после пути в папкам.
BASE_DIR . '/css/style.css';
BASE_DIR . '/register.php';
BASE_DIR . '/templates/main.php';
Так у тебя будет единство в подключении файлов и при переносе файла, в котором инклюд, в другое место, ничего не собьётся.
Ведь в принципе это и сейчас реально с точки зрения программирования.
Органы чувств можно имитировать телекоммуникациями, отдавать приказы роботу и получать ответы можно по вайфаю, радио, моб.связи, как угодно.
Зрение заменить датчиками инфракрасного излучения или всякими сонарами, например.
Проблема только в развитии технологий. Датчики недостаточно дешевые и неточные, источники энергии некомпактные.
А какой это будет прорыв в развитии человечества: ведь быдланов наконец можно будет заменить на роботов. Робот не просит большую зарплату на погашение кредита на быдломобиль, поездку в турцею и тряпки для самки. Робот не бухает, работает 24 часа в сутки. Не гадит в подъезде, не хамит в общественных местах и не совершает преступлений.
Быдланы постепенно вымрут, можно будет небольшую популяцию держать в зоопарках, поставить им там лавочки, дать гитары, водку, провести вк и одноклассники, кормить семечками.
Надеюсь так и будет.
Спасибо, а то, что я подключаю этот конфиг в 2 местах? В index.php понятное дело, но как сделать, чтобы и в файле registration.php были подключены эти константы?
Ну в твоём случае тебе таки придётся в каждом подключать конфиг отдельно. Можно сделать простой роутинг: все запросы идут на index.php, сам index.php в .htaccess убирается, и параметр, который идёт после, будет не директорией, а файлом, который нужно использовать. Вот как-то так:
mysite.com/registration
в файле index.php:
include('config.php');
include('registration.php'); - это будет переменной, которая берётся из адресной строки.
Странно, все хостинги (2 штуки, лол) с которыми я работал имели виндовую структуру файлов.
В 95% случаев виртуальный хостинг на юниксе, поэтому даже рекомендуется разрабатывать сайт на виртуалке юникса, чтобы избежать потом ситуаций "так у меня же на локальном работало!".
Да блин, проблема в том, что я неймспейсы использую. И он какого-то хуя обратный слеш дублирует. Т.е. в коде вызывается что-то типа
$controller = Controllers\Main;
А он вместо этого пытается вызвать Controllers\\Main. Можно это как-то починить?
<?php
$url = 'http:pp.vk.me/c623123\/v623123593\/2f37f\/GBtlCHgF6eg.jpg';
$path = './images/logo.jpg';
file_put_contents($path, file_get_contents($url));
?>
Но denwer выдает варнинг
Warning: file_get_contents(http:pp.vk.me/c623123\/v623123593\/2f37f\/GBtlCHgF6eg.jpg) [function.file-get-contents]: failed to open stream: Invalid argument in Z:\home\localhost\www\proba.php on line 4
Файл создается, но когда пытаюсь его открыть, пишет, что он пуст, поподскажите, как правильно скачать картинку по юрл адресу?
Блин, я забыл new дописать. В коде пишется
$controller = new Controllers\Main;
Т.е. по идее должен инклудится файл main.php из папки Controllers и создаваться новый экземпляр класса Main, но он с какого-то хуя приписывает дополнительный слеш. Мб это в композере что-то?
ты ебанат, если думаешь, что ИИ получится таким антропоморфным хуйламном на ножках. ИИ - это в первую очередь свобода выбора и будет оно в виде программы без всяких глазок-ножек.
и наша планета превратится в что-то наподобие "Непобедимого" Лема
>ИИ - это в первую очередь свобода выбора
Пиздец, свободоребёнок почитал статью из школьного курса философии. В чём выражается твоя свобода, если все твои желания детерминированы?
И при чем тут ии, если нужно чтобы станок на заводе мог самостоятельно вставить новую деталь и обработать ее по программе?
Автоматизация не интеллект.
в терминаторе сказали, что вообще пиздец начнется
Сука! Два часа убил на эту хуйню, а проблема оказалась в том, что классы не грузились из-за того, что названия файлов начинаются с маленькой буквы. Ну не пиздец ли?
str_replace
сейчас с этой задачей прекрасно справляются мясные баки за виртуальную симулякрокосточку, зачем машинам так утруждаться?
было что-то вроде этого: http://ideone.com/vaoMok
Возникает проблема на строке 7.
Это вообще возможно? Вызвать метод до вызова конструктора.
Теперь с элементами, чот тупанул.
Зачем ты вообще суешь туда пустые строки?
Объект по умолчанию создается с пустыми свойствами, только там вместо '' лежат null.
Запусти код, посмотри что будет:
class MyClass
{
public $property1;
public $porperty2;
}
$empty = new MyClass;
var_dump($empty);
Это я всё знаю. Мне надо, чтобы при создании объекта, если конструктор не получает аргументы, вместо null были пустые строки.
И вопрос, собственно в том, можно ли в качестве аргумента в конструктор запихнуть метод того же экземпляра объекта?
А почему нужны именно пустые строки? Null ведь легко конвертируется в пустую строку при рендере.
Например у тебя в шаблоне может выводиться
<div class="name"><?php echo $obj->name; ?></div>
<div class="email"><?php echo $obj->email; ?></div>
...
Если в каком-то из свойств null, то выведется пустая строка, ошибки не будет.
Почему именно в качестве аргумента?
В самом теле конструктора вызываешь любой метод и свойство текущего объекта или класса:
public function __construct()
{
$var1 = $this->anyMethod($args);
$var2 = self::anyStaticMethod($args);
}
Ты описывай конкретно задачу, может ее можно решить более подходящим способом.
Ок.
Есть один класс, конструктор которого принимает данные только в формате массива. На случай, если конструктор вызывается без аргументов, нам нужен массив с пустыми строками.
Но если:
>Null ведь легко конвертируется в пустую строку при рендере.
>Если в каком-то из свойств null, то выведется пустая строка
то всё это уже не нужно. Я хотел привести данные в подходящий вид для вывода в шаблоне. Спасибо.
Но ответ на этот вопрос всё ещё интересен:
>Можно ли в качестве аргумента в конструктор запихнуть метод того же экземпляра?
https://ideone.com/dlmu5g
Задача здесь http://archive-ipq-co.narod.ru/l1/regexp.html «Grammar Nazi»
Ебать дебил. Харкач, я научился детектить школьников-максималистов.
https://ru.wikipedia.org/wiki/Китайская_комната
>класс, конструктор которого принимает данные только в формате массива
Красивее будет, если этот класс принимает в качестве аргумента экземпляр другого класса, а не массив.
Например, если у тебя идет сбор информации из формы, то логичнее создать один класс для формы, типа User, а второй класс для взаимодействия с базой, который будет принимать экземпляр этого класса в качестве аргумента. Это похоже на паттерн DataMapper, только там класс поступает не в конструктор, а в определенный метод, например ->save(User $user) сохраняет объект с заполненными полями в таблицу.
>Можно ли в качестве аргумента в конструктор запихнуть метод того же экземпляра?
Я не знаю таких тонкостей, жди опа.
По идее при создании объекта создаются его свойства, а только потом отрабатывает конструктор.
Поскольку любой метод это свойство, в котором хранится функция (подозреваю что объект класса Closure), то метод объекта должен существовать до срабатывания конструктора. Да, думаю можно, надо сейчас проверить.
Только не "метод в качестве аргумента", а то что метод возвращает.
Если нужно "а" или "но", то делай так: (а|но).
В квадратных скобках указываются наборы символов, а не слова.
Небольшой эксперимент.
http://ideone.com/UdpdcL
Кстати, ты и сам мог его произвести.
__construct($var = $this->method()) не работает. Почему - ОП его знает.
Т.е. ходить на ножках и распознавать 3D объекты - это не попытка наделить машину человеческим сознанием в твоем говнопонимании?
>маам, я хочу чтобы робот собирал за миня партфель и конструктор ну мааам и выглядил вот так да))
>>506145
Походу при объявлении функции или метода можно задать дефолтное значение только в виде примитива (числа, строки), переменные и результаты работы функции не принимает.
>Значение по умолчанию должно быть константным выражением, а не (к примеру) переменной или вызовом функции/метода класса.
http://php.net/manual/ru/functions.arguments.php
Доделал задачу про «Grammar Nazi».
Но не сделал одного пункта, а именно: В случае обнаружения ошибки скрипт должен писать сообщение об этом и выводить кусок текста с ошибкой
Через что выводить эту неправильную часть?
И еще без ответа осталось и утонуло вот это:
Решил задачу про номера с большим списком номеров.
https://ideone.com/S1YPgh
Все правильно?
> Это вообще возможно? Вызвать метод до вызова конструктора.
Тебе надо вернуться к основам ООП. Конструктор это метод, который вызывается при создании объекта и инициализирует его и разумеется до него ничего вызвать нельзя по определению.
> public function __construct(array $values = array("property1" => "", "property2" => ""))
Ты занимаешься фигней. У объекта можно указать значения свойств по молчанию:
protected $x= 'asdasdad';
Проходил ли ты задание на ООО Вектор? Если нет то стоит решить.
> foreach ($this as $property => $value) {
> $this->$property = $values[$property];
Это неправильный код. Во-первых, в массиве могут остутсвовать какие-то поля, во-вторых, это массиво-ориентированное программирование.
Зачем тебе этот массив когда ты можешь прописать значения полей явно:
$obj = new Class1;
$obj->property1 = 2312313;
Массив тут лишний. Ты усложняешь код так как не понимаешь как работает ООП.
Конечно, ситцации когда мы хотим проставить значения полей из массива, бывают, обычно для этого делают метод setAttributes:
$user->setAttributes($_POST);
при этом мы создаем риск уязвимости: ведь злоумышленник может передать любые поля в POST, в том числе и те которые не должны изменяться извне. Если у тебя у пользователя есть свойство isAdmin то он может передать isAdmin = 1 и сделать себя админом. Именно так был в свое время взломан гитхаб.
>>506094
Нельзя.
>>506104
> конструктор которого принимает данные только в формате массива.
Это уже плохой признак. У нас есть объект, зачем нам вводить сюда массив который хуже по возможностям?
>>506117
> Красивее будет, если этот класс принимает в качестве аргумента экземпляр другого класса, а не массив.
Бред же. Класс User для создания требует объект класса User, так?
> то логичнее создать один класс для формы, типа User, а второй класс для взаимодействия с базой, который будет принимать экземпляр этого класса в качестве аргумента. Это похоже на паттерн DataMapper,
Разберись, что такое DataMapper, ибо я вижу что ты толком не понимаешь.
> только там класс поступает не в конструктор, а в определенный метод, например ->save(User $user) сохраняет объект с заполненными полями в таблицу.
Именно так DataMapper и работает: http://design-pattern.ru/patterns/data-mapper.html
>> Можно ли в качестве аргумента в конструктор запихнуть метод того же экземпляра?
нельзя
> Поскольку любой метод это свойство, в котором хранится функция (подозреваю что объект класса Closure)
Неверно. Так сделано только в яваскрипте, а во всех норальных языках метод и поле разная сущность. В этом легко убедиться попробовав сделать:
class A { function test() {} }
$a = new A();
var_dump($a->test); // ошибка
А также таким кодом:
class B {
public $x;
function x() {}
}
> (подозреваю что объект класса Closure)
А чем тогда являются методы класса Closure?
> то метод объекта должен существовать до срабатывания конструктора.
да, методы и поля сущестуют до вызова конструктора
> Это вообще возможно? Вызвать метод до вызова конструктора.
Тебе надо вернуться к основам ООП. Конструктор это метод, который вызывается при создании объекта и инициализирует его и разумеется до него ничего вызвать нельзя по определению.
> public function __construct(array $values = array("property1" => "", "property2" => ""))
Ты занимаешься фигней. У объекта можно указать значения свойств по молчанию:
protected $x= 'asdasdad';
Проходил ли ты задание на ООО Вектор? Если нет то стоит решить.
> foreach ($this as $property => $value) {
> $this->$property = $values[$property];
Это неправильный код. Во-первых, в массиве могут остутсвовать какие-то поля, во-вторых, это массиво-ориентированное программирование.
Зачем тебе этот массив когда ты можешь прописать значения полей явно:
$obj = new Class1;
$obj->property1 = 2312313;
Массив тут лишний. Ты усложняешь код так как не понимаешь как работает ООП.
Конечно, ситцации когда мы хотим проставить значения полей из массива, бывают, обычно для этого делают метод setAttributes:
$user->setAttributes($_POST);
при этом мы создаем риск уязвимости: ведь злоумышленник может передать любые поля в POST, в том числе и те которые не должны изменяться извне. Если у тебя у пользователя есть свойство isAdmin то он может передать isAdmin = 1 и сделать себя админом. Именно так был в свое время взломан гитхаб.
>>506094
Нельзя.
>>506104
> конструктор которого принимает данные только в формате массива.
Это уже плохой признак. У нас есть объект, зачем нам вводить сюда массив который хуже по возможностям?
>>506117
> Красивее будет, если этот класс принимает в качестве аргумента экземпляр другого класса, а не массив.
Бред же. Класс User для создания требует объект класса User, так?
> то логичнее создать один класс для формы, типа User, а второй класс для взаимодействия с базой, который будет принимать экземпляр этого класса в качестве аргумента. Это похоже на паттерн DataMapper,
Разберись, что такое DataMapper, ибо я вижу что ты толком не понимаешь.
> только там класс поступает не в конструктор, а в определенный метод, например ->save(User $user) сохраняет объект с заполненными полями в таблицу.
Именно так DataMapper и работает: http://design-pattern.ru/patterns/data-mapper.html
>> Можно ли в качестве аргумента в конструктор запихнуть метод того же экземпляра?
нельзя
> Поскольку любой метод это свойство, в котором хранится функция (подозреваю что объект класса Closure)
Неверно. Так сделано только в яваскрипте, а во всех норальных языках метод и поле разная сущность. В этом легко убедиться попробовав сделать:
class A { function test() {} }
$a = new A();
var_dump($a->test); // ошибка
А также таким кодом:
class B {
public $x;
function x() {}
}
> (подозреваю что объект класса Closure)
А чем тогда являются методы класса Closure?
> то метод объекта должен существовать до срабатывания конструктора.
да, методы и поля сущестуют до вызова конструктора
Кстати, если тебе любопытно, разработчики библиотеки PDO тоже не читали теорию ООП и умудрились сделать опцию (PDO::FETCH_OBJ), которая прописывает значения свойств до вызова конструктора вопреки принципам ООП. Потом правда кто-то им указал на ошибку и они добавили вторую опцию, исправляющую это.
можете подсказать годных книг и какой-нибудь эталон на инглише?
после этого учить php или базы данных?
и тупой вопрос: почему надо знать html css если есть софтина от адоби на букву D? Приемлимо ли использование WYSIWYG редакторов? почему?
спасибо.
>html css
Синтаксис настолько простой, что его за две недели можно выучить.
>выучить
Ссыканул для профилактики.
Ну так он и есть простой, выучив его что надо уметь делать? одно дело синтаксис другое его на практике применять
Ну так выучи его, пройдя курс на HTML Academy, найди пару-тройку PSD макетиков и сверстай их. Вот тебе и опыт и умение применять на практике будет.
Не знаю, ни разу не пользовался. Подозреваю, что много отсебятины лепит и гибкости недостает.
Сначала пройди уроки ОПа, если осилишь и останется интерес, то покупай курс там и получай сертификат. С сертификатом уже можно пробовать устраиваться на работу или начинать пытаться фрилансить. Но лучше начинать с фриланса, а то может как у меня получиться, что на работу примут, дадут задание, а я не могу его выполнить, знаний не хватает. Ну я и слился побыстрому пока не успели официально оформить и не уволили по статье профнепригодность. Лол.
Потом на фрилансе опыт набирал, а потом забил на это дело из-за нехватки бабла и пошел продавать машины, там хоть зп по графику.
> ну в хтмл все просто и упирается в память чтобы запомнить все дискрипторы,
Не дескрипторы, а теги.
> Так вот насколько надо владеть этими технологиями?
Уметь нормально сверстать страницу по макету. У нас есть в Оп пост задачи на HTML/CSS, можешь их порешать.
> и тупой вопрос: почему надо знать html css если есть софтина от адоби на букву D?
Dreamweaver невозможно нормально пользоваться не понимая HTML. Ведь реальная страница может отображаться в окне разной ширины, контент в ней тоже динамически меняется. HTML это не статичная картинка. Без знания HTML ты это не сверстаешь.
Это помощник для тех кто знает верстку, а не замена.
> Приемлимо ли использование WYSIWYG редакторов?
Приемлемо если ты способен и без них все сделать. Более того, вручную по моему верстатть удобнее и быстрее получается.
>>506282
Уметь сверстать страницу по макету. У нас есть в ОП посте задачи на HTML/CSS, надо уметь решать их все.
>>506283
В Оп посте есть задача на верстку и есть PSD
>>506289
Без знания HTML/CSS и понимания позиционирования ты в них номально ничего не сверстаешь.
>>506303
И кто этим будет заниматься?
> ну в хтмл все просто и упирается в память чтобы запомнить все дискрипторы,
Не дескрипторы, а теги.
> Так вот насколько надо владеть этими технологиями?
Уметь нормально сверстать страницу по макету. У нас есть в Оп пост задачи на HTML/CSS, можешь их порешать.
> и тупой вопрос: почему надо знать html css если есть софтина от адоби на букву D?
Dreamweaver невозможно нормально пользоваться не понимая HTML. Ведь реальная страница может отображаться в окне разной ширины, контент в ней тоже динамически меняется. HTML это не статичная картинка. Без знания HTML ты это не сверстаешь.
Это помощник для тех кто знает верстку, а не замена.
> Приемлимо ли использование WYSIWYG редакторов?
Приемлемо если ты способен и без них все сделать. Более того, вручную по моему верстатть удобнее и быстрее получается.
>>506282
Уметь сверстать страницу по макету. У нас есть в ОП посте задачи на HTML/CSS, надо уметь решать их все.
>>506283
В Оп посте есть задача на верстку и есть PSD
>>506289
Без знания HTML/CSS и понимания позиционирования ты в них номально ничего не сверстаешь.
>>506303
И кто этим будет заниматься?
Ну спасибо, пора уже перестать хуйней страдать, начну с задачек ОПа
вопрос на будущее, вот есть апач и пхп, это обязательно или хватит для начала Denver?
Чет проиграл)) ОП няшка
оу, апачи это сервер, у меня один хард, годится ли на флеху ставить генту+ апач+ нотепад++?
PHP IDE не кошерно?
Или можно на винь PHP ставить? вот говорят что на генту быстрее других линуксов, а с вендой не сравнивали скорость исполнения.
Как ты мог усомниться в курсах Борисова? Почему ещё не скачал?
Ты эту разницу не заметишь, разрабатывай на чём удобнее и всё.
У меня товарищ работает тестером, получает 3к.
>генту быстрее других линуксов
На 0.0005%, и то, после ебли. Обычно ньюфаги комплируют криво и делают её медленнее убунт всяких.
Можешь и на венде ставить. Качай phpstorm и занимайся. Если хочешь линукс - поставь в виртуалку какую-нибудь убунту, настрой по гайду с digital ocean.
<?php
error_reporting(-1);
$dollars = 200; / Число долларов /
$exchangeRate = 32.24; / Курс обмена /
$roubles = 0; / А вот эту строчку надо дописать самому /
echo "$dollars долларов можно обменять на $roubles рублей";
Собсна, вопрос. Каким образом на экран выводится количество рублей и долларей, если не задан алгоритм умножения обменного курса на количество у.е? Или переменная exchangeRate все делает за тебя?
Что-то я не понял твоего вопроса. Тебе нужно в переменной roubles поменять 0 на формулу.
В любом языке можно называть переменный как угодно. Ну, в некоторых придётся дописать перед переменной какой-нибудь определитель, но в целом это стандартная картина для любого языка.
Естественно. Результат сохраняешь в переменную, а ее значение подкручиваешь циклами.
Чтобы вероятность выпадения одного числа была выше по отношению к другому. К примеру, ставит игрок на красное, а код ему говорит if $красное esle черное. Как-то так, только с числами.
Да, точно, фенки.
Конечно, например есть 10 чисел на рулетке, тебе нужно, чтобы чаще других выпадали от 7 до 10.
Делаешь массив:
$arr = [
1 = [1,2],
2 = [3,4],
3 = [5,6],
4 = [7,8,9,10],
];
Потом выбираешь случайный элемент из этого массива и берёшь случайное число и выбранного ранее. В этом примере у тебя числа от 7 до 10 будут выпадать в 2 раза чаще. Можно это сделать множеством способов, я привёл довольно упрощённый.
А как реализовать вероятность выйгрыша, просто пониженную? Зарядить в цикл что-то вроде:
if $количествоПроигрышей >= 3
else $количествоПроигрышей = $рандомноеЧислоБезИзменений
>>506379
http://ideone.com/es5Bcp первое что пришло мне в голову. По идее красное будет выпадать гораздо чаще. Хотя наверное глупое решение.
Если только два варианта, сделай ассоциативный массив вида
'1-60' => 'red',
'61-100' => 'black'
Потом делаешь rand(1,100), выпавшее число подставляешь в ключи массива, если входит в диапазон - выбираешь этот вариант. Например, если выпадет 63, то будет 'black', но если выпадет 60 - будет 'red'.
Их наказали, проклинающие их игроки, когда в гиду по игре написан дроп-шанс в 20% с босса, а по факту он 5%.
Что конкретно не так? Люди вроде хвалят.
Удивляюсь тебе, ОП, как у тебя хватает терпения на них. Макаки даже в чтение глазами не могут.
Я не ОП, кстати.
Чтобы прервать цикл, очевидно.
Возьми код цикла в { }. Убери break;
Выведи парами $letter1 и $letter2. Узри закономерность. Прочитай еще раз про строки, нумерацию символов в строке. Разберись какие символы ты проверяешь в текущий момент.
У тебя там вообще ничего не работает, тело цикла должно быть в фигурных скобках.
Ну пожалуй да, если правильно переменные подписывать то все читаться будет, хотя на системных языках вполне можно писать НЕХ
Все написано просто и понятно, как раз для таких имбецилов как я.
Главное все делать только за счет разбора теории без подстказок и не читать дебилов, которые в комментах сразу вбрасывают рабочий код.
Кстати, самая коварная вещь - неправильный код выдаёт правильный результат.
Выучить два десятка тегов, в конце-концов, любой сможет.
боль
а до куда ты дошел по учебнику ОПа?
Вот набор замечаний по коду.
База данных
> https://github.com/Si0n/register3/blob/c30980b8cbe605efff0ad6c15551f15c07142ca2/Students.sql#L41
Что это у тебя один индекс 3 раза встречается? Надо бы удалить лишние.
Уникальный ключ надо сделать по email и password, а не по id. Ты явно это делал в какой-то программе и напутал. Я думаю, что начинающему лучше руками написать запрос ALTER TABLE ... ADD UNIQUE KEY как тут описано:
http://www.google.ru/search?aq=f&sourceid=chrome&ie=UTF-8&q=mysql+alter+table+add+key
Регистрация
По поводу формы регистрации — а почему у тебя 2 URL для нее?
index.php?page=registration
reg.php
Я считаю, это создает лишнюю путаницу и надо оставить только один скрипт и для вывода формы и для обработки отправленных из нее данных. Я думаю, надо убрать эту ссылку index.php?page=registration
> header('Location: index.php?register=ok');
После редиректа надо завершать скрипт, а не выводить дальше то-то.
Картинки
> https://github.com/Si0n/register3/blob/master/savePhoto.php
> if (isset($_POST['submit']))
Что если это условие не выолняется? Что выведется? Белый экран?
> https://github.com/Si0n/register3/blob/master/savePhoto.php#L11
при ошибке надо не редиректить на главную, а на форму загрузки, а еще лучше, сразу выводить форму чтобы нажатием F5 ее можно было отправить повторно.
Редиректить надо после успешной обработки формы. При неуспешной надо снова выводить форму.
Чтобы форму легко было вывести повторно, надо чтобы один и тот же скрипт выводил страницу с формой и обрабаывал данные от нее.
> https://github.com/Si0n/register3/blob/c30980b8cbe605efff0ad6c15551f15c07142ca2/lib/Image.php#L41
Эта строчка слишком длинная, разбей ее переносами. Максимальный размер файла надо сделать не числом, а свойством класса.
> https://github.com/Si0n/register3/blob/c30980b8cbe605efff0ad6c15551f15c07142ca2/lib/Image.php#L50
> public function makeNewNameOfPhoto($ID)
> while (file_exists("upload/" . $ID . $baseName . $randomNumber. '.jpg'));
Не стоит использовать для таких вещей потенциально вечные циклы. Надо использовать цикл for допустим с 10 попытками и если не удалось подобрать имя файла, выкинуть исключение.
Но здесь вообще необязательно генерировать уникальное имя. Что плохого в том что мы перезапишем файл новым с тем же именем?
> https://github.com/Si0n/register3/blob/c30980b8cbe605efff0ad6c15551f15c07142ca2/lib/Image.php#L70
> if (!file_exists($src)) return false;
Ты возвращаешь false при ошибке. А ты при вызове функции проверяешь ее результат? Не проверяешь. Тогда для кого ты возвращаешь false?
Надо при ошибке либо обрабатывать ее (то есть проверять вернула ли функция false) и показывать понятное пользователю сообщение (без технических подробностей) либо выбрасывать исключение. Игнорировать ошибку и притворяться что ничего не произошло, как ты это делаешь, неправильно.
> saveImage
> img_resize
> $x_ratio
> $baseName
Функции и переменные надо называть в едином стиле. Почему они в другом стиле? Ты скопировал откуда-то функцию? Тогда плохо, когда ты копируешь ты ничему не учишься. Надо посмотреть на код, разобраться как он работает, а затем закрыть его и написать своими словами.
> https://github.com/Si0n/register3/blob/c30980b8cbe605efff0ad6c15551f15c07142ca2/lib/Image.php#L63
> $src = 'upload/'. $name;
Ты используешь относительный путь и это чревато проблемами. Для команд работы с файлами надо передавать полный путь от корня диска. В базу сохранять, разумеется, отсносительный.
Также, путь к файлу и путь к превьюшке должны формироваться с помощью отдельных методов.
сообщения
> LIMIT $offset, 4
Не вставляй переменные прямо в запрос, используй плейсхолдеры.
Что значит 4? Это должно храниться где-то в поле, константе или переменной с понятным именем. Также, убедись что число сообщений на странице задается ровно в одном месте кода, не в двух.
Та же самая проблема тут:
> LIKE :string ORDER BY $order $sort LIMIT $offset, 4";
Эта цифра тоже должна где-то храниться и быть в единственном экземпляре.
> https://github.com/Si0n/register3/blob/c30980b8cbe605efff0ad6c15551f15c07142ca2/mess_action.php
Нет, так не пойдет. Валидацию сообщения надо вынести в отдельный класс или функцию. При ошибке надо не редиректить а выводить ту же самую форму с введенными значениями и текстом ошибки.
Прочитай внимательно урок про работу с формами: https://github.com/codedokode/pasta/blob/master/forms.md
Сделай также, как там описано, и так же как сделана форма регистрации.
Пока все. Исправь сначала это, а потом проверим остальное. Я может быть не очень понятно что-то написал, в таком случае задавай вопросы.
Вот набор замечаний по коду.
База данных
> https://github.com/Si0n/register3/blob/c30980b8cbe605efff0ad6c15551f15c07142ca2/Students.sql#L41
Что это у тебя один индекс 3 раза встречается? Надо бы удалить лишние.
Уникальный ключ надо сделать по email и password, а не по id. Ты явно это делал в какой-то программе и напутал. Я думаю, что начинающему лучше руками написать запрос ALTER TABLE ... ADD UNIQUE KEY как тут описано:
http://www.google.ru/search?aq=f&sourceid=chrome&ie=UTF-8&q=mysql+alter+table+add+key
Регистрация
По поводу формы регистрации — а почему у тебя 2 URL для нее?
index.php?page=registration
reg.php
Я считаю, это создает лишнюю путаницу и надо оставить только один скрипт и для вывода формы и для обработки отправленных из нее данных. Я думаю, надо убрать эту ссылку index.php?page=registration
> header('Location: index.php?register=ok');
После редиректа надо завершать скрипт, а не выводить дальше то-то.
Картинки
> https://github.com/Si0n/register3/blob/master/savePhoto.php
> if (isset($_POST['submit']))
Что если это условие не выолняется? Что выведется? Белый экран?
> https://github.com/Si0n/register3/blob/master/savePhoto.php#L11
при ошибке надо не редиректить на главную, а на форму загрузки, а еще лучше, сразу выводить форму чтобы нажатием F5 ее можно было отправить повторно.
Редиректить надо после успешной обработки формы. При неуспешной надо снова выводить форму.
Чтобы форму легко было вывести повторно, надо чтобы один и тот же скрипт выводил страницу с формой и обрабаывал данные от нее.
> https://github.com/Si0n/register3/blob/c30980b8cbe605efff0ad6c15551f15c07142ca2/lib/Image.php#L41
Эта строчка слишком длинная, разбей ее переносами. Максимальный размер файла надо сделать не числом, а свойством класса.
> https://github.com/Si0n/register3/blob/c30980b8cbe605efff0ad6c15551f15c07142ca2/lib/Image.php#L50
> public function makeNewNameOfPhoto($ID)
> while (file_exists("upload/" . $ID . $baseName . $randomNumber. '.jpg'));
Не стоит использовать для таких вещей потенциально вечные циклы. Надо использовать цикл for допустим с 10 попытками и если не удалось подобрать имя файла, выкинуть исключение.
Но здесь вообще необязательно генерировать уникальное имя. Что плохого в том что мы перезапишем файл новым с тем же именем?
> https://github.com/Si0n/register3/blob/c30980b8cbe605efff0ad6c15551f15c07142ca2/lib/Image.php#L70
> if (!file_exists($src)) return false;
Ты возвращаешь false при ошибке. А ты при вызове функции проверяешь ее результат? Не проверяешь. Тогда для кого ты возвращаешь false?
Надо при ошибке либо обрабатывать ее (то есть проверять вернула ли функция false) и показывать понятное пользователю сообщение (без технических подробностей) либо выбрасывать исключение. Игнорировать ошибку и притворяться что ничего не произошло, как ты это делаешь, неправильно.
> saveImage
> img_resize
> $x_ratio
> $baseName
Функции и переменные надо называть в едином стиле. Почему они в другом стиле? Ты скопировал откуда-то функцию? Тогда плохо, когда ты копируешь ты ничему не учишься. Надо посмотреть на код, разобраться как он работает, а затем закрыть его и написать своими словами.
> https://github.com/Si0n/register3/blob/c30980b8cbe605efff0ad6c15551f15c07142ca2/lib/Image.php#L63
> $src = 'upload/'. $name;
Ты используешь относительный путь и это чревато проблемами. Для команд работы с файлами надо передавать полный путь от корня диска. В базу сохранять, разумеется, отсносительный.
Также, путь к файлу и путь к превьюшке должны формироваться с помощью отдельных методов.
сообщения
> LIMIT $offset, 4
Не вставляй переменные прямо в запрос, используй плейсхолдеры.
Что значит 4? Это должно храниться где-то в поле, константе или переменной с понятным именем. Также, убедись что число сообщений на странице задается ровно в одном месте кода, не в двух.
Та же самая проблема тут:
> LIKE :string ORDER BY $order $sort LIMIT $offset, 4";
Эта цифра тоже должна где-то храниться и быть в единственном экземпляре.
> https://github.com/Si0n/register3/blob/c30980b8cbe605efff0ad6c15551f15c07142ca2/mess_action.php
Нет, так не пойдет. Валидацию сообщения надо вынести в отдельный класс или функцию. При ошибке надо не редиректить а выводить ту же самую форму с введенными значениями и текстом ошибки.
Прочитай внимательно урок про работу с формами: https://github.com/codedokode/pasta/blob/master/forms.md
Сделай также, как там описано, и так же как сделана форма регистрации.
Пока все. Исправь сначала это, а потом проверим остальное. Я может быть не очень понятно что-то написал, в таком случае задавай вопросы.
Так подойдет.
Разорвать тут надо всего 2 тега, body и html. Когда дойдешь до изучения шаблонизатора twig, узнаешь про наследование шаблонов и теги разрывать не придется.
>>504891
> Но зачем мне заучивать, что есть какой-то модификатор escape, который экранирует строки, если я могу с таким же успехом написать в шаблоне htmlspecialchars?
Потому что в смарти так приянто. Если не нравится, не используй его. Ну и писать htmlspecialchars(.., ENT_QUOTS) как минимум дольше.
Это косяк смарти, что он позволяет вызывать любые функции, в других шаблонизаторах обычно такого нет.
Кстати в твиге есть автоэкранирование и можно просто писать
{{ name }}
> чтобы шаблонизатор не был привязан к конкретному языку
Наверно.
>>504948
Нет. Но у нас есть этот тред.
>>504952
Уметь сделать список студентов и файлообменник из ОП-поста.
>>504757
Работать придется через 6 месяцев.
>>504993
> чтобы претендовать на вакансию джуниора (младшего разработчика).
Только поправлю что требования в разных компаниях разные. В какой-нибудь подвальной веб-студии этих знаний хватит, а в яндексе нет. В яндексе джуниор это круче чем в подвальной студии архитектор.
Так подойдет.
Разорвать тут надо всего 2 тега, body и html. Когда дойдешь до изучения шаблонизатора twig, узнаешь про наследование шаблонов и теги разрывать не придется.
>>504891
> Но зачем мне заучивать, что есть какой-то модификатор escape, который экранирует строки, если я могу с таким же успехом написать в шаблоне htmlspecialchars?
Потому что в смарти так приянто. Если не нравится, не используй его. Ну и писать htmlspecialchars(.., ENT_QUOTS) как минимум дольше.
Это косяк смарти, что он позволяет вызывать любые функции, в других шаблонизаторах обычно такого нет.
Кстати в твиге есть автоэкранирование и можно просто писать
{{ name }}
> чтобы шаблонизатор не был привязан к конкретному языку
Наверно.
>>504948
Нет. Но у нас есть этот тред.
>>504952
Уметь сделать список студентов и файлообменник из ОП-поста.
>>504757
Работать придется через 6 месяцев.
>>504993
> чтобы претендовать на вакансию джуниора (младшего разработчика).
Только поправлю что требования в разных компаниях разные. В какой-нибудь подвальной веб-студии этих знаний хватит, а в яндексе нет. В яндексе джуниор это круче чем в подвальной студии архитектор.
Вакансии бывают разные и да, на удаленке могут быть высокие требования, например в совершенстве знать Юи, Симфони, оптимизацию баз данных и тд. Но мы можем вас дотянуть до этих требований (если там не нужен опыт), было бы желание и время.
>>505041
Зря кстати. Лучше разрабатывать локально, а потом синхронизировать с хостингом каким-нибудь скриптом или программой (если это не требует ручных действий). Нет ниего хуже чем править файлы по FTP, это порочная практика и так делать не надо (почему? потому что это медленнее, это не совместимо с гитом, можно потерять или затереть файлы).
>>505149
У меня описано как https://github.com/codedokode/pasta/blob/master/security/xss.md
Выглядит костыльно. Например, если ты удаляешь лишние символы в номере, зачем ты в выражении для проверки их проверяешь? Надо сделать либо одно либо другое.
> [\d][)]
То есть ты предполагаешь что между цифрой и скобкой не может быть пробела? Я думаю, лучше просто написать «дополнительные символы могут идти в любом порядке», а не задавать жесткий порядок следования.
Далее, вот это подозрительно:
preg_replace('[\+7]'
Регулярка заключается в ограничители. Почему ты в качестве них используешь квадратные скобки? По моему ты наугад поставил это.
Ну и наконец, понимаешь ли ты что делают квадратные скобки? [+7] это не значит «знак плюс за которым идет цифра 7». Это значит «любой из символов, плюс или цифра семь».
> for ($i = 0; $i <= (count($rnumber) - 1); $i++) {
Тут надо использовать foreach
> Дело в том, что данные выводятся с последней строки в таблице по первую, т.е. в обратном порядке,
Во-первых можно получить id и удалить через них:
SELECT id ORDER LIMIT
DELETE WHERE id IN(...)
Во-вторых можно попробовать это объединить в один запрос, DELETE WHERE id IN (SELECT)
В-третьих, в mySQL DELETE поддерживает ORDER и LIMIT.
>>505662
надо самому все писать
>>505711
Нет, боюсь что я не готов делать за тебя твою работу.
>>505813
Так и должно быть.
>>505821
У нас есть «Путь HTML», ссылка в ОП посте, там правда в основном задачи, но есть и ссылки на теорию.
>>505840
Некоторые пасты я сохраняю в txt, найти бы еще время все это разгрести.
>>505840
Работы для всех хватит. Проникновение интернета и компьютеров растет и большая часть населения (которая пока им не охвачена) это потенциальный рынок. Будет больше пользователей интернета, будет больше сайтов, нужно будет больше разработчиков для них (правда зарплата низкоквалифицированных разработчиков может снизиться, что поделать).
Также, в будущем нас ждут роботизированные автомобили, промышленные роботы, домашние роботы и еще много чего.
>>505950
По умолчанию там используется жадный аглоритм. То есть берем по максимуму самой большо купюры, потом по максимуму купюры поеньше и тд.
Но если ты вводишь банкноты в 200 и 2000 этот алгоритм не работает. Так как если нам надо выдать 6000, а у нас есть 1×5000 и 3×2000 то жадный алгоритм возьмет 5000-ю купюру и не сможет выдать оставшуюся тысячу.
С произвольными банкнотами мы должны перебирать все возможные комбинации количеств купюр. Это разновидность так называемой задачи о рюкзаке.
Прямой перебор имеет сложность O(N^M) где N это запас банкнот одного вида, M это числов видов банкнот. Однако если вести перебор в правильном порядке, во многих случаях решение найдется быстро.
Есть алгоритм, который позволяет найти решение за меньшее время, он описан тут:
http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BE_%D1%80%D1%8E%D0%BA%D0%B7%D0%B0%D0%BA%D0%B5#.D0.97.D0.B0.D0.B4.D0.B0.D1.87.D0.B0_.D0.BE_.D1.80.D0.B0.D0.B7.D0.BC.D0.B5.D0.BD.D0.B5
и тут
http://informatics.mccme.ru/mod/book/view.php?id=815
> Вот интересно, как это в реальных банкоматах сделано.
В реальных банкоматах купюр ограниченное количество и проблемы нет.
> Дело в том, что данные выводятся с последней строки в таблице по первую, т.е. в обратном порядке,
Во-первых можно получить id и удалить через них:
SELECT id ORDER LIMIT
DELETE WHERE id IN(...)
Во-вторых можно попробовать это объединить в один запрос, DELETE WHERE id IN (SELECT)
В-третьих, в mySQL DELETE поддерживает ORDER и LIMIT.
>>505662
надо самому все писать
>>505711
Нет, боюсь что я не готов делать за тебя твою работу.
>>505813
Так и должно быть.
>>505821
У нас есть «Путь HTML», ссылка в ОП посте, там правда в основном задачи, но есть и ссылки на теорию.
>>505840
Некоторые пасты я сохраняю в txt, найти бы еще время все это разгрести.
>>505840
Работы для всех хватит. Проникновение интернета и компьютеров растет и большая часть населения (которая пока им не охвачена) это потенциальный рынок. Будет больше пользователей интернета, будет больше сайтов, нужно будет больше разработчиков для них (правда зарплата низкоквалифицированных разработчиков может снизиться, что поделать).
Также, в будущем нас ждут роботизированные автомобили, промышленные роботы, домашние роботы и еще много чего.
>>505950
По умолчанию там используется жадный аглоритм. То есть берем по максимуму самой большо купюры, потом по максимуму купюры поеньше и тд.
Но если ты вводишь банкноты в 200 и 2000 этот алгоритм не работает. Так как если нам надо выдать 6000, а у нас есть 1×5000 и 3×2000 то жадный алгоритм возьмет 5000-ю купюру и не сможет выдать оставшуюся тысячу.
С произвольными банкнотами мы должны перебирать все возможные комбинации количеств купюр. Это разновидность так называемой задачи о рюкзаке.
Прямой перебор имеет сложность O(N^M) где N это запас банкнот одного вида, M это числов видов банкнот. Однако если вести перебор в правильном порядке, во многих случаях решение найдется быстро.
Есть алгоритм, который позволяет найти решение за меньшее время, он описан тут:
http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BE_%D1%80%D1%8E%D0%BA%D0%B7%D0%B0%D0%BA%D0%B5#.D0.97.D0.B0.D0.B4.D0.B0.D1.87.D0.B0_.D0.BE_.D1.80.D0.B0.D0.B7.D0.BC.D0.B5.D0.BD.D0.B5
и тут
http://informatics.mccme.ru/mod/book/view.php?id=815
> Вот интересно, как это в реальных банкоматах сделано.
В реальных банкоматах купюр ограниченное количество и проблемы нет.
Запости свой код. ты делал что-то не так, так как алгоритм полного перебора всех комбинаций не потребляет много памяти.
>>505989
Попробуй меньше есть.
>>506000
Кстати гитхаб показывает твою активность: https://github.com/codedokode/
>>506020
Сделай в конфиге настройку $baseDir которая хранит путь к корню сайта, например /student или / если твой проект в корне расположен.
лучше переменной, не константой.
Алсо не копируй атрибуты которые ты не понимаешь. зачем ты autofocus на несколько тегов скопировал? Зачем у тебя meta viewport стоит?
>>506023
Проверить где ищет, легко, расковыряй автозагрузчик и поставь туда var_dump.
>>506026
Лучше переменной, а не константой. Константы это неизменные вещи.
>>506027
Норм
>>506028
Роботы уже много где исопльзуются, если ты читаешь хабр/гиктаймс то должен знать что проводятся конкурсы, испытываются роботомобили, промышленные роботы на западных заводах используются.
По мере увеличения объемов производства цены будут снижаться, а качество повышаться. Особенно когда начнут появляться домашиние роботы, которых сможет купить каждый.
> Быдланы постепенно вымрут,
Для этого нужны не роботы, а культура и образование.
>>506029
В линуксе имена файлов чувствительны к регистру.
>>506032
Тут важно уязвимостей не оставить
>>506036
Нет, ты неправильно мыслишь. Полезнее разрабатывать под виндой чтобы уметь писать кроссплатформенный код, а не код в котором все захардкожено и который ломается при малейших изменениях в окружении.
>>506037
Это так выводится скорее всего, на самом деле бекслеш там один.
>>506038
Учись.
Запости свой код. ты делал что-то не так, так как алгоритм полного перебора всех комбинаций не потребляет много памяти.
>>505989
Попробуй меньше есть.
>>506000
Кстати гитхаб показывает твою активность: https://github.com/codedokode/
>>506020
Сделай в конфиге настройку $baseDir которая хранит путь к корню сайта, например /student или / если твой проект в корне расположен.
лучше переменной, не константой.
Алсо не копируй атрибуты которые ты не понимаешь. зачем ты autofocus на несколько тегов скопировал? Зачем у тебя meta viewport стоит?
>>506023
Проверить где ищет, легко, расковыряй автозагрузчик и поставь туда var_dump.
>>506026
Лучше переменной, а не константой. Константы это неизменные вещи.
>>506027
Норм
>>506028
Роботы уже много где исопльзуются, если ты читаешь хабр/гиктаймс то должен знать что проводятся конкурсы, испытываются роботомобили, промышленные роботы на западных заводах используются.
По мере увеличения объемов производства цены будут снижаться, а качество повышаться. Особенно когда начнут появляться домашиние роботы, которых сможет купить каждый.
> Быдланы постепенно вымрут,
Для этого нужны не роботы, а культура и образование.
>>506029
В линуксе имена файлов чувствительны к регистру.
>>506032
Тут важно уязвимостей не оставить
>>506036
Нет, ты неправильно мыслишь. Полезнее разрабатывать под виндой чтобы уметь писать кроссплатформенный код, а не код в котором все захардкожено и который ломается при малейших изменениях в окружении.
>>506037
Это так выводится скорее всего, на самом деле бекслеш там один.
>>506038
Учись.
>Попробуй меньше есть.
Wut? Как это поможет? Во мне итак 60 килограмм чистого веса при 180 см роста.
Нет, нужно делать у себя и иметь скрипт или программу для синхронизации файлов куда надо.
>>506049
Найди программу-даунлоадер.
>>506051
Файл должен иметь имя в том же регистре букв, это требование PSR-4
>>506052
Зачем нам искуственный интеллект когда есть естественный?
>>506055
Есть разница между «детерминированы и предсказуемы» и «детерминированы но непредсказуемы». Последнее на практике ближе к «недетерминированы».
>>506074
Робот справляется лучше. Особенно лучше станет когда роботы смогут производить роботов и их цена будет стремиться к стоимости исходных материалов.
>>506065
Надо написать самому.
Нет, нужно делать у себя и иметь скрипт или программу для синхронизации файлов куда надо.
>>506049
Найди программу-даунлоадер.
>>506051
Файл должен иметь имя в том же регистре букв, это требование PSR-4
>>506052
Зачем нам искуственный интеллект когда есть естественный?
>>506055
Есть разница между «детерминированы и предсказуемы» и «детерминированы но непредсказуемы». Последнее на практике ближе к «недетерминированы».
>>506074
Робот справляется лучше. Особенно лучше станет когда роботы смогут производить роботов и их цена будет стремиться к стоимости исходных материалов.
>>506065
Надо написать самому.
запомни что делают скобки:
[abc] значит «любой из символов написанных в скобках»
(abc|def) группируют часть выражения
{1,3} задают число повторений
> [,|:|;|.|!|?]
Здесь знак | значит «символ вертикальной черты» и не имеет никакого особого значения. Скобки значат «любой из символов: ,:;.!?|»
> [\\S]
Скобки тут не нужны
> [а-яё|0-9]
То же самое, в квадратных скобках | значит просто вертикальную черту и все
В этой задаче лучше использовать preg_match_all так как она находит все соответствия шаблону, а preg_match толкьо первое. Также, хорошо бы выводить кусок с ошибкой, например:
Нет пробела после запятой: ,н
Нет пробела после запятой: ,а
Или так:
Нет пробела после запятой: координально [,н]е она[,а]
> "Нет запятой перед \"но\"
Можно писать строку в одиночных кавычках чтобы не экранировать двойные.
запомни что делают скобки:
[abc] значит «любой из символов написанных в скобках»
(abc|def) группируют часть выражения
{1,3} задают число повторений
> [,|:|;|.|!|?]
Здесь знак | значит «символ вертикальной черты» и не имеет никакого особого значения. Скобки значат «любой из символов: ,:;.!?|»
> [\\S]
Скобки тут не нужны
> [а-яё|0-9]
То же самое, в квадратных скобках | значит просто вертикальную черту и все
В этой задаче лучше использовать preg_match_all так как она находит все соответствия шаблону, а preg_match толкьо первое. Также, хорошо бы выводить кусок с ошибкой, например:
Нет пробела после запятой: ,н
Нет пробела после запятой: ,а
Или так:
Нет пробела после запятой: координально [,н]е она[,а]
> "Нет запятой перед \"но\"
Можно писать строку в одиночных кавычках чтобы не экранировать двойные.
Ну когда досыта нажираешься, то тянет ко сну, и ничего не соображаешь.
Еще обязательно хорошо высыпаться. Я когда ложусь в три-четыре ночи, потом сплю до 12, просыпаюсь вялый и разбитый, сижу как овощ.
А когда хорошо выспишься, бодро себя чувствуешь, и можно работать хоть 15 часов.
В общем, он наверное имел ввиду что нужно следить за здоровьем и правильным порядком дня, это очень сильно сказывается на умственных способностях.
> Через что выводить эту неправильную часть?
preg_match умеет захватывать найденную часть строки и класть ее в массив, это описано в документации: http://php.net/manual/ru/function.preg-match.php
if (preg_match($rule1, $text, $m)) {
var_dump($m); // найденный текст и его фрагменты
}
Но тут лучше использовать preg_match_all так как preg_match находит только первое совпадение с выражением.
> Решил задачу про номера с большим списком номеров.
Те же замечания что и выше: >>506529
>>506249
>>506251
> mt_rand(0,3)
Это неудобно так как при измеении массива слов надо руками пересчитывать элементы. Сделай чтобы эти числа вычислялись автоматически.
Также для взятия случайного ключа есть функция array_rand.
Также не называй переменные по-русски, используй гуглотранслейт.
>>506349
Он не выводится, ты должен дописать код чтобы выводилось.
>>506375
Мне интересно кто согласится в нее играть? Алсо распределение можно посчитать при желании.
Играть можно только если в казино есть какие-то гарантии вроде хешей или что они там используют, которые можно потом проверить.
>>506403
Зачем писать 1-60 если можно просто писать 60 и ставит ключи по возврастанию?
>>506304
ЧТо входит в курс? Только материалы или например общение и констультации с преподавателем? Если тлько материалы то наверно не стоит так как все можно при желании и так найти.
>>506434
Ошибка из-за того что твоя программа слишком долго работала и ideone ее прибил. Ну сам посмотри, 500 месяцев набежало.
А ошибка из-за опечатки тут:
> for ($mounth=1; $mounth <= 20; $month ++) {
Ты увеличиваешь другую переменную о чем тебе PHP внизу намекает: PHP Notice: Undefined variable: month in /home/kjFsc2/prog.php on line 10
> $creditPercent = 3;
проценты надо делить на 100 так как процент это сотая часть.
Алсо ответ должен быть около 61270.
> Через что выводить эту неправильную часть?
preg_match умеет захватывать найденную часть строки и класть ее в массив, это описано в документации: http://php.net/manual/ru/function.preg-match.php
if (preg_match($rule1, $text, $m)) {
var_dump($m); // найденный текст и его фрагменты
}
Но тут лучше использовать preg_match_all так как preg_match находит только первое совпадение с выражением.
> Решил задачу про номера с большим списком номеров.
Те же замечания что и выше: >>506529
>>506249
>>506251
> mt_rand(0,3)
Это неудобно так как при измеении массива слов надо руками пересчитывать элементы. Сделай чтобы эти числа вычислялись автоматически.
Также для взятия случайного ключа есть функция array_rand.
Также не называй переменные по-русски, используй гуглотранслейт.
>>506349
Он не выводится, ты должен дописать код чтобы выводилось.
>>506375
Мне интересно кто согласится в нее играть? Алсо распределение можно посчитать при желании.
Играть можно только если в казино есть какие-то гарантии вроде хешей или что они там используют, которые можно потом проверить.
>>506403
Зачем писать 1-60 если можно просто писать 60 и ставит ключи по возврастанию?
>>506304
ЧТо входит в курс? Только материалы или например общение и констультации с преподавателем? Если тлько материалы то наверно не стоит так как все можно при желании и так найти.
>>506434
Ошибка из-за того что твоя программа слишком долго работала и ideone ее прибил. Ну сам посмотри, 500 месяцев набежало.
А ошибка из-за опечатки тут:
> for ($mounth=1; $mounth <= 20; $month ++) {
Ты увеличиваешь другую переменную о чем тебе PHP внизу намекает: PHP Notice: Undefined variable: month in /home/kjFsc2/prog.php on line 10
> $creditPercent = 3;
проценты надо делить на 100 так как процент это сотая часть.
Алсо ответ должен быть около 61270.
> for ($i=1; $i<=$halfLength; $i++)
> \t$letter1 = mb_substr($text, $i, 1);
Буквы в PHP нумеруются с нуля, чтобы получить первую букву $i должно равняться нулю. Ну и как тебе советуют, выводи какие именно буквы ты сравниваешь на каждом шаге.
>>506551
Сытое брюхо к учению глухо. Сытый кот мышей не ловит.
Собираюсь покупать хостинг, чтобы ИННОБ дб опробовать.
Смотря к чему тебя тянет.
Это то же самое что спрашивать: мне сегодня рыбу или мясо на ужин съесть?
Скачал XAMPP, написал сайт на пхп, а он из мускля не хочет правильно показывать русские буквы.
my.ini
# Example MySQL config file for medium systems.
#
# This is for a system with little memory (32M - 64M) where MySQL plays
# an important part, or systems up to 128M where MySQL is used together with
# other programs (such as a web server)
#
# You can copy this file to
# /etc/my.cnf to set global options,
# mysql-data-dir/my.cnf to set server-specific options (in this
# installation this directory is @localstatedir@) or
# ~/.my.cnf to set user-specific options.
#
# In this file, you can use all long options that a program supports.
# If you want to know which options a program supports, run the program
# with the "--help" option.
# The following options will be passed to all MySQL clients
[client]
#user \t= your_username
#password = your_password
host = .
port\t\t= 3306
socket\t\t= "MySQL"
# Here follows entries for some specific programs
# The MySQL server
[mysqld]
basedir = "/Documents/Dropbox/web/xampp/mysql/"
datadir = "/Documents/Dropbox/web/xampp/mysql/data/"
port\t\t = 3306
socket\t\t = "MySQL"
skip-locking
key_buffer = 16M
max_allowed_packet = 1M
table_cache = 64
sort_buffer_size = 512K
net_buffer_length = 8K
read_buffer_size = 256K
read_rnd_buffer_size = 512K
myisam_sort_buffer_size = 8M
default-character-set=utf8
default-time-zone = "Europe/Moscow"
log_error = "/Documents/Dropbox/web/xampp/mysql/data/mysql.err"
pid_file = "mysql.pid"
general_log = 0
general_log_file = "/Documents/Dropbox/web/xampp/mysql/data/mysql.log"
slow_query_log = 0
slow_query_log_file = "/Documents/Dropbox/web/xampp/mysql/data/mysql-slow.log"
# Don't listen on a TCP/IP port at all. This can be a security enhancement,
# if all processes that need to connect to mysqld run on the same host.
# All interaction with mysqld must be made via Unix sockets or named pipes.
# Note that using this option without enabling named pipes on Windows
# (via the "enable-named-pipe" option) will render mysqld useless!
#
#skip-networking
enable-named-pipe
# Disable Federated by default
skip-federated
# Replication Master Server (default)
# binary logging is required for replication
#log-bin = mysql-bin
# binary logging format - mixed recommended
#binlog_format = mixed
# required unique id between 1 and 2^32 - 1
# defaults to 1 if master-host is not set
# but will not function as a master if omitted
server-id = 1
# Replication Slave (comment out master section to use this)
#
# To configure this host as a replication slave, you can choose between
# two methods :
#
# 1) Use the CHANGE MASTER TO command (fully described in our manual) -
# the syntax is:
#
# CHANGE MASTER TO MASTER_HOST=<host>, MASTER_PORT=<port>,
# MASTER_USER=<user>, MASTER_PASSWORD=<password> ;
#
# where you replace <host>, <user>, <password> by quoted strings and
# <port> by the master's port number (3306 by default).
#
# Example:
#
# CHANGE MASTER TO MASTER_HOST='125.564.12.1', MASTER_PORT=3306,
# MASTER_USER='joe', MASTER_PASSWORD='secret';
#
# OR
#
# 2) Set the variables below. However, in case you choose this method, then
# start replication for the first time (even unsuccessfully, for example
# if you mistyped the password in master-password and the slave fails to
# connect), the slave will create a master.info file, and any later
# change in this file to the variables' values below will be ignored and
# overridden by the content of the master.info file, unless you shutdown
# the slave server, delete master.info and restart the slaver server.
# For that reason, you may want to leave the lines below untouched
# (commented) and instead use CHANGE MASTER TO (see above)
#
# required unique id between 2 and 2^32 - 1
# (and different from the master)
# defaults to 2 if master-host is set
# but will not function as a slave if omitted
#server-id = 2
#
# The replication master for this slave - required
#master-host = <hostname>
#
# The username the slave will use for authentication when connecting
# to the master - required
#master-user = <username>
#
# The password the slave will authenticate with when connecting to
# the master - required
#master-password = <password>
#
# The port the master is listening on.
# optional - defaults to 3306
#master-port = <port>
#
# binary logging - not required for slaves, but recommended
#log-bin = mysql-bin
# Point the following paths to different dedicated disks
tmpdir\t\t = "/Documents/Dropbox/web/xampp/tmp/"
#log-update = "/Documents/Dropbox/web/xampp/tmp/mysql"
# Uncomment the following if you are using InnoDB tables
#skip-innodb
innodb_data_home_dir = "/Documents/Dropbox/web/xampp/mysql/data/"
innodb_data_file_path = ibdata1:10M:autoextend
innodb_log_group_home_dir = "/Documents/Dropbox/web/xampp/mysql/data/"
# You can set .._buffer_pool_size up to 50 - 80 %
# of RAM but beware of setting memory usage too high
innodb_buffer_pool_size = 16M
innodb_additional_mem_pool_size = 2M
# Set .._log_file_size to 25 % of buffer pool size
innodb_log_file_size = 5M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 50
[mysqldump]
quick
max_allowed_packet = 16M
[mysql]
no-auto-rehash
# Remove the next comment character if you are not familiar with SQL
#safe-updates
default-character-set=utf8
[isamchk]
key_buffer = 20M
sort_buffer_size = 20M
read_buffer = 2M
write_buffer = 2M
[myisamchk]
key_buffer = 20M
sort_buffer_size = 20M
read_buffer = 2M
write_buffer = 2M
[mysqlhotcopy]
interactive-timeout
В настройках базы данных и таблице везде поставил utf8, файл скрипта в utf8 без ВОМ, а он мне какую-то херню пишет, что-то вроде текста в latin1 (cp1252), но отображаемом как utf8.
Или посоветуйте, пожалуйста, сборку апач+пхп+мускл.
Скачал XAMPP, написал сайт на пхп, а он из мускля не хочет правильно показывать русские буквы.
my.ini
# Example MySQL config file for medium systems.
#
# This is for a system with little memory (32M - 64M) where MySQL plays
# an important part, or systems up to 128M where MySQL is used together with
# other programs (such as a web server)
#
# You can copy this file to
# /etc/my.cnf to set global options,
# mysql-data-dir/my.cnf to set server-specific options (in this
# installation this directory is @localstatedir@) or
# ~/.my.cnf to set user-specific options.
#
# In this file, you can use all long options that a program supports.
# If you want to know which options a program supports, run the program
# with the "--help" option.
# The following options will be passed to all MySQL clients
[client]
#user \t= your_username
#password = your_password
host = .
port\t\t= 3306
socket\t\t= "MySQL"
# Here follows entries for some specific programs
# The MySQL server
[mysqld]
basedir = "/Documents/Dropbox/web/xampp/mysql/"
datadir = "/Documents/Dropbox/web/xampp/mysql/data/"
port\t\t = 3306
socket\t\t = "MySQL"
skip-locking
key_buffer = 16M
max_allowed_packet = 1M
table_cache = 64
sort_buffer_size = 512K
net_buffer_length = 8K
read_buffer_size = 256K
read_rnd_buffer_size = 512K
myisam_sort_buffer_size = 8M
default-character-set=utf8
default-time-zone = "Europe/Moscow"
log_error = "/Documents/Dropbox/web/xampp/mysql/data/mysql.err"
pid_file = "mysql.pid"
general_log = 0
general_log_file = "/Documents/Dropbox/web/xampp/mysql/data/mysql.log"
slow_query_log = 0
slow_query_log_file = "/Documents/Dropbox/web/xampp/mysql/data/mysql-slow.log"
# Don't listen on a TCP/IP port at all. This can be a security enhancement,
# if all processes that need to connect to mysqld run on the same host.
# All interaction with mysqld must be made via Unix sockets or named pipes.
# Note that using this option without enabling named pipes on Windows
# (via the "enable-named-pipe" option) will render mysqld useless!
#
#skip-networking
enable-named-pipe
# Disable Federated by default
skip-federated
# Replication Master Server (default)
# binary logging is required for replication
#log-bin = mysql-bin
# binary logging format - mixed recommended
#binlog_format = mixed
# required unique id between 1 and 2^32 - 1
# defaults to 1 if master-host is not set
# but will not function as a master if omitted
server-id = 1
# Replication Slave (comment out master section to use this)
#
# To configure this host as a replication slave, you can choose between
# two methods :
#
# 1) Use the CHANGE MASTER TO command (fully described in our manual) -
# the syntax is:
#
# CHANGE MASTER TO MASTER_HOST=<host>, MASTER_PORT=<port>,
# MASTER_USER=<user>, MASTER_PASSWORD=<password> ;
#
# where you replace <host>, <user>, <password> by quoted strings and
# <port> by the master's port number (3306 by default).
#
# Example:
#
# CHANGE MASTER TO MASTER_HOST='125.564.12.1', MASTER_PORT=3306,
# MASTER_USER='joe', MASTER_PASSWORD='secret';
#
# OR
#
# 2) Set the variables below. However, in case you choose this method, then
# start replication for the first time (even unsuccessfully, for example
# if you mistyped the password in master-password and the slave fails to
# connect), the slave will create a master.info file, and any later
# change in this file to the variables' values below will be ignored and
# overridden by the content of the master.info file, unless you shutdown
# the slave server, delete master.info and restart the slaver server.
# For that reason, you may want to leave the lines below untouched
# (commented) and instead use CHANGE MASTER TO (see above)
#
# required unique id between 2 and 2^32 - 1
# (and different from the master)
# defaults to 2 if master-host is set
# but will not function as a slave if omitted
#server-id = 2
#
# The replication master for this slave - required
#master-host = <hostname>
#
# The username the slave will use for authentication when connecting
# to the master - required
#master-user = <username>
#
# The password the slave will authenticate with when connecting to
# the master - required
#master-password = <password>
#
# The port the master is listening on.
# optional - defaults to 3306
#master-port = <port>
#
# binary logging - not required for slaves, but recommended
#log-bin = mysql-bin
# Point the following paths to different dedicated disks
tmpdir\t\t = "/Documents/Dropbox/web/xampp/tmp/"
#log-update = "/Documents/Dropbox/web/xampp/tmp/mysql"
# Uncomment the following if you are using InnoDB tables
#skip-innodb
innodb_data_home_dir = "/Documents/Dropbox/web/xampp/mysql/data/"
innodb_data_file_path = ibdata1:10M:autoextend
innodb_log_group_home_dir = "/Documents/Dropbox/web/xampp/mysql/data/"
# You can set .._buffer_pool_size up to 50 - 80 %
# of RAM but beware of setting memory usage too high
innodb_buffer_pool_size = 16M
innodb_additional_mem_pool_size = 2M
# Set .._log_file_size to 25 % of buffer pool size
innodb_log_file_size = 5M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 50
[mysqldump]
quick
max_allowed_packet = 16M
[mysql]
no-auto-rehash
# Remove the next comment character if you are not familiar with SQL
#safe-updates
default-character-set=utf8
[isamchk]
key_buffer = 20M
sort_buffer_size = 20M
read_buffer = 2M
write_buffer = 2M
[myisamchk]
key_buffer = 20M
sort_buffer_size = 20M
read_buffer = 2M
write_buffer = 2M
[mysqlhotcopy]
interactive-timeout
В настройках базы данных и таблице везде поставил utf8, файл скрипта в utf8 без ВОМ, а он мне какую-то херню пишет, что-то вроде текста в latin1 (cp1252), но отображаемом как utf8.
Или посоветуйте, пожалуйста, сборку апач+пхп+мускл.
У меня в случае с кастомными банкнотами (150, 200, 2000) по этому алгоритму PHP-скрипт искал ответ около 15 секунд. Мне это показалось неадекватным, т.к. даже сложнейшие фреймворки разворачиваются за 1 секунду.
ставь денвир
SET NAMES utf8 после соединения надо использовать, а в таблицах указывать DEFAULT CHARSET utf8.
http://phpfaq.ru/charset
http://www.tmanager.ru/russian/charset.html
http://fstrange.ru/coder/mysql/kodirovka-krakozyably.html
http://gahcep.github.io/blog/2013/01/05/mysql-utf8/
В случае PDO там есть опция charset для этого.
Лучше вместо сборок ставить PHP и Апач руками.
mysql_query('SET NAMES ...
Пробовал, не помогает. В пхпмуадмин все работает правильно, а при подключении из моего скрипта неправильно - субъективное впечатление, что апач все получает от сервера или пердает в пхп в latin1. Где еще есть настройки, которые можно настраивать?
>Нет, ты неправильно мыслишь. Полезнее разрабатывать под виндой чтобы уметь писать кроссплатформенный код, а не код в котором все захардкожено и который ломается при малейших изменениях в окружении.
Не всегда. Если в веб-приложении, например, используются сторонние программы, написанные под прыщи, ты не сможешь их обкатать на винде. Можно, конечно, накостылить, но времени тоже жалко. Ещё один фактор - разные версии PHP - если писать кроссплатформенный код, то так и будешь сидеть на 5.3, когда столько ништяков появилось в новых версиях.
Проанализируй почему. Например залоггируй сколько там и каких элементов создается, сколько времени это занимает и тд.
> если писать кроссплатформенный код, то так и будешь сидеть на 5.3, когда столько ништяков появилось в новых версиях.
Чушь собачья. Под винду есть новые версии PHP, откуда ты взял цифру 5.3? До выхода debian 8 PHP под винду был новее чем под дебиан.
> Если в веб-приложении, например, используются сторонние программы, написанные под прыщи,
Во-первых, они могут быть и под винду ,во-вторых для тетсирования на локалхосте они могут быть не обязательны.
Накостылить — это когда в коде жестко прописываются пути к файлам, программам, домен, ссылки и прочее.
Сделай минимальный скрипт который просто соединяется с базой и одним INSERT без всяких POST, GET, переменных вставляет туда текст на русском. Если он не заработает, скинь его сюда, через файлообменник, например rghost, чтобы можно было проверить кодировку.
>Чушь собачья. Под винду есть новые версии PHP, откуда ты взял цифру 5.3?
Я говорю про реалии, когда клиент тебе даёт ТЗ, в котором написано PHP версии 5.3, или 5.2. Задачками ты на хлеб не заработаешь.
>Во-первых, они могут быть и под винду
>во-вторых для тетсирования на локалхосте они могут быть не обязательны.
Пиздос, могут быть, а могут и не быть.
Инсерт работает, в майадмине все показывает как ввожу. Не работает извлечение.
$li=mysql_connect($hostname, $username, $password) OR DIE("Что-то не работает...");
//mysql_query("SET NAMES utf8");
mysql_select_db($dbName, $li);
//mysql_set_charset( 'utf8' );
$query = "SELECT * FROM reviews";
$result = MYSQL_QUERY($query);
$number = MYSQL_NUMROWS($result);
$i = 0;
if ($number == 0) {
} elseif ($number > 0) {
WHILE ($i < $number){
$name = mysql_result($result,$i,"name");
$review = mysql_result($result,$i,"review");
$datetime = mysql_result($result,$i,"date");
echo $datetime . " " . htmlentities($name) . "</br> \n";
//echo iconv("UTF-8", "Windows-1251", htmlentities($review)) . "</br>";
echo htmlentities($review) . "</br>\n";
$i++;
}
}
чарсет и сет неймс закомментированы, без них впечатление, что апач получает все правильно, но обращается с текстом как с кодировкой latin1, хотя там utf, а с ними тоже кракозябры, но подбор кодировки от лебедева уже не может подобрать ничего.
Инсерт работает, в майадмине все показывает как ввожу. Не работает извлечение.
$li=mysql_connect($hostname, $username, $password) OR DIE("Что-то не работает...");
//mysql_query("SET NAMES utf8");
mysql_select_db($dbName, $li);
//mysql_set_charset( 'utf8' );
$query = "SELECT * FROM reviews";
$result = MYSQL_QUERY($query);
$number = MYSQL_NUMROWS($result);
$i = 0;
if ($number == 0) {
} elseif ($number > 0) {
WHILE ($i < $number){
$name = mysql_result($result,$i,"name");
$review = mysql_result($result,$i,"review");
$datetime = mysql_result($result,$i,"date");
echo $datetime . " " . htmlentities($name) . "</br> \n";
//echo iconv("UTF-8", "Windows-1251", htmlentities($review)) . "</br>";
echo htmlentities($review) . "</br>\n";
$i++;
}
}
чарсет и сет неймс закомментированы, без них впечатление, что апач получает все правильно, но обращается с текстом как с кодировкой latin1, хотя там utf, а с ними тоже кракозябры, но подбор кодировки от лебедева уже не может подобрать ничего.
Все там в utf8, ебусь с этим уже второй день.
http://rghost.ru/6rMPVJlRJ
Знаний языков программирования, js, MySQL и всего остального - ноль.
Инсерт и моим скриптом и майадмином работает правильно. Кажется мне, косяк между апачем и мускулем, но я вообще не знаю как эта херня работает, скажите где настройки кодировок апача и пхп?
У тебя какого рода сайт планируется? Какой-то уникальный сервис, который ты готов предложить? Или обычная хуйня с контентом из статей/фоточек/картиночек/видосов? Если второе, то может быть тебе глянуть в сторону wordpress? Это и есть как раз готовый движок для подобных задач. На нем бложик или сайт несколькими страничками сделать очень просто, и для этого он собственно и написан.
Логично предположить, раз муадмин все правильно показывает, то проблема во мне и моем скрипте, но я перепробовал все в разных комбинациях, я в тупике.
Попробуй ещё в самом php файле кодировку header'ом прописать. И попробуй поменять на UTF8+БОМ.
>В какой-нибудь подвальной веб-студии этих знаний хватит
Ты имеешь ввиду курс кодакадеми? Или нашу элитную школу?
Мне кажется, материал, предоставляемый тобой крут. Чтобы попасть в яндекс, конечно, нужно еще нехило знать всякий матан, а по части кодинга я думаю знания, полученные по твоему учебнику и твоим же рекомендациям и наставлениям отличные!
Ты про вывод в страницу <meta http-equiv="Content-Type" content="text/html" charset="utf-8"/>
? Это делаю. БОМ добавлял, изменений не заметил, хотя, как я понял из форумов, должен был интерпретатор ругаться. Да, у меня win xp и портативная сборка xampp, васян едишон.
> когда клиент тебе даёт ТЗ, в котором написано PHP версии 5.3, или 5.2
И по моему под винду эту версию PHP поставить куда как проще чем под линукс. Не понимаю, при чем тут этот аргумент вообще, если мы говорили о кроссплатформенности.
>>506675
Поставь в начало скрипта
header("Content-Type: text/plain; charset=utf-8");
Раскомментируй SET NAMES utf8. Удали htmlentitites.
Если все отобразится верно значит с базой все в порядке все работает как надо а проблема в том что ты написал или скопировал неправильный код.
Также, расширение mysql давно устарело (открй мануал PHP и посомтри сам). Почему ты не хочешь изучить что-нибудь посовременнее, а вместо этого притащил сюда этот древний хлам?
Домен надо купить или получить бесплатный и натсроить чтобы указывал на твой IP. На машине поднять Апач и выложит туда HTML или PHP файлы.
>Почему ты не хочешь изучить что-нибудь посовременнее, а вместо этого притащил сюда этот древний хлам?
Потому что у меня икс пи, сломанная видеокарта, старый ноутбук. Сейчас попробую хидер. Спасибо.
>Потому что у меня икс пи, сломанная видеокарта, старый ноутбук
Лол, а ничего, что mysqli, которым насильно заменяют, mysql, работает быстрее и потребляет меньше ресурсов, потому им и заменяют, собственно.
set charset
Либо ты сделал что-то неправильно, не как я написал, либо у тебя данные в базе непраильные, а phpmyadmin их отображает из-за каких-то хитрых настроек.
Ты с таким подходом ничему не научишься. Если ты наткнулся на прлоблему надо понять почему она возникла а не переустанавливать версии PHP. Программирование так не работает.
ОП, я могу использовать oferflow:auto для того чтобы избавиться от схлопывания отступов?
Я помню что ты когда-то агрился на overflow, но не помню почему.
Мержевич еще говорит, что можно использовать clear для отмены схлопывания, но у меня что-то не работает.
http://htmlbook.ru/samlayout/blochnaya-verstka/skhlopyvayushchiesya-otstupy
Нет, не можешь. overflow: auto значит что при вываливании содержимого за пределы блока появляются линейки прокрутки. Больше ни для чего его использовать не надо.
Для борьбы с маргин коллапсингом достаточно добавить бордер или однопиксельный паддинг.
Мне эти способы показались самыми костыльными. Зачем мне padding, пусть даже еле заметный? Зачем мне бордер? Рамку подгонять по цвету к бэкграунду?
Ну ладно, сделаю паддинг. Надеюсь этот 1px мне потом боком не вылезет.
Иначе бывают такие вот истории, чуть человека не убило: http://www.fontanka.ru/2015/06/30/169/
Ну и еще меня конечно удивляет почему у этих аппаратов открытые винты и много острых краев, можно же их хотя бы закрыть как-то. Совсем не думают о безопасности.
text-align теперь похерился.
Короче обойдусь overflow: auto.
Твоя критика использования этого свойства показалась мне недостаточно убедительной.
Ну и где мне почитать про css, чтобы хорошо объяснялись именно принципы действия тех или иных свойств?
Ты же сам видишь, что у того же Мержевича тупо дается перечень рецептов: поставь паддинг, сделай оверфлоу и т.д.
Книжку не посоветуете, или курсы? (бесплатные, естественно, я не идиот чтобы платить за знания)
Вот нашел статью про коллапсиснг: http://softwaremaniacs.org/blog/2005/09/05/css-layout-flow-margins/
Твоя ссылка тоже вполне подробная, вот эта http://htmlbook.ru/samlayout/blochnaya-verstka/skhlopyvayushchiesya-otstupy
Средств борьбы с коллапсингом немного: паддинг, бордер, убрать маргины и по моему все.
Они все основаны на том, что коллапсинг работает только при соблюдении нескольких условий и эти методы нарушают одно из условий.
Условия, если тебе важен первоисточник, описаны в стандарте: http://www.w3.org/TR/css3-box/#collapsing-margins
inline-block не решение так как его поведение сильно отличается от block и ломает верстку.
На мой взгляд добавление паддинга лучше так как не имеет никаких побочных последствий. Ну и между блоками в любом случае есть какое-то расстояние, так что паддинг проблем не должен добавлять.
Разумеется про этот паддинг надо помнить при верстке дургих элементов.
Оверфлоу имеет тот побочный эффект что например длинное слово или картинка могут вызвать появление линейки прокрутки.
> что у того же Мержевича тупо дается перечень рецептов: поставь паддинг, сделай оверфлоу
Если ты возьмешь условия из стандарта и попробуешь их нарушить то получишь тот же список.
Раз ты заскучал, можешь глянуть мой файлообменник.
Там особо ничего нового, я занимался только исправлениями твоих замечаний. >>502176
Так что это не к спеху.
https://github.com/nsdvw/file-sharing
Не успел только формирование ссылок через методы.
На полные пространства имен не обращай внимания. Я еще не научился использовать архисложное импортирование через use (тест на сарказм).
Сижу читаю про jplayer.
Подключить модулек x-sendfile ради счетчика скачиваний.
Еще нужно сделать загрузку файлов аяксом.
Переделать таблицы с информацией о файлах в дивы (ради адаптивной верстки).
Что еще можно сделать? А то даже месяца не потратил на файлообменник.
Информацию о файле еще можно верстать с помощью списков dd/dl/dt
Но вообще я бы советовал посмотреть статью: https://css-tricks.com/responsive-data-tables/
Средствами CSS можно сделать td/table не-таблицей. В CSS можно почти любой тег переопределить, разве что кроме элементов форм.
Но я посмотрел скриншоты, вот я не уверен что это хорошая идея ту таблицу вытягивать в высоту, ты же замучаешься ее прокручивать. Разве не удобнее обычная таблица, которую можно приблизить и такскать по экрану? У кого есть смартфон, расскажите, как вам было бы удобнее?
В твоем случае впрочем адаптивность имеет смысл, таблица у тебя не большая и вертикально она может быть будет смотреться лучше.
Ах да, надеюсь ты там th не забыл использовать для заголовков?
>добавление паддинга лучше так как не имеет никаких побочных последствий
Имеет. У меня там подвал прикрепленный к низу сраницы.
Это реализовано через отрицательный маржин, на котором все завязано. Смотри стили для footer, #wrapper и #content.
https://github.com/nsdvw/file-sharing/blob/master/public_html/css/main.css
Если я начну делать паддинги с бордерами у подвала, это увеличит его высоту, потянет за собой изменение margin-bottom у wrapper и padding-bottom у #content.
Лессы-сассы я точно сюда не буду прикручивать ради того чтобы связать эти числа.
>Оверфлоу имеет тот побочный эффект что например длинное слово или картинка могут вызвать появление линейки прокрутки.
Только если жоско задана высота. Если высота бесконечна, то overflow безобиден.
>>506863
>я посмотрел скриншоты
Это где их можно посмотреть?
Да, th для шапки таблицы. Можно еще наверное thead и tbody добавить для кошерности.
>У кого есть смартфон
У меня нокиа н70, можно школьников пугать.
> Лессы-сассы я точно сюда не буду прикручивать ради того чтобы связать эти числа.
Руками можно прибавить.
> Только если жоско задана высота. Если высота бесконечна, то overflow безобиден.
Ты можешь не уложиться по ширине которая конечна.
>>я посмотрел скриншоты
> Это где их можно посмотреть?
В статье на css-tricks
>Ты можешь не уложиться по ширине которая конечна.
Тогда overflow-y.
Я имел ввиду не сводную большую таблицу по всем файлам, а для характеристик конкретного, detailView. Пикрелейтед.
Ее пожалуй можно заменить дивами. Тогда и оформление будет легче.
Сейчас там кросс-браузерная ерунда для этих несчастных четырех скругленных уголков.
tr:last-child td:first-child {
border-bottom-left-radius: 10px;
-webkit-border-bottom-left-radius: 10px;
-moz-border-radius-bottomleft: 10px;
}
Не, на дивах нет border-сollapse и c ними мне кажется, сложнее будет. (ну то есть ты можешь сделать display: table но это будет странно). А для маленьких экранов ты можешь переформатировать таблицу вертикально.
В разрешении лучше вместо буквы x использовать значок × который вставляется через ×
А, ну и ладно, мне же меньше работы. Еще вопрос по поводу генерации превью, посмотри потом насколько оптимальное я придумал решение.
В принципе это апач должен сигнализировать о том, что превью не существует и через модреврайт дернуть скрипт с генератором.
Но у меня немного иначе: в при обращении к конкретному маршруту php проверяет file_exists(превью), и если его нет нет то дергает метод генератора.
Вроде тоже почти нет лишних телодвижений. Я не думаю, что file_exists пожрет слишком много ресурсов или много времени.
Нужно ли при подставлении значений переменных в SQL-код приводить эти значения к нужному типу? Если с int, varchar и им подобным всё ясно, то как быть, например, с enum?
Надо ли писать что-то вроде:
$stmt = $pdo->prepare("INSERT INTO abiturients(sex, local) VALUES(ENUM :sex, BIT :local)");
$stmt->bindvalue(':sex', $abiturient->sex);
$stmt->bindvalue(':local', $abiturient->local);
Пикрилейтед - моя таблица.
Enum это обычный набор строк, только значения
Значения в bindValue приводятся с помощью третьего аргумента, предопределенной pdo константы.
$stmt->bindValue(':sex', $abiturient->sex, PDO::PARAM_STR);
http://php.net/manual/ru/pdostatement.bindvalue.php
>Значения в bindValue приводятся с помощью третьего аргумента, предопределенной pdo константы.
Да, я в курсе, но там только PARAM::STR и PARAM::INT.
Значит ли это, что достаточно лишь указать, строковое значение или числовое, а дальше MySQL всё заботливо сделает за меня?
ENUM надо передавать как строку и ни в коем случае не как число, иначе будут трудноотлаживаемые баги.
>>506905
Нет, в запросе ты пишешь строку.
>>506906
>>506910
Кроме константы надо привести значение к нужному типу через intval/strval, иначе она не сработает.
$x->bindValue(':x', intval($x), PDO::...);
https://web.telegram.org/#/im?p=@mew_bot
Я хуею товарищи, на хостинге минимальная оплата за три мес - тыща ебаных рублей. блеаааа. я могу забыть про свои таблицы.
Пиздос, а почему я тогда плачу 1200 рублей в год за хостинг для своих 5 сайтов?
>Junior
>90000
>Опыт работы с фреймворками будет большим преимуществом.
Чот игранул)))))
Это модная замена слова "зарплата".
чо за хостинг?
Может кто-нибудь объяснить, почему оно работает так? Наркомания какая-то.
Попробуйте пораскомменчивать кейсы.
https://ideone.com/8x5DiR
character_set_client utf8
character_set_connection utf8
character_set_database utf8
character_set_filesystem binary
character_set_results utf8
character_set_server utf8
character_set_system utf8
character_sets_dir \usr\local\mysql-5.5\share\charsets\
Использую notepad++, русский текст из файла, вида echo "бла бла" выводится нормально, в бд в майадмине добавил руками запись русскими буквами - из скрипта выводится кракозябрами. Что не так с этим говном/мной/ОС?
OC Win XP, денвер последний доступный с оф сайта.
До этого такая же проблема была с XAMPP и портабельным денвером от васяна.
С BOM попробуй.
вот поэтому нам нужно переводить рузке на латиницу.
>echo var_dump
var_dump и так выводит данные на экран, echo тут не нужно.
А что тебе непонятно? Что ты вообще хотел сделать?
foreach ($obj as $property => $value) {
\techo var_dump($property);
Тут перебираются все свойства объекта (name, surname, email) в цикле. var_dump у тебя выводит ключ, то есть название свойства. На первой итерации выведет name, на второй surname, на третьей email.
switch ($property) {
case "name":
case "surname":
$obj->$property = 'Василий';
echo var_dump($obj->$property);
case 'email':
\t$obj->$property = 'Иван';
Поскольку не указан break, то выполнится не только блок соответствующий условию, но и все нижележащие. Почитай как работает switch, там обязательно нужно указывать break, иначе продолжат выполняться следующие блоки.
Я плачу 4,5к в год. Дисковое пространство — 250 Gb. Брат доволен. GoDaddy
>на хостинге минимальная оплата за три мес
Щито? Когда я был школьником, то платил 100 рублей в месяц, а сайт выдерживал 15к хостов в день.
НУЖЕН ВИЗИОНЕР. НЕОБХОДИМАЯ ЭКСПЕРТИЗА 5 ЛЕТ
Почему-то не хочет заменять картинку на скрипт.
Упрямо открывает картинку в браузере, и все.
RewriteRule ^images/image.jpeg$ index.php
Что интересно, когда подсунул ему txt, прекрасно все работает.
RewriteRule ^images/hello.txt$ index.php
Я в ступоре, если честно. Что вообще творится?
Нет, дело не в этом.
Пусть будет
RewriteRule ^images/image.png$ index.php
И даже если бы файла не существовало, то он все равно должен быть подменен на index.php.
Упс, уже работает. Очень странно. Может это было какое-то кеширование?
Ладно, извиняюсь за бесполезные посты.
<div><img src='1.jpg'></div>
<div><img src='2.jpg'></div>
<div><img src='3.jpg'></div>
и так далее, т.е получается такая лента из картинок. Как сделать, что бы при нажатие на картинку(напр под номером i), на её место скролилась картинка под номером i+1, т.е лента сдвигалась и на месте первой картинки была вторая
С помощью JS. На клик событие вешаешь и удаляешь первую картинку, вместо нее вторая автоматически встанет.
Сейчас тебе макаки скажут про джаваскрипт, но ты не слушай их, это безработный скам.
Сделай вот что: помести картинки в ссылку
<div><a href="#img2"><img src='1.jpg' id="img1"></div>
<div><a href="#img3"><img src='2.jpg' id="img2"></div>
Так средствами только настоящего первородного PHP мы скролим страницу куда хотим и вертим на хую скрипто-мака.
Только не средствами PHP, а средствами HTML. Это хорошая идея (за счет простоты), только конечно не для всех слуаев подойдет (засоряется история браузера, нельзя плавно прокрутить или применить анимацию).
И при клике на ссылку с якорем экран будет скролиться на ссылку, что тебе ещё нужно?
Как?
>картинка встает к верху экрана
Она встает не кверху экрана, а туда, куда ты укажешь anchor в ссылке. Можешь и по центру разместить.
Нет, браузер прокручивается так чтобы anchor касался верхнего края страницы.
Алсо, мне кажется этот анон сам не понимает то надо и занимется ерундой. Зачем прокручивать страницу при клике? Колесом мыши это делать гораздо удобнее.
Может он хочет сделать такой слайдер. Где вместо стрелок будут картинки: нажимаешь на ту, что с края, и она двигается ближе к центру, а на её место встает следующая.
Да, не дописал, должно быть так: кликаешь на картинку на её место всаёт следующая и т.д Просто у меня по 300 картинок на странице и скролить их заебёшься, я попробовал с html якорями сделать, стало удобнее, но они в верх экрана встают.
>Поскольку не указан break, то выполнится не только блок соответствующий условию, но и все нижележащие.
Спасибо.
Тоже борюсь с прокрастинацией.
Написал вчера ~100 строчек кода. А 3 дня до этого ничего не писал.
Братишьь, такая же хуйня, но не в такой сильной форме.
Сколько уже учишь, какой инпут твой вообще по жизни?
[0-9]+x[0-9]+
>>507387
Нельзя, надо обязательно массив.
Учу год с чем-то. Ну как учу, бывает рабочее настроение и я могу каждый день кодить, но такое довольно редко, в основном по часу в день а то и в неделю. Хотя вроде совсем чуть чуть осталось, доделать превьюшки, начать файлообменник и можно работату искать, но я с каждой задачей становлюсь все ленивее. Видимо свою роль играет подсознательный страх фейла.
>Что отвечают кандидатам на вакансию в Aviasales (нет, не про перезвоним): http://m.siliconrus.com/2015/07/kalinov-hr/
Я потёк. Че-то как-то не очень. Унижать людей можно и без брани. Ему стоит у Тёмы поучиться умеренному и уместному использованию нецензурной лексики.
А по делу, наверное, прав.
Можно и без exists обойтись. Первый запрос вернет empty set (null), если записи нет в базе.
Нет, неправильно. EXISTS предназначен не для этог, он для подзапросов (и то, джойны работают лучше, а подзапрсоы лучше вообще не использовать). Чтобы проверить наличие записи в таблице есть
SELECT COUNT(x) FROM ...
Могу порекомендовать тебе задачки на SQL из Оп-поста, они тебя и не такому научат.
И кстати что значит passcode? Ты явно смотрел на чей-то код и у него не думаю скопировл это название. Там нет никаких паролей, а код это просто код или токен доступа.
$stmt->execute возвращает не число найденных записей. Он лишь взвращает успешно выполнен запрос или нет.
Чтобы полуить число записей надо например использовать fetchColumn
xsendfile
Выдает ошибку
No such file or directory: [client 127.0.0.1:43804] xsendfile: cannot open file: /upload/picture.png
Что нужно указать в XSendFilePath, чтобы оно заработало?
Пробовал абсолютный путь, не помогает
No such file or directory: [client 127.0.0.1:43787] xsendfile: cannot open file: redirect:/upload/picture.png
(решаю задачу про палиндром, хочу сделать её через массив. Строку пихаю в массив, циклом меняю порядок букв, сравниваю в итоге две строки)
<?php
error_reporting(-1);
mb_internal_encoding('utf-8');
$text = "Аргентина манит негра";
$text = mb_strtolower($text);
$text = str_replace(" ", "", $text);
$letters = mb_strlen($text);
$array = str_split($text);
var_dump($array);
?>
А это еще что? Я слеш добавил в начало.
The given path was above the root path: [client 127.0.0.1:43921] xsendfile: unable to find file: /upload/picture.png
> cannot open file: /upload/picture.png
Ну так такого файла нет, о чем тебе и пишут.
Судя по мануалу https://tn123.org/mod_xsendfile/ если путь указан абсолютный то он и рассматривается как абсолютный, то есть не относительно веб-директории а относительно корня файловой системы.
Соответственно надо передавать правильный путь, например
/var/www/example.com/upload/file.txt
>>507585
так не пойдет. Ты просто ставишь команды наугад в надежде что заработает. Программирование так не работает.
1) выполни запрос руками и посмотри что он возвращает в случае если email есть и если нет
2) прочти мануал по всем функциям fetch которые есть в PDO (fetch, fetchAll и тд), разберись что и в каком виде они возвращают и выбери нужную
3) посмотри что она возвращает с помощью var_dump
4) напиши код
странно, провел эксперимент, создал массив циклом for, он вывелся по-человечески, наверное, с той командой str_split косяк, типа байт-хуяйт или еще какая-нибудь йоба, просветите, плиз.
Написано же, файл за пределами корневой директории.
Воозможно дело в белом списке каталогов который упомянут в мануале:
> You still can only access paths that are whitelisted.
Тогда надо добавить нужный каталог в белый список.
str_split наверно не совместим с utf-8, урок: https://gist.github.com/codedokode/ff99e357e9860ea169b8
Он генерирует мусор, а ideone ломается от кодов не соответствующих utf-8.
Не используй str_split. Он не разбивает строку на массив букв, а на массив байт-огрызков от букв.
О, прописал родительскую директорию, и ОНО заработало.
>header('X-SendFile: ' . '../upload/' . $name);
А почему родительскую? Что за фигня? Как оно вообще пути смотрит?
>>507591
опчик, блджад, мы и сами видим что как обезьяны прописываем всякую хрень наугад. Но это не из-за того, что мы плохие, а из-за того что у матерей авторов всяких документаций легкое поведение.
Информацию приходится буквально выгрызать, тратить по несколько часов на то, чтобы найти несчастных две строчки.
Если бы не ты, я бы вообще по три дня сидел гадал, как сделать его работать.
Так вот, разрули, как этот xsendfile ищет пути, как их мне тут прописывать? Я ничего не понимаю.
>>507594
Погоди, начинаю догадываться. У меня там запрос типа /download/image.name подменивается на /upload/image.name, следовательно он наверное берет относительный путь от /download, поэтому надо подняться на уровень выше.
Хрень какая-то.
Сам вижу, что нет понимания. Знал бы как исправить этот пробел, исправил бы.
жаль(( потому что в моих маня-мечтах задача про палиндром с этой командой выглядела изящней, чем сейчас
http://ideone.com/wEgQtn
теперь надо по способу из учебника сделать, а то не очень вкурил в эту строковую функцию.
> Как оно вообще пути смотрит?
Вот мануал: https://tn123.org/mod_xsendfile/
Там есть раздел Remarks - Relative paths
В нем объяснено как и где ищется.
Если плхо понимаешь английский, есть перевод гуглом:
https://translate.google.com/translate?hl=en&sl=auto&tl=ru&u=https%3A%2F%2Ftn123.org%2Fmod_xsendfile%2F
Прочти для начала.
> Информацию приходится буквально выгрызать, тратить по несколько часов на то,
Мануал PHP доступен на русском. Ничего выгрызать не надо, надо просто сесть и не спеша разобраться.
Можно разбить строку на буквы таким хаком:
$array = preg_split('//u', $text, null, PREG_SPLIT_NO_EMPTY);
Пустое регулярное выражение // соответствует промежуткам между буквами и разбивает строку на буквы + 2 пстых куска с краев которые удаляются флагом NO_EMPTY
точно, в глаза ебался, когда урок читал, спасибо
Я два раза прочитал. Да и не в этом дело. xsendfile мы тупо указываем, из каких папок можно отдавать файлы, а из каких нельзя.
У меня этот затуп случился с общим пониманием url и http, а не столько xsendfile.
Давай разберем этот пример.
1) DocumentRoot /home/user/www/example.com/public
2) В настройках виртуального хоста
XSendFilePath /home/user/www/example.com/public/upload
3) .htaccess
RewriteRule ^download/([^/]+)/([^/]+)$ index.php
4) header('X-SendFile: ' . '../upload/' . $fileName);
Так вот, как здесь идет разбор полета?
У меня есть переход по ссылке /download/id/image.name
Мод реврайт заставляет апач запустить index.php, где в соответствующем роуте прописан некий путь к файлу.
Вопрос: относительно чего этот путь отсчитывается?
Почему у меня заработало только ../upload/$fileName?
Получается, относительно самой папки upload! В request_uri у нас валяется /upload/image.name, вот он наверное от него и пляшет.
Надо же, как все запутано. Два модуля, куча перенаправлений и подмен урлов. Господи иисусе.
Чтобы сразу прояснить все моменты с путями и урлами подбор тупых вопросов:
1) <img src="images/hello.jpeg"> и <img src="/images/hello.jpeg">
В первом случае путь к картинке будет формироваться относительно текущей директории, не так ли?
То есть если адрес страницы http://example.com/news/index.php, то путь к картинке получится http://example.com/news/images/hello.jpeg
Во втором случае независимо от реферера http://example.com/images/hello.jpeg, я так понимаю, то есть абсолютный.
2) Есть файлы
/app/views/main.tpl
/public/css/main.css
Каков будет правильный путь к main.css из шаблона? ../../public/css/main.css?
> В первом случае путь к картинке будет формироваться относительно текущей директории, не так ли?
Относительно текущего URL, да, верно.
> Во втором случае независимо от реферера
Независимо от пути к текущей странице, да, ты правильно понял.
> Есть файлы
> /app/views/main.tpl
> /public/css/main.css
> Каков будет правильный путь к main.css из шаблона? ../../public/css/main.css?
Где находится шаблон не имеет значения так как браузер смотрит на URL в адресной строке и отсчитывает путь от него, а где ледит файл шаблона знает только сервер а браузер этого не знает.
Так как в твоем вопросе не дан URL страницы то ответить на него невозможно.
>>507649
Потому что COUNT специально придуман для подсчета числа записей, а анон не очень хорошо знает SQL.
>анон не очень хорошо знает SQL
Знал бы хорошо, не сидел бы тут с вами.
Ну, не будь таким педантичным, в случае если mysql не найдет записи по айди, он ведь вернет null, не так ли?
Ладно здесь ему нужно получить булев ответ, есть запись или нет.
Но если мне нужно выдернуть запись по айдишнику, надеюсь ты не будешь настаивать на дополнительном запросе для проверки наличия записи в бд?
Вполне можно ограничиться одним запросом, обернув результат в if
if (!row = $model->findById($id)) {
$controller->redirect('404.html');
}
$controller->render(...);
> $controller->redirect('404.html');
Это грубая ошибка. Редирект не должен использоваться для 404, надо сразу показывать страницу 404 с соответствующим кодом.
Редирект используют когда страница переехала по другому адресу или например после успешной обработки формы.
Твой вариант затирает адрес в адресной строке и более того, не отдает код 404.
Страница 404 должна не просто содержать слова для людей но и код для роботов.
Сорцы показывать не буду, т.к. все равно править что-либо времени нет. Да и заебался я, если честно. Но если какие-то серьезные баги найдете, то сообщите. Поправлю, как время будет.
кун, который месяцок назад создавал http://randomwebm.esy.es/
ОП, посмотри пожалуйста еще раз мой черновой вариант файлообменника, теперь вместо Paris ORM я использую Doctrine 2, ну и поменял чуть структуру директорий и неймспейсы. Стены кода из индекс пхп вынесу в отдельные классы. Подскажи что нужно изменить на данном этапе.
>>507754
Сколько времени ты учился перед тем как начал так делать? И что в каком порядке и по сколько времени учил, если не сложно опиши
Пхп начал месяца два с половиной назад учить. Недельки две поучил синтаксис и порешал базовые задачки ОП-а, потом начал сайт с вебмками делать. Месяц где-то на него убил, потом еще недельку поучил JS/Jquery и начал файлообменник делать, на который недели 3 потратил. Я бы конечно мог все это намного быстрее сделать, но по разным причинам не получается больше 4 часов в день тратить на это дело.
А в хтмл\цсс долго практиковался чтоб руку набить? И по какому курсу учился\что читал?
Сайты симпатичные у тебя получаются, я тоже так хочу
Да не очень. Курс HTML Academy прошел ~год назад и сверстал несколько макетов. Потом забил вообще на все это дело и вот только недавно решил снова за ум взяться. Еще месяцок подлатаю дыры в знаниях и надеюсь возьмут джуном.
В техническом плане они не сложные, такое можно сверстать после прохождения пути html/css в оп-посте. Просто у них приятный дизайн.
На learn.javascript дается какой-то странный код для серверной части приложения.
http://jsfiddle.net/mm74w6t5/
Я так догадываюсь, что это node.js (ну не на php же им было писать этот пример, в самом деле)
Насколько это большая технология? Учить я буду обязательно, только сейчас времени в обрез, поэтому планирую задачи по степени важности.
Ну и пару слов обзора: что оно может, какие преимущества и недостатки у node.js по отношению к тому же php, насколько популярен?
Да, это node.
Расскажу с вершины того, что я вчера кодил на node.js - 10 часов.
1. В ~ 2 раза быстрее php.
2. Без 2-х, 3-х фреймоворков писать код станет тяжеловато, при объемных проектах.
3. Мало хороших разработчиков. Поэтому и не особо популярен для типовых проектов.
4. CALLBACK! CALLBACK EVERYWHERE!
Ага, то есть достаточно эффективная, но не стандартизированная и потому непопулярная технология, я понял, спасибо.
Повременю тогда с ней.
Для сервера пока хватит php, потом может осилю руби.
http://ideone.com/nLnF7K
И вопрос: я хотел прикрутить к этой задаче выбор самого лучшего банка. Думал, засуну в массив, где ключом будет название банка, значением - сумма итогового платежа, а далее перебор. Но остановило меня то, что я не понял, как вытащить наружу имя банка, которое в данном массиве является ключом. Подскажите, пожалуйста.
Переведем в более машинный вид: у тебя есть массив, у которого ключи - это строки, а значения - числа. Нужно найти макс или мин значение и вывести соответствующий ему ключ.
В php есть встроенная функция для поиска ключа по значению array_search.
Вообще полезно посмотреть все встроенные функции, что они делают. Потому что потом начинаешь изобретать хитрый способ, а оказывается что такая функция уже есть.
Для поиска минимального и максимального элемента массива кстати тоже есть функция.
1. Общие свойства товара, название, описание и прочее, в этой таблице в качестве ключей надо сделать поля с id производителя товара и с id категории и с id дополнительных свойств.
2. Производители товара
3. Категории
4. Дополнительные свойства, и вот здесь у меня проблема, как должна быть организована эта таблица, в ней должны быть поля свойство 1, свойство 2, свойство 3 и т.д.? А также поле с id товара из первой таблицы? То есть свойства не должны быть определены чётко, так как они разные для всех товаров из разных категорий, а название свойств уже определяется во время вывода данных из этой таблицы на веб страницу?
Господа, такой вопрос. Кто под какой ОС сидит? Интересуют разработчики среднего-высокого уровня. Где вам удобнее всего работать? Если под юниксом, то название дистра, будьте добры.
Нужно писать так, чтобы работало и на юниксах, и на виндоуз.
Нет, RewriteCond это маска, определяющая, будет ли к данному запросу применено следующее правило RewriteRule.
Condition - условие, при котором будет выполнен RewriteRule, иначе он игнорируется.
Например
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php
При запросе любого "нефайла", отдавать index.php
Документация по mod_rewrite
http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html
>получить путь до файла, исключая сам файл.
%{REQUEST_URI}
Там же все остальные server-variables
http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html
Я знаю, мне нужно такой rewritecond который бы не вызывал скрипт, если папки в котором находится файл не существует.
>>508015
В той статье, да и во всех остальных ничего не написано о том, что в REQUEST_URI путь идет до файла, исключая сам файл. Да и вообще я не могу даже нагуглить конкретный пример на конкретном адресе, что из себя представляет эта переменная. В любом случае я сейчас попробовал поменять %{REQUEST_FILENAME} на %{REQUEST_URI} но это не сработало.
Что-то у меня индек.пхп не запускается на денвере (я их три установил и два апача) в папке локалхост, сам локалхост работает, денверы и апачи включил - перо, шляпа - все иконки есть. что такое блеать?
и еще вопрос по ходу, куда пилить ебучий пхп зенмейт фреймворк? у меня его хостинг еле поднимает.
На компьютере не получится запустить больше одного Апача если они используют один и тот же порт (по умолчанию используют). Ты только создаешь себе проблемы этим.
у меня локалхост работает, апач денверский ща включил. index.php не находит, а он есть сучечка, в папке Z:\home\localhost\www
чому так?
Чтобы проектировать таблицы, надо сначала изучить нормализацию БД. Прочти по ней статьи если не читал. Также прочти про внешние ключи в MySQL если не читал.
> Дополнительные свойства, и вот здесь у меня проблема,
Общераспространенный подход это Entity-Attribute-Value:
id товара | id свойства | целое значение | строковое значение
Также если свойств немного и они никогда не будут добавлться можно попробовать сделать простуб таблицу вида
id товара | свойство 1 | свойство 2 | ... свойство N
Это применимо только когда свойств мало и они не добавляются.
Без грамотно расставленных индексов поиск и выборки из таблиц будут медленными.
> и с id дополнительных свойств.
Неверно, нужно сделать id товара в таблице свойств.
>>508000
Виндоус + дебиан в виртуалке (мне было бы удобнее без него но так как сейчас много маководов то на поддержку винды забивают).
Ну и я слышал макбуки хороши, если у тебя есть на них деньги.
Некоторым линукс нравится, убунта например.
>>508013
> При запросе любого "нефайла", отдавать index.php
Если запрос не указывает на существующий файл, так будет правильнее.
>>508029
> Есть общий класс продукты, у этого класса есть наследники
Не стоит тут применять наследование. Иначе ты что, собрался делать класс для каждого виа товаров? У тебя так скоро будут сотни классов. Сделай один класс Товар и этого хватит. И один маппер товаров.
> (при выборе определённое категории из списка подгружаются остальные остальные поля формы), каким маппером мне всё это обрабатывать?
маппером который отвечает за таблицу свойств товара. Ну то есть ProductPropertiesMapper. Либо если тебе неохота плодить мапперы то ProductMapper.
Алсо, зачем ты пишешь магазин? Для саморазвития?
Если твоя цель не учиться, а зарабатывать деньги то выгоднее взять готовый движок, их десятки, а писать свой это глупая трата времени.
> (при выборе определённое категории из списка подгружаются остальные остальные поля формы),
Эффективнее наверно заложить в страницу список «категория => набор полей» и добавлять эти поля яваскриптом без лищних запросов. Это будет работать быстрее.
Чтобы проектировать таблицы, надо сначала изучить нормализацию БД. Прочти по ней статьи если не читал. Также прочти про внешние ключи в MySQL если не читал.
> Дополнительные свойства, и вот здесь у меня проблема,
Общераспространенный подход это Entity-Attribute-Value:
id товара | id свойства | целое значение | строковое значение
Также если свойств немного и они никогда не будут добавлться можно попробовать сделать простуб таблицу вида
id товара | свойство 1 | свойство 2 | ... свойство N
Это применимо только когда свойств мало и они не добавляются.
Без грамотно расставленных индексов поиск и выборки из таблиц будут медленными.
> и с id дополнительных свойств.
Неверно, нужно сделать id товара в таблице свойств.
>>508000
Виндоус + дебиан в виртуалке (мне было бы удобнее без него но так как сейчас много маководов то на поддержку винды забивают).
Ну и я слышал макбуки хороши, если у тебя есть на них деньги.
Некоторым линукс нравится, убунта например.
>>508013
> При запросе любого "нефайла", отдавать index.php
Если запрос не указывает на существующий файл, так будет правильнее.
>>508029
> Есть общий класс продукты, у этого класса есть наследники
Не стоит тут применять наследование. Иначе ты что, собрался делать класс для каждого виа товаров? У тебя так скоро будут сотни классов. Сделай один класс Товар и этого хватит. И один маппер товаров.
> (при выборе определённое категории из списка подгружаются остальные остальные поля формы), каким маппером мне всё это обрабатывать?
маппером который отвечает за таблицу свойств товара. Ну то есть ProductPropertiesMapper. Либо если тебе неохота плодить мапперы то ProductMapper.
Алсо, зачем ты пишешь магазин? Для саморазвития?
Если твоя цель не учиться, а зарабатывать деньги то выгоднее взять готовый движок, их десятки, а писать свой это глупая трата времени.
> (при выборе определённое категории из списка подгружаются остальные остальные поля формы),
Эффективнее наверно заложить в страницу список «категория => набор полей» и добавлять эти поля яваскриптом без лищних запросов. Это будет работать быстрее.
Очевидно ты думашь что запущен один апач. а запущен другой. Удали все лишнее с компьютера сначала. Также, я советую не использоват сборки, а ставить апач + PHp руками.
>>508139
> куда пилить ебучий пхп зенмейт фреймворк?
Я не понял что значит «куда пилить» и что такое «зенмейт фреймворк».
>>508025
> В той статье, да и во всех остальных ничего не написано о том, что в REQUEST_URI путь идет до файла, исключая сам файл.
Это неверно. Можно открыть документацию и прочесть: http://httpd.apache.org/docs/current/mod/mod_rewrite.html
(по русски очень кратко это написано тут https://beget.ru/articles/htaccess#mod_rewrite )
> REQUEST_URI
> The path component of the requested URI, such as "/index.html". This notably excludes the query string which is available as as its own variable named QUERY_STRING.
Это path из URL, то есть то что идет после адреса хоста и до знака вопроса (если он есть).
> REQUEST_FILENAME
> The full local filesystem path to the file or script matching the request, if this has already been determined by the server at the time REQUEST_FILENAME is referenced. Otherwise, such as when used in virtual host context, the same value as REQUEST_URI. Depending on the value of AcceptPathInfo, the server may have only used some leading components of the REQUEST_URI to map the request to a file.
Очевидно использовать REQUEST_URI для проверки наличия файла нельзя так как имя файла (оно хранится в REQUEST_FILENAME) обычно имеет вид
c:/www/example.com/public/index.html
А REQUEST_URI имеет вид
/index.html
То есть REQUEST+URI это часть URL а не путь к файлу. И использовать с ним флаг -f бессмысленно. По моему это очевидно.
Таким образом это
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php
праивльный код (если конечно твоя цель переписывать все не указывающие на файлы URL чтобы вызывался index.php).
>>508025
> Я знаю, мне нужно такой rewritecond который бы не вызывал скрипт, если папки в котором находится файл не существует.
Изучи как работает mod_rewrite и напиши. Но я бы предостерег тебя от нагромождения сложных конструкций в htaccess, такие вещи лучше делать в коде.
>>508010
> но похоже там другой принцип и он проверяет существует ли файл и является ли он директорией.
Верно
> По этому вместо %{REQUEST_FILENAME} мне надо как-то получить путь до файла, исключая сам файл.
Это можно сделать хитрым использованием регулярки и псевдопеременных %N и $N которые хранят захваченные скобками в регулярке часть URL. Они описаны в документации.
Очевидно ты думашь что запущен один апач. а запущен другой. Удали все лишнее с компьютера сначала. Также, я советую не использоват сборки, а ставить апач + PHp руками.
>>508139
> куда пилить ебучий пхп зенмейт фреймворк?
Я не понял что значит «куда пилить» и что такое «зенмейт фреймворк».
>>508025
> В той статье, да и во всех остальных ничего не написано о том, что в REQUEST_URI путь идет до файла, исключая сам файл.
Это неверно. Можно открыть документацию и прочесть: http://httpd.apache.org/docs/current/mod/mod_rewrite.html
(по русски очень кратко это написано тут https://beget.ru/articles/htaccess#mod_rewrite )
> REQUEST_URI
> The path component of the requested URI, such as "/index.html". This notably excludes the query string which is available as as its own variable named QUERY_STRING.
Это path из URL, то есть то что идет после адреса хоста и до знака вопроса (если он есть).
> REQUEST_FILENAME
> The full local filesystem path to the file or script matching the request, if this has already been determined by the server at the time REQUEST_FILENAME is referenced. Otherwise, such as when used in virtual host context, the same value as REQUEST_URI. Depending on the value of AcceptPathInfo, the server may have only used some leading components of the REQUEST_URI to map the request to a file.
Очевидно использовать REQUEST_URI для проверки наличия файла нельзя так как имя файла (оно хранится в REQUEST_FILENAME) обычно имеет вид
c:/www/example.com/public/index.html
А REQUEST_URI имеет вид
/index.html
То есть REQUEST+URI это часть URL а не путь к файлу. И использовать с ним флаг -f бессмысленно. По моему это очевидно.
Таким образом это
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php
праивльный код (если конечно твоя цель переписывать все не указывающие на файлы URL чтобы вызывался index.php).
>>508025
> Я знаю, мне нужно такой rewritecond который бы не вызывал скрипт, если папки в котором находится файл не существует.
Изучи как работает mod_rewrite и напиши. Но я бы предостерег тебя от нагромождения сложных конструкций в htaccess, такие вещи лучше делать в коде.
>>508010
> но похоже там другой принцип и он проверяет существует ли файл и является ли он директорией.
Верно
> По этому вместо %{REQUEST_FILENAME} мне надо как-то получить путь до файла, исключая сам файл.
Это можно сделать хитрым использованием регулярки и псевдопеременных %N и $N которые хранят захваченные скобками в регулярке часть URL. Они описаны в документации.
> Но остановило меня то, что я не понял, как вытащить наружу имя банка, которое в данном массиве является ключом. Подскажите, пожалуйста.
Можно отсортровать массив нужной функцией сотировки и взять первую пару ключ-значение. Можно, как анон написал, через min и array_search, так наверно проще. Можно тупо несколько if написать.
Считает программа неверно, во втором банке получается около 61270.
Ты каждый месяц добавляешь фиксированный процент, но надо брать процент от суммы долга, который каждый месяц разный.
> 1. В ~ 2 раза быстрее php.
Пруфы будут? Я наблюдал другое, многие библиотеки медленнее так как написаны на JS, а не на Си.
Также, я добавлю недостатки ноды:
— нет многих крутых фич PHP: нормального ООП, тайп-хинтов, код по мере роста неудержимо превращается в лапшу из скобок которую даже автор не может разобрать
— можно сложить массив с числом или объектом
— сложнее запускать код и выгружать на хостинг. Для PHP достаточно обновить страницу в браузере, а для хостинга просто закачать файлы. С нодой все в разы сложнее.
— для ноды вроде до сих пор даже отладчика и профайлера нет (пожалуйста не пишите названия только если вы с ними рабьотали, я изучал этот вопрос некоторое время назад и по моему там все было очень плохо)
— меньше расширений для работы со всякими базами данных например
— меньше библиотек, например уровня доктрины
— меньше фреймворков
— Нет крутых IDE типа PhpStorm
— для PHP идет любой хостинг, для ноды нужен VPS + надо уметь его настраивать и устанавливать софт
— приложение может течь, падать, причем не из-за багов самой ноды, а из-за принятого там стиля написания кода
В общем я бы сказал что это очень молодая технология, необкатанная, со слабой инфраструктурой. Она предназначена для специфичных задач (асинхронные сетевые приложения с небольшим объемом кода и несложной бизнес-логикой).
По сложности освоения на мой взгляд она сложнее PHP если мы имеем в виду не умение написать хелло воррлд, а реальное приложение.
> \t$payout = $sum + $sum × $percent/100 + $commission;
Эта формула повторяется 3 раза. Это перебор. Избавься от повторов.
>>507850
> Мало хороших разработчиков.
Может хорошие разработчики понимают что для типовых проектов больше подходят другие технологии?
>>507822
Тебе не нужна нода для загрузки файла на сервер, он загружается через обычный POST запрос и значит обрабатывается средствами PHP так же как и загруженный через форму.
Если ты загружаешь файл по частям, то PHP тоже может работать с ними, сырые POST-данные доступны в php://:input, также можно слать куски файла как обычные POST переменные.
Если ты плохо понимаешь то, что выше написано, что такое POST запрос и тело запроса то тебе надо изучить HTTP, понять как передаются эти куски файла, прежде чем что-то писать.
Не забудь сделать решение для тех случаев, когда поддержки фоновой загрузки файлов в браузере нет, в этом случае можно слать обычной формой.
>Если ты плохо понимаешь то, что выше написано
Ну я понял, что данные попадут не в массив post, а в некий поток, который наверное можно перехватить file_get_contents и соответственно записать в файл.
Впрочем, не хотелось бы это делать средствами php. Неужто апач сам сохранить не может?
>тебе надо изучить HTTP
Где взять материал? На оф.документацию не посылай.
>когда поддержки фоновой загрузки файлов в браузере нет
Какой-нибудь пятый эксплорер? И как определить, есть эта поддержка или нет?
Дизайн сам нарисовал? Так как код ты не показываешь, я собираюсь по нему небольшую пасту накатать, как с работой разберусь.
Так, первое впечатление приятное, если учитывать что ты пока начинающий, то это хорошая работа.
Алсо в моем файерфоксе плеер появляется на долю секунды и исчезает, я потом гляну отладчиков почему.
Алсо, как всегда, рекомендую вбросить свой сайт в /b, там куча скучающих людей (а у нас лишь три с половиной анона) и ты получишь бесплатное тестирование и отзывы.
Заметил странный баг: при загрузке текстового файла к нему в начало добавляется 3 байта (BOM, https://ru.wikipedia.org/wiki/%D0%9C%D0%B0%D1%80%D0%BA%D0%B5%D1%80_%D0%BF%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%B1%D0%B0%D0%B9%D1%82%D0%BE%D0%B2 ). Файл становится на 3 байта больше.
Я думаю, этот BOM у тебя в начале одного из скриптов и при скачивании сначала отдается BOM, а потом сам файл. Это плохо, так как например картинки становятся битыми от добавления к ним 3 байтов и не открываются. Пересохрани свой код в utf-8 без BOM.
Проверить наличие BOM можно HEX редактором, обычный редактор его не выводит.
Закачанный PHP файл, если знать прямую ссылку на него, не выполнится?
Ну и приписывать имя сервиса в имя по моему перебор. Мне бы это не понравилось.
> Впрочем, не хотелось бы это делать средствами php. Неужто апач сам сохранить не может?
Если бы он сам сохранял файлы то любой мог бы забить твой хостинг мусором. Сохраняет файл именно PHP код. И код не сложный там, особенно если не передавать файл по частям, а передавать через FormData, то есть обычным POST c multipart/form-data.
> Где взять материал? На оф.документацию не посылай.
не знаю, вот что я нагуглил:
https://ru.wikipedia.org/wiki/Multipart/form-data — смотри тут поле пример, там как раз пример запроса который отправляет браузер при отправке формы с данными (там написано про отправку формы письмом, но при отправке на сервер запрос выглядит так же)
http://phpclub.ru/detail/article/http_request
PHP при получении запроса разбирает его и заполняет массивы _POST, _GET, _FILES, _COOKIE, _SERVER. Они описаны в мануале PHP, на русском.
При отправке формы браузер собирает и отправляет запрос сам. Если ты хочешь делать то же самое аяксом, то не вздумай кодировать данные руками. Используй класс FormData который есть в новых браузерах и который позволяет составлять multipart запрос, в том числе с добавлением файлов (если ты хочешь отправить файл целиком).
Инфа по FormData: https://developer.mozilla.org/ru/docs/Web/API/FormData
>>когда поддержки фоновой загрузки файлов в браузере нет
> Какой-нибудь пятый эксплорер? И как определить, есть эта поддержка или нет?
Эта поддержка появилась пару лет назад, так что не умебщие в нее браузеры можно найти: http://caniuse.com/#feat=xhr2
Как видишь эти фичи называются XHR Level 2.
Проверять надо через feature testing яваскриптом, проверь что есть все нужные тебе классы, а в них нужные методы:
if (!window.FormData) {
// нету FormData
}
if (!window.FileReader) {
// нету чтения файлов (если ты его используешь, если нет то можно не проверять)
}
Проверка наличия поддержки XHR2: http://stackoverflow.com/a/6966407
То есть определи какие фичи нужны твоему коду и сделай функцию их проверки. Используй сайт caniuse чтобы оценить уровень поддержки нужной фичи.
Вообще ты должен понимать что набор браузеров огромный, и например тот же сафари часто не поддерживает или поддерживает с задержкой нововведения. Есть мобильные браузеры, это отдельная история. Потому ты должен всегда стараться проверять наличие нужных фич через feature testing, и желательно предусмотреть либо какой-то альтернативный метод либо поясняющее сообщение для пользователя. Надо стараться делать как можно более надежный и работающий на максимальном числе устройств код.
И мне кажется любой, кто изучает фронтенд должен про это знать.
> Впрочем, не хотелось бы это делать средствами php. Неужто апач сам сохранить не может?
Если бы он сам сохранял файлы то любой мог бы забить твой хостинг мусором. Сохраняет файл именно PHP код. И код не сложный там, особенно если не передавать файл по частям, а передавать через FormData, то есть обычным POST c multipart/form-data.
> Где взять материал? На оф.документацию не посылай.
не знаю, вот что я нагуглил:
https://ru.wikipedia.org/wiki/Multipart/form-data — смотри тут поле пример, там как раз пример запроса который отправляет браузер при отправке формы с данными (там написано про отправку формы письмом, но при отправке на сервер запрос выглядит так же)
http://phpclub.ru/detail/article/http_request
PHP при получении запроса разбирает его и заполняет массивы _POST, _GET, _FILES, _COOKIE, _SERVER. Они описаны в мануале PHP, на русском.
При отправке формы браузер собирает и отправляет запрос сам. Если ты хочешь делать то же самое аяксом, то не вздумай кодировать данные руками. Используй класс FormData который есть в новых браузерах и который позволяет составлять multipart запрос, в том числе с добавлением файлов (если ты хочешь отправить файл целиком).
Инфа по FormData: https://developer.mozilla.org/ru/docs/Web/API/FormData
>>когда поддержки фоновой загрузки файлов в браузере нет
> Какой-нибудь пятый эксплорер? И как определить, есть эта поддержка или нет?
Эта поддержка появилась пару лет назад, так что не умебщие в нее браузеры можно найти: http://caniuse.com/#feat=xhr2
Как видишь эти фичи называются XHR Level 2.
Проверять надо через feature testing яваскриптом, проверь что есть все нужные тебе классы, а в них нужные методы:
if (!window.FormData) {
// нету FormData
}
if (!window.FileReader) {
// нету чтения файлов (если ты его используешь, если нет то можно не проверять)
}
Проверка наличия поддержки XHR2: http://stackoverflow.com/a/6966407
То есть определи какие фичи нужны твоему коду и сделай функцию их проверки. Используй сайт caniuse чтобы оценить уровень поддержки нужной фичи.
Вообще ты должен понимать что набор браузеров огромный, и например тот же сафари часто не поддерживает или поддерживает с задержкой нововведения. Есть мобильные браузеры, это отдельная история. Потому ты должен всегда стараться проверять наличие нужных фич через feature testing, и желательно предусмотреть либо какой-то альтернативный метод либо поясняющее сообщение для пользователя. Надо стараться делать как можно более надежный и работающий на максимальном числе устройств код.
И мне кажется любой, кто изучает фронтенд должен про это знать.
Если ты читал стать/учебник которая рассказывает про загрузку файлов аяксом, но не рассказывает про feature testing то мне кажется, это плохо, это низкий уровень. Если речь о learn.javascrpt, там наверняка это есть, просто где-то в другом разделе.
npm ~30000 либ.
Быстрее, это факт. Своими глазами видел, как сайт переписали с php на node.js и время отклика сервера уменьшилось в 2 раза.
>Я наблюдал другое, многие библиотеки медленнее так как написаны на JS, а не на Си.
Суть в однопоточной модели и "бассейна" асинхронных потоков.
> Своими глазами видел, как сайт переписали с php на node.js и время отклика сервера уменьшилось в 2 раза.
Это ничего не докаызвает. Я могу код на JS переписать так, что он станет медленее.
> Суть в однопоточной модели и "бассейна" асинхронных потоков.
Что хорошего в однопоточной модели когда у тебя много ядер? На серверах стоит обычно 8, 16, 24, 32 ядра. КОнечно их можно задействовать, организовав пул рабочих и балансер, но в PHP все это идет из коробки.
>Это ничего не докаызвает
Вот например статья с хабра. http://habrahabr.ru/post/191646/
>Что хорошего в однопоточной модели когда у тебя много ядер?
Кажется ты не понимаешь сути.
Представьте себе, что у вас на сервер приходит запрос, связанный с выборкой данных из БД.
Он отрабатывает, предположим, за 150 мс, из которых 130 это работа с базой данных.
В случае с PHP у вас полльзователь будет заблокирован эти 150 мс для обработки других запросов.
В случае с асинхронным сервером, он, пока запрос 1 ждет данные от БД в течение 130 мс, сможет принять и начать обрабатывать другие запросы. Предположим, что у нас один PHP-пользователь. В этом случае таких запросов, как из примера, он сможет обработать семь штук за секунду.
Асинхронному же, допустим, прилетят 20 запросов. Он обработает каждый до взаимодействия с БД, допустим за 10 мс, полетят 20 запросов к БД, пройдут, допустим, за 500 мс, и сервер сформирует ответ. И это все практически параллельно. Итого меньше чем за секунду мы таким образом обработаем 20 запросов.
> Кажется ты не понимаешь сути.
Нет, ты
> В случае с PHP у вас полльзователь будет заблокирован эти 150 мс для обработки других запросов.
Что значит пользователь? Сервер будет заблокирован? Нет, не будет так как есть другие потоки-рабочие которые принимают и обрабатывают запросы.
Алсо прочти что я написал выше. PHP использует все ядра процессора. Если например огромная нагрузка то он мождет загрузить несколько ядер. Твой однопоточный сервер упрется в одно ядро и либо не будет принимать новые соединения либо будет увеличивать время их обработки.
Я вижу что ты плохо разбираешься в серверах и ты зря со мной пытаешься спорить не имея хотя бы базовых знаний.
Есть ситуации где однопоточная обработка выгодна. Это поддержка числа большого числа параллельных соединений с небольшим трафиком и быстрой обработкой запроса на каждом. Например, чаты, уведомления. Там асинхронная модель имеет преимущества.
Nginx так же ее использует (но он создает не один процесс, а пул процессов-обработчиков).
В других случаях она не дает преимуществ. Но требует более сложной конфигурации. Вопрос, зачем с ней мучаться? Простота натсройки и разворачивания серьезное преимущество PHP.
Я же написал что нода нужна для специфичеких применений, а не для всего подряд.
Код на ней писать неудобнее из-за асинхронности.
Например в PHP ты пишешь:
$result = $mapper->findUser(1);
В JS тебе придется написать несколько строк и сделать код более запутанным. Есть языки, где для такого есть синтаксический сахар (C#, хаскелл) но JS к ним не относится.
Ну и напомню про список недостатков ноды который я написал выше.
> Кажется ты не понимаешь сути.
Нет, ты
> В случае с PHP у вас полльзователь будет заблокирован эти 150 мс для обработки других запросов.
Что значит пользователь? Сервер будет заблокирован? Нет, не будет так как есть другие потоки-рабочие которые принимают и обрабатывают запросы.
Алсо прочти что я написал выше. PHP использует все ядра процессора. Если например огромная нагрузка то он мождет загрузить несколько ядер. Твой однопоточный сервер упрется в одно ядро и либо не будет принимать новые соединения либо будет увеличивать время их обработки.
Я вижу что ты плохо разбираешься в серверах и ты зря со мной пытаешься спорить не имея хотя бы базовых знаний.
Есть ситуации где однопоточная обработка выгодна. Это поддержка числа большого числа параллельных соединений с небольшим трафиком и быстрой обработкой запроса на каждом. Например, чаты, уведомления. Там асинхронная модель имеет преимущества.
Nginx так же ее использует (но он создает не один процесс, а пул процессов-обработчиков).
В других случаях она не дает преимуществ. Но требует более сложной конфигурации. Вопрос, зачем с ней мучаться? Простота натсройки и разворачивания серьезное преимущество PHP.
Я же написал что нода нужна для специфичеких применений, а не для всего подряд.
Код на ней писать неудобнее из-за асинхронности.
Например в PHP ты пишешь:
$result = $mapper->findUser(1);
В JS тебе придется написать несколько строк и сделать код более запутанным. Есть языки, где для такого есть синтаксический сахар (C#, хаскелл) но JS к ним не относится.
Ну и напомню про список недостатков ноды который я написал выше.
Также, а зачем сайт переписывали? Имхо это скорее плохая идея так как затраты денег есть, а прибыль неочевидна.
Я реально плохо разбираюсь в серверах, поэтому спорить не буду.
Просто поделился пониманием и паблик инфой по ноду.
$text = <<<HERE
blabla
HERE
;
А дальше весь код подсвечивается как коммент, но при этом исполняется.
Ну я цветовую схему и общий силуэт подсмотрел в одном платном макете. Но результат получился очень далеким от оригинала, так что можно сказать да, сам рисовал.
Код не показываю, т.к. я знаю, что он далек от идеала, а ты то уж точно найдешь до чего докопаться, лол. Сейчас просто еще один сайт делаю, уже за деньги, так что нет времени правками тренировочных сайтов заниматься.
>Заметил странный баг: при загрузке текстового файла к нему в начало добавляется 3 байта
Этот BOM походу добавляется, когда я файлы по FTP редактирую блокнотом. Ладно, спасибо за баг-репорт, поправлю.
>Закачанный PHP файл, если знать прямую ссылку на него, не выполнится?
Нет конечно, мы же эту тему тут мусолили сколько времени. Все сделал как надо.
Вот. Список студентов, сделанный наполовину.
Готова пока только часть с регистрацией, только токен не генерируется/сохраняется почему-то.
С этим буду разбираться. Какие замечания на данный момент?
Кодеакадеми это вообще самые основы основ, то есть он больше подходит просто чтобы познакомиться с языком, но ничего серьезного там вроде не делают.
> Мне кажется, материал, предоставляемый тобой крут.
ну я бы не сказал что у нас что-то крутое, разве что оно поновее и поактуальнее некоторых других курсов.
> (\PREVIEW_DIR."/{$file->id}.txt"
> $uploadedFile = \UPLOAD_DIR."/{$file->id}_{$file->name}.txt";
для получения путей должны быть отдельные методы, это не должно быть вписано в нескольких местах кода.
> $preview = fopen(\PREVIEW_DIR."/{$file->id}.txt", 'w');
> fclose($preview);
Не понимаю смысла, зачем ты создаешь пустой файл? Мне кажется этого тут не должно быть.
> switch ($file->mime_type) {
Нужно сделать здесь ветку default (и например выбрасывать исключение или как-то еще обрабатывать ситуацию), а то не очень понятно что если тип не соответствует одному из поддерживаемых
При масштабировании картинки ты никогда не должен увеличивать ее так как растровые картинки нельзя увеличивать (будут искажения). Соответтвенно надо предусмотреть этот случай.
Проверь корректно ли масштабируется PNG с полупрозрачностью. Мне кажется, там прозрачность может превратиться в черный цвет.
> if (in_array($this->mime_type, $types)) {
Можно сразу писать return in_array(....) так как in_array возвращает true/false.
> public function save(\Storage\Model\File &$file)
Зачем тут & ? Объект и так не копируется при передаче. Мануал: http://www.google.ru/search?sourceid=chrome&ie=UTF-8&q=php+%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B+%D1%81%D1%81%D1%8B%D0%BB%D0%BA%D0%B8
> $sth->bindParam(
> ':mediaInfo', json_encode($file->mediaInfo), \PDO::PARAM_STR
Это вообще работает? Разве можно в bindParam передавать результат вызова функции?
Также, мне не нравится что ты преобразуешь в JSON объект целиком, там могут быть поля которые мы не хотим сохранять. Лучше сделать $file->mediaInfo->toJson() и чтобы объект явно создавал массив с нужными полями.
> $row->mediaInfo = \Storage\Model\MediaInfo::fromDataBase(
Чтобы не копипастить код маппинга 2 раза, лучше сделать отдельный метод который приведет объект в нужный вид.
> foreach ($obj as $property => $value) {
> $mediaInfo->$property = $obj->$property;
Тут должна быть какая-то проверка полей по списку, например с выдачей исключения при попытке передать неправильное поле. Иначе ошибка останется незамеченной.
Вместо stdClass JSON лучше преобразовывать в массив (так как для работы с массивом есть куча функций, а для stdClass нету).
> <a href="../">
Относительная ссылка зависит от URL страницы, то есть на странице /some/page она ведет на /some, а со страницы /some/other/page она ведет на /some/other. Лучше завести переменную и хранить в ней путь к корню сайта и приписывать ее ко всем ссылкам. Slim предоставляет готовую функцию для вычисления этого пути, она называется getRootUri: http://docs.slimframework.com/request/paths/
Более того, в некоторых местах у тебя она уже используется.
> {$file->name|escape|truncate:25}
escape должен идти последним иначе ты можешь HTML-сущность вроде & посередине разрезать.
> <td class="value">{$file->description|escape}</td>
Сделай чтобы переводы строк работали (думаю нужен nl2br или что-то аналогичное)
> <a href="../download/{$file->id}/{$file->name}">скачать</a>
Ссылку на скачивание надо генерировать функций или методом а не вписывать в куче мест.
Также, в ссылке не может содержаться пробел (а в имени файла может). Символы в имени файла при подстановке в ссылку надо кодировать процентным кодированием ( https://ru.wikipedia.org/wiki/URL#.D0.9A.D0.BE.D0.B4.D0.B8.D1.80.D0.BE.D0.B2.D0.B0.D0.BD.D0.B8.D0.B5_URL ), а саму ссылку потом экранировать через escape.
Чтобы лучше разробраться с кодированием ссылок и экранированием символов, реши задачку:
============
Сделай страницу с формой из textarea и кнопки отправки. Никакого оформления и CSS не требуется, просто черный текст на белом фоне. При вводе любого текста и нажатия кнопки текст должен появиться внизу под textarea. Текст должен точно соответствовать введенному, корректно отображать все символы, включая пробелы и переводы строк (тут тебе поможет тег pre), точно так как их ввел пользователь. Проверь что сочетания вроде
%20%20
<b>test
&amp;
"'\<>
&t=1&
Отображаются ровно в том же виде как введены.
После того, как ты это сделаешь, добавь еще кое-что. Кроме текста, надо выводить ссылку вида script.php?text=....., которая содержит введенный текст и открыв которую мы можем увидеть его на странице.
=============
> font-size: 1em;
Когда указываешь font-size, всегда указывай line-height.
> Скругления не срабатывают при collapse. Whyй?
Таблицы вообще сложная штука и у них много ограничений. То есть скругление на таблицах и не обязано работать по моему. Вот в стандарте пишут: http://www.w3.org/TR/css3-background/#border-radius-tables
> When ‘border-collapse’ is ‘collapse’, the UA may apply the border-radius properties to ‘table’ and ‘inline-table’ elements, but is not required to.
> The effect of border-radius on internal table elements is undefined in CSS3 Backgrounds and Borders, but may be defined in a future specification. CSS3 UAs should ignore border-radius properties applied to internal table elements when ‘border-collapse’ is ‘collapse’.
Получается по стандарту можно применять бордер радиус только к элементу table и только если не используется collapse. Мне кажется, проще просто обернуть таблицу в block/inline-block и применить скругление к нему.
> я не понял, как теперь напрямую обратиться к объекту смарти?
$app->view наверно?
> $mapper = new \Storage\Model\FileMapper($app->connection);
Маппер надо сделать синглтоном в Слиме
> if (!\Storage\Helper\PreviewGenerator::hasPreview($path)) {
> \Storage\Helper\PreviewGenerator::createPreview($file);
Превью лучше делать в момент загрузки файла.
Так, у тебя пока неплохо получается.
> Что еще можно сделать? А то даже месяца не потратил на файлообменник.
Древовидные комментарии конечно. У меня есть урок на тему как это хранить в БД: https://github.com/codedokode/pasta/blob/master/db/trees.md
Там же можешь потом и аяксовую отправку комментариев прикрутить. Не забудь несколько вещей которые должны быть при отправке аякс запроса:
— индикатор отправки
— обработка и вывод сетевых ошибок и ошибок от приложения, с возможностью повторить попытку отправки (как это сделано в соцсетях например)
— блокировка кнопок на время отправки запроса
Также, можешь прикрутить загрузку файлов перетаскиванием с рабочего стола, перетаскиванием картинки с других веб-страниц и из ворда (это будет сложнее), вставку файла с рабочего стола или картинки с браузера через Ctrl + V (для этого надо ловить событие paste на документе).
Перетаскивание с рабочего стола работает например на rghost.
Не спеши искать готовую библиотеку, сделай тестовый полигон из простого HTML файла с яваскриптом и поэкспериментируй, посмотри какие события с какими параметрами происходят в разных браузерах.
Когда разберешься, у тебя уже будет готовый код для перехвата таких файлов.
Помни что пользователь может перетащить несколько файлов сразу. желательно проверять объем до загрузки.
При перетаскивании картинок с веб-страниц некоторые браузеры сохраняют файл в временную папку и дают тебе этот файл, некоторые просто дают ссылку. То же самое при Ctrl + V.
Ну и индикатор прогресса загрузки в тех браузерах которые его поддерживают.
> (\PREVIEW_DIR."/{$file->id}.txt"
> $uploadedFile = \UPLOAD_DIR."/{$file->id}_{$file->name}.txt";
для получения путей должны быть отдельные методы, это не должно быть вписано в нескольких местах кода.
> $preview = fopen(\PREVIEW_DIR."/{$file->id}.txt", 'w');
> fclose($preview);
Не понимаю смысла, зачем ты создаешь пустой файл? Мне кажется этого тут не должно быть.
> switch ($file->mime_type) {
Нужно сделать здесь ветку default (и например выбрасывать исключение или как-то еще обрабатывать ситуацию), а то не очень понятно что если тип не соответствует одному из поддерживаемых
При масштабировании картинки ты никогда не должен увеличивать ее так как растровые картинки нельзя увеличивать (будут искажения). Соответтвенно надо предусмотреть этот случай.
Проверь корректно ли масштабируется PNG с полупрозрачностью. Мне кажется, там прозрачность может превратиться в черный цвет.
> if (in_array($this->mime_type, $types)) {
Можно сразу писать return in_array(....) так как in_array возвращает true/false.
> public function save(\Storage\Model\File &$file)
Зачем тут & ? Объект и так не копируется при передаче. Мануал: http://www.google.ru/search?sourceid=chrome&ie=UTF-8&q=php+%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B+%D1%81%D1%81%D1%8B%D0%BB%D0%BA%D0%B8
> $sth->bindParam(
> ':mediaInfo', json_encode($file->mediaInfo), \PDO::PARAM_STR
Это вообще работает? Разве можно в bindParam передавать результат вызова функции?
Также, мне не нравится что ты преобразуешь в JSON объект целиком, там могут быть поля которые мы не хотим сохранять. Лучше сделать $file->mediaInfo->toJson() и чтобы объект явно создавал массив с нужными полями.
> $row->mediaInfo = \Storage\Model\MediaInfo::fromDataBase(
Чтобы не копипастить код маппинга 2 раза, лучше сделать отдельный метод который приведет объект в нужный вид.
> foreach ($obj as $property => $value) {
> $mediaInfo->$property = $obj->$property;
Тут должна быть какая-то проверка полей по списку, например с выдачей исключения при попытке передать неправильное поле. Иначе ошибка останется незамеченной.
Вместо stdClass JSON лучше преобразовывать в массив (так как для работы с массивом есть куча функций, а для stdClass нету).
> <a href="../">
Относительная ссылка зависит от URL страницы, то есть на странице /some/page она ведет на /some, а со страницы /some/other/page она ведет на /some/other. Лучше завести переменную и хранить в ней путь к корню сайта и приписывать ее ко всем ссылкам. Slim предоставляет готовую функцию для вычисления этого пути, она называется getRootUri: http://docs.slimframework.com/request/paths/
Более того, в некоторых местах у тебя она уже используется.
> {$file->name|escape|truncate:25}
escape должен идти последним иначе ты можешь HTML-сущность вроде & посередине разрезать.
> <td class="value">{$file->description|escape}</td>
Сделай чтобы переводы строк работали (думаю нужен nl2br или что-то аналогичное)
> <a href="../download/{$file->id}/{$file->name}">скачать</a>
Ссылку на скачивание надо генерировать функций или методом а не вписывать в куче мест.
Также, в ссылке не может содержаться пробел (а в имени файла может). Символы в имени файла при подстановке в ссылку надо кодировать процентным кодированием ( https://ru.wikipedia.org/wiki/URL#.D0.9A.D0.BE.D0.B4.D0.B8.D1.80.D0.BE.D0.B2.D0.B0.D0.BD.D0.B8.D0.B5_URL ), а саму ссылку потом экранировать через escape.
Чтобы лучше разробраться с кодированием ссылок и экранированием символов, реши задачку:
============
Сделай страницу с формой из textarea и кнопки отправки. Никакого оформления и CSS не требуется, просто черный текст на белом фоне. При вводе любого текста и нажатия кнопки текст должен появиться внизу под textarea. Текст должен точно соответствовать введенному, корректно отображать все символы, включая пробелы и переводы строк (тут тебе поможет тег pre), точно так как их ввел пользователь. Проверь что сочетания вроде
%20%20
<b>test
&amp;
"'\<>
&t=1&
Отображаются ровно в том же виде как введены.
После того, как ты это сделаешь, добавь еще кое-что. Кроме текста, надо выводить ссылку вида script.php?text=....., которая содержит введенный текст и открыв которую мы можем увидеть его на странице.
=============
> font-size: 1em;
Когда указываешь font-size, всегда указывай line-height.
> Скругления не срабатывают при collapse. Whyй?
Таблицы вообще сложная штука и у них много ограничений. То есть скругление на таблицах и не обязано работать по моему. Вот в стандарте пишут: http://www.w3.org/TR/css3-background/#border-radius-tables
> When ‘border-collapse’ is ‘collapse’, the UA may apply the border-radius properties to ‘table’ and ‘inline-table’ elements, but is not required to.
> The effect of border-radius on internal table elements is undefined in CSS3 Backgrounds and Borders, but may be defined in a future specification. CSS3 UAs should ignore border-radius properties applied to internal table elements when ‘border-collapse’ is ‘collapse’.
Получается по стандарту можно применять бордер радиус только к элементу table и только если не используется collapse. Мне кажется, проще просто обернуть таблицу в block/inline-block и применить скругление к нему.
> я не понял, как теперь напрямую обратиться к объекту смарти?
$app->view наверно?
> $mapper = new \Storage\Model\FileMapper($app->connection);
Маппер надо сделать синглтоном в Слиме
> if (!\Storage\Helper\PreviewGenerator::hasPreview($path)) {
> \Storage\Helper\PreviewGenerator::createPreview($file);
Превью лучше делать в момент загрузки файла.
Так, у тебя пока неплохо получается.
> Что еще можно сделать? А то даже месяца не потратил на файлообменник.
Древовидные комментарии конечно. У меня есть урок на тему как это хранить в БД: https://github.com/codedokode/pasta/blob/master/db/trees.md
Там же можешь потом и аяксовую отправку комментариев прикрутить. Не забудь несколько вещей которые должны быть при отправке аякс запроса:
— индикатор отправки
— обработка и вывод сетевых ошибок и ошибок от приложения, с возможностью повторить попытку отправки (как это сделано в соцсетях например)
— блокировка кнопок на время отправки запроса
Также, можешь прикрутить загрузку файлов перетаскиванием с рабочего стола, перетаскиванием картинки с других веб-страниц и из ворда (это будет сложнее), вставку файла с рабочего стола или картинки с браузера через Ctrl + V (для этого надо ловить событие paste на документе).
Перетаскивание с рабочего стола работает например на rghost.
Не спеши искать готовую библиотеку, сделай тестовый полигон из простого HTML файла с яваскриптом и поэкспериментируй, посмотри какие события с какими параметрами происходят в разных браузерах.
Когда разберешься, у тебя уже будет готовый код для перехвата таких файлов.
Помни что пользователь может перетащить несколько файлов сразу. желательно проверять объем до загрузки.
При перетаскивании картинок с веб-страниц некоторые браузеры сохраняют файл в временную папку и дают тебе этот файл, некоторые просто дают ссылку. То же самое при Ctrl + V.
Ну и индикатор прогресса загрузки в тех браузерах которые его поддерживают.
Проблема в твоем редакторе, напиши баг-репорт разработчикам или погугли решение или возьми другой.
>>508275
> когда я файлы по FTP редактирую блокнотом
Это плохой способ, лучше иметь у себя копию проекта и редактировать ее, а изменения скриптом или программой заливать на сервер. Твой способ чреват ошибками, не позволяет использовать git, и с ним легко потерять данные. Я советую сразу отучаться.
Ну и виндовый блокнот не стоит вообще применять ни для чего, а тем более для кода.
>>508386
Потому что куки проще. Сессия это хранилище данных на сервере, идентификатор которого хранится в куке, то есть более сложный инструмент (зато данные в ней спрятаны от пользователя). Также, сессия это временное хранилище, неактивные в течечие 20-30 минут сессии удаляются.
Безопасность одинаковая.
>Закачанный PHP файл, если знать прямую ссылку на него, не выполнится?
Хм, а как запретить ему выполняться?
1) php_flag engine off (на некоторых хоститнгах не работает)
2) менять расширение при сохранении на диск на безобидное и известное (так как если расширение неизвесто то апач смотрит на идущее перед ним)
>>508440
Ну так украв куку с идентификатором сессии ты можешь прикинуться тем же пользователем. То же самое. Чтобы украсть было труднее, надо ставить флаг httpOnly: http://prophet.ru/2010/12/httponly-cookies/
Заметь что это не панацея, так как при XSS вредоносный скрипт хоть и не может украсть куки, но может делать любые действия на странице, нажимать кнопки, отпралять запросы и т.д.
А если куки вообще не юзать? Или сессии так и так юзают куки?
Не надо ничего "подгружать", сделай дополнительные элементы скрытыми по умолчанию (display: none в стилях), а при выборе определенного пункта в твоем списке менять у этих элементов display: block.
Спасибо, а не подскажешь как сделать так что бы после нажатия на один из пунктов списка всё подгружалось и при этом выбор оставался на этом же пункте.
Выбор и так останется на этом пункте. Стили меняются через javascript, перезагрузки страницы не будет.
Если тебе нужно несколько дополнительных текстовых полей, то сделай их скрытыми через display:none, меняй через js на display:block при выборе нужного пункта списка.
Если нужно чтобы именно подгрузился список в селект, то это нужно делать аяксом. Например при выборе категории в первом селекте, во второй селект подгружались соответствующие подкатегории.
Опиши конкретно что ты делаешь, что описывает эта форма.
>> Впрочем, не хотелось бы это делать средствами php. Неужто апач сам сохранить не может?
>Если бы он сам сохранял файлы то любой мог бы забить твой хостинг мусором. Сохраняет файл именно PHP код.
Погоди, я не понял: ведь при обычной загрузке файла через форму файл сохраняется сам (в смысле это делает апач, разве нет?), в php-скрипте мне нужно только переместить его из временной директории в папку загрузок. Или я заблуждаюсь, и манипуляцией с файлами занимается php без моего участия? Наверное так и есть, апач это же сервер, его дело отдавать, а никак не манипулировать файлами на жестком диске.
Хотелось бы тогда знать подробнее нюансы, как ето происходит.
>При отправке формы браузер собирает и отправляет запрос сам. Если ты хочешь делать то же самое аяксом, то не вздумай кодировать данные руками.
Понятия не имею как вообще отправить данные из формы, не то что кодировать их руками.
Все мои знания аякса на данный момент ограничиваются XmlHttpRequest с методами open и send, соответственно onReadyState == 4 манипулируем строкой ResponseText и вставляем ее в dom.
Всё.
Как отправить бинарные данные, не имею представления.
Про FormData намек понял, но как им пользоваться не понимаю. По твоей ссылке только сказано, что у него есть какие-то там методы и свойства для каких-то там данных. Мне нужен пример использования этой шняги, у меня недостаточно опыта чтобы домысливать. Опытные кодеры конечно при виде унылой спецификации сразу могут что-то понять по аналогии с другими техниками, им уже известными.
Допустим, если я знаю Yii, то мне будет уже несложно по аналогии понять принцип действия некоторых фич Симфони.
https://developer.mozilla.org/ru/docs/Web/API/FormData
>FormData()
>Создает объект FormData.
Что за объект такой? Предполагаю, что это объект, хранящий передаваемые данные и заголовки.
Наша цель получить запрос типа описанного в википедии
https://ru.wikipedia.org/wiki/Multipart/form-data
Значит объект FormData скорее всего представляет собой как бы каркас, который будет хранить данные и заголовки.
Используя его методы, мы формируем заголовки и тело, затем этот объект отправляем через обычный xhr.send()
Ну это мои догадки. Я конечно сейчас пойду гуглить примеры, все равно без этого никак.
А как отправить этот запрос руками через командную строку, например? Наверное, там используется какая-нибудь НЁХ типа curl или ssh?
Хочу быть небыдло-кодером, уметь отправлять запросы и получать контент (или хотя бы заголовки) прямо в терминал.
> window.FileReader
Это еще кто?
>> Впрочем, не хотелось бы это делать средствами php. Неужто апач сам сохранить не может?
>Если бы он сам сохранял файлы то любой мог бы забить твой хостинг мусором. Сохраняет файл именно PHP код.
Погоди, я не понял: ведь при обычной загрузке файла через форму файл сохраняется сам (в смысле это делает апач, разве нет?), в php-скрипте мне нужно только переместить его из временной директории в папку загрузок. Или я заблуждаюсь, и манипуляцией с файлами занимается php без моего участия? Наверное так и есть, апач это же сервер, его дело отдавать, а никак не манипулировать файлами на жестком диске.
Хотелось бы тогда знать подробнее нюансы, как ето происходит.
>При отправке формы браузер собирает и отправляет запрос сам. Если ты хочешь делать то же самое аяксом, то не вздумай кодировать данные руками.
Понятия не имею как вообще отправить данные из формы, не то что кодировать их руками.
Все мои знания аякса на данный момент ограничиваются XmlHttpRequest с методами open и send, соответственно onReadyState == 4 манипулируем строкой ResponseText и вставляем ее в dom.
Всё.
Как отправить бинарные данные, не имею представления.
Про FormData намек понял, но как им пользоваться не понимаю. По твоей ссылке только сказано, что у него есть какие-то там методы и свойства для каких-то там данных. Мне нужен пример использования этой шняги, у меня недостаточно опыта чтобы домысливать. Опытные кодеры конечно при виде унылой спецификации сразу могут что-то понять по аналогии с другими техниками, им уже известными.
Допустим, если я знаю Yii, то мне будет уже несложно по аналогии понять принцип действия некоторых фич Симфони.
https://developer.mozilla.org/ru/docs/Web/API/FormData
>FormData()
>Создает объект FormData.
Что за объект такой? Предполагаю, что это объект, хранящий передаваемые данные и заголовки.
Наша цель получить запрос типа описанного в википедии
https://ru.wikipedia.org/wiki/Multipart/form-data
Значит объект FormData скорее всего представляет собой как бы каркас, который будет хранить данные и заголовки.
Используя его методы, мы формируем заголовки и тело, затем этот объект отправляем через обычный xhr.send()
Ну это мои догадки. Я конечно сейчас пойду гуглить примеры, все равно без этого никак.
А как отправить этот запрос руками через командную строку, например? Наверное, там используется какая-нибудь НЁХ типа curl или ssh?
Хочу быть небыдло-кодером, уметь отправлять запросы и получать контент (или хотя бы заголовки) прямо в терминал.
> window.FileReader
Это еще кто?
ну вот до этого я хеллоувордил на питоне. Решал задачки из проекта Эйлера, читал хабр, немного подрочился по алгоритмам и структурам данных, мнил себя немного недо-"пайтониста". Пытался везде пихать декораторы, генераторы. Ну list comprehension это, конечно, вообще красота. Начал ковырять фласк. Но все чувствовал недостаток практики. И тут я понял, что надо изучать пхп, для того, чтобы пойти работать. Нашел этот тред, и осознал насколько важно показывать свой говнокод более опытным товарищам. В этом самая годнота. А по поводу джуниора в яндекс, накидай требования, будем брать максимальную планку!
Пишу в коде
preg_replace('/[\\(\\)-\s]/', '', $right);
и не работает. А если написать
preg_replace('/[\\(\\)\s-]/', '', $right);
или
preg_replace('/[\s\\(\\)-]/', '', $right);
то работает нормально.
Значок "-" (минус, или дефис) это спецсимвол в регулярных выражениях, как * или ?
В квадратных скобках он обозначает диапазон (так называемый класс символов)
Например [d-m] означает любой символ латинского алфавита с d по m, [4-8] одна цифра в промежутке от 4 до 8 (4, 5, 6, 7 или 8).
Чтобы интерпретатор регулярных выражений не воспринимал - как спецсимвол, его можно поставить в неподходящем месте, например в начале или конце выражения в скобках.
[48-] означает либо 4, либо 8, либо -
Выучи сначала синтаксис регулярных выражений, потом что-то пробуй писать. Потому что там еще много таких моментов, которые надо знать.
Благодарю. Теперь ясно. Ну, пойду штудировать в таком случае.
> ведь при обычной загрузке файла через форму файл сохраняется сам (в смысле это делает апач, разве нет?), в php-скрипте мне нужно только переместить его из временной директории в папку загрузок.
Верно, он сохраняется во временную директорию (PHP принимает POST запрос, извлекает файл из тела и сохраняет на диск) и если ты с ним ничего не сделаешь то удаляется при завершении скрипта. То есть по умолчанию сохраняется на время работы скрипта, не навсегда.
А если ты его переместишь то он уже останется на свом месте навсегда.
> Понятия не имею как вообще отправить данные из формы
Имеется в виду когда ты заполняешь форму и жмешь отправить, браузер собирает ее данные и передает их в теле POST запроса на сервер. Как именно кодируются и выглядят данные, написано по ссылкам которые я давал.
> Все мои знания аякса на данный момент ограничиваются XmlHttpRequest с методами open и send
Правильно. У метода send есть параметр. Это может быть строка или FormData. Если ты даешь строку то она отправляется в теле аякс запроса. Таким образом ты можешь передавть данные в любом, даже нестандартном формате.
Мануалы:
https://learn.javascript.ru/xhr-forms
https://learn.javascript.ru/ajax-xmlhttprequest#отослать-данные-send
https://developer.mozilla.org/ru/docs/Web/API/XMLHttpRequest#send() (обрати внимание сколько есть разных способов указать тело запроса)
Но чтобы не кодировать данные из формы руками, придуман FormData, мануал по которому есть в MDN. Ты создаешь объект FormData, добавляешь в него поля и файлы, а потом передаешь в метод send при отправке аякс запроса. И тогда formData собирает все указанные в нем поля и формирует тело запроса, аналогичное тому которое формируется при отправке обычной формы. Так как используется стандартный метод multipart/form-data то PHP понимает его и при получении запроса извлекает из него данные в массив $_POST, а переданные файлы сохраняет в $_FILES.
Я чувствую пора писать урок по HTTP так как тема важная, а нигде нормально не объяняется.
> Как отправить бинарные данные, не имею представления.
Как я вижу в мануале, в метод send можно передать Blob. Blob — это объект который представляет собой набор байтов, то енсть произвольные бинарные данные. Ты также можешь яваскриптом открыть файл и разбить его на блобы определенного размера. Как я понимаю, именно такой подзод предлагался в статье про пошаговую отправку, мы разбиваем файл на блобы и шлем эти блобы. Так как в данном слчае формат передачи данных нестандартный, PHP его не разберет и это надо будет сделать тебе самому, прочитать тело запроса из php://stdin, это строк 10-20.
Также, ты можешь взять блоб (кусок данных из файла) и добавить его в FormData как будто бы это файл, так как метод FormData#append принимет Blob в качестве значения.Тогда PHP увидит как будто бы т отправил форму с прилженным файлом. только этот файл содержит только кусок загружаеомго.
Также, ты можешь перекодировать блоб с бинарными данными каким-то способом в текст (urlencode, base64, base72 и другие методы) и слать этот текст стандартным методом. Тогда PHP сможет разобрать тело запроса, но эти методы кодирования увеличивают размер запроса.
В общем, полистай все ссылки что я скинул и разберись с тем что такое
Blob
FormData
> По твоей ссылке только сказано, что у него есть какие-то там методы и свойства для каких-то там данных.
Он просто позволяет создать запрос аналогичный тому что отправляется при отправке формы.
> Что за объект такой? Предполагаю, что это объект, хранящий передаваемые данные и заголовки.
Объект хранящий данные которые будут отправляться, там могут быть текстовые поля и файлы, как в обычной форме.
> как бы каркас, который будет хранить данные и заголовки.
Заголовки он не хранит, только данные нужные для сборки тела запроса.
> А как отправить этот запрос руками через командную строку, например?
Ну вообще можно открыть консоль в браузере и там писать яваскрипт команды. Ctrl + SHift + J
Но да, можно удобно отправлять запросы из командной строки с помощью curl и видеть результат в консоли. Нужно установить curl, способ установки зависит от ОС.
Вот официальный мануал: http://www.google.ru/search?aq=f&sourceid=chrome&ie=UTF-8&q=man+curl
Краткий список опций можно увидеть набрав curl --help
Вот SO с примерами отправки простых запросов: http://www.google.ru/search?aq=f&sourceid=chrome&ie=UTF-8&q=curl+send+request
Вот объяснялка опций в команде: http://explainshell.com/explain?cmd=curl+-d+x%3D1+-X+POST+-vvv
Спрашивай вопросы, если что-то непонятно. И посмотри все ссылки что я скинул. Надо разобраться в этой теме, это сбережет тебе потом часы отладки.
> ведь при обычной загрузке файла через форму файл сохраняется сам (в смысле это делает апач, разве нет?), в php-скрипте мне нужно только переместить его из временной директории в папку загрузок.
Верно, он сохраняется во временную директорию (PHP принимает POST запрос, извлекает файл из тела и сохраняет на диск) и если ты с ним ничего не сделаешь то удаляется при завершении скрипта. То есть по умолчанию сохраняется на время работы скрипта, не навсегда.
А если ты его переместишь то он уже останется на свом месте навсегда.
> Понятия не имею как вообще отправить данные из формы
Имеется в виду когда ты заполняешь форму и жмешь отправить, браузер собирает ее данные и передает их в теле POST запроса на сервер. Как именно кодируются и выглядят данные, написано по ссылкам которые я давал.
> Все мои знания аякса на данный момент ограничиваются XmlHttpRequest с методами open и send
Правильно. У метода send есть параметр. Это может быть строка или FormData. Если ты даешь строку то она отправляется в теле аякс запроса. Таким образом ты можешь передавть данные в любом, даже нестандартном формате.
Мануалы:
https://learn.javascript.ru/xhr-forms
https://learn.javascript.ru/ajax-xmlhttprequest#отослать-данные-send
https://developer.mozilla.org/ru/docs/Web/API/XMLHttpRequest#send() (обрати внимание сколько есть разных способов указать тело запроса)
Но чтобы не кодировать данные из формы руками, придуман FormData, мануал по которому есть в MDN. Ты создаешь объект FormData, добавляешь в него поля и файлы, а потом передаешь в метод send при отправке аякс запроса. И тогда formData собирает все указанные в нем поля и формирует тело запроса, аналогичное тому которое формируется при отправке обычной формы. Так как используется стандартный метод multipart/form-data то PHP понимает его и при получении запроса извлекает из него данные в массив $_POST, а переданные файлы сохраняет в $_FILES.
Я чувствую пора писать урок по HTTP так как тема важная, а нигде нормально не объяняется.
> Как отправить бинарные данные, не имею представления.
Как я вижу в мануале, в метод send можно передать Blob. Blob — это объект который представляет собой набор байтов, то енсть произвольные бинарные данные. Ты также можешь яваскриптом открыть файл и разбить его на блобы определенного размера. Как я понимаю, именно такой подзод предлагался в статье про пошаговую отправку, мы разбиваем файл на блобы и шлем эти блобы. Так как в данном слчае формат передачи данных нестандартный, PHP его не разберет и это надо будет сделать тебе самому, прочитать тело запроса из php://stdin, это строк 10-20.
Также, ты можешь взять блоб (кусок данных из файла) и добавить его в FormData как будто бы это файл, так как метод FormData#append принимет Blob в качестве значения.Тогда PHP увидит как будто бы т отправил форму с прилженным файлом. только этот файл содержит только кусок загружаеомго.
Также, ты можешь перекодировать блоб с бинарными данными каким-то способом в текст (urlencode, base64, base72 и другие методы) и слать этот текст стандартным методом. Тогда PHP сможет разобрать тело запроса, но эти методы кодирования увеличивают размер запроса.
В общем, полистай все ссылки что я скинул и разберись с тем что такое
Blob
FormData
> По твоей ссылке только сказано, что у него есть какие-то там методы и свойства для каких-то там данных.
Он просто позволяет создать запрос аналогичный тому что отправляется при отправке формы.
> Что за объект такой? Предполагаю, что это объект, хранящий передаваемые данные и заголовки.
Объект хранящий данные которые будут отправляться, там могут быть текстовые поля и файлы, как в обычной форме.
> как бы каркас, который будет хранить данные и заголовки.
Заголовки он не хранит, только данные нужные для сборки тела запроса.
> А как отправить этот запрос руками через командную строку, например?
Ну вообще можно открыть консоль в браузере и там писать яваскрипт команды. Ctrl + SHift + J
Но да, можно удобно отправлять запросы из командной строки с помощью curl и видеть результат в консоли. Нужно установить curl, способ установки зависит от ОС.
Вот официальный мануал: http://www.google.ru/search?aq=f&sourceid=chrome&ie=UTF-8&q=man+curl
Краткий список опций можно увидеть набрав curl --help
Вот SO с примерами отправки простых запросов: http://www.google.ru/search?aq=f&sourceid=chrome&ie=UTF-8&q=curl+send+request
Вот объяснялка опций в команде: http://explainshell.com/explain?cmd=curl+-d+x%3D1+-X+POST+-vvv
Спрашивай вопросы, если что-то непонятно. И посмотри все ссылки что я скинул. Надо разобраться в этой теме, это сбережет тебе потом часы отладки.
>IE9- по умолчанию кеширует все ответы, не снабжённые антикеш-заголовком. Другие браузеры этого не делают. Чтобы этого избежать, сервер должен добавить в ответ соответствующие антикеш-заголовки, например Cache-Control: no-cache.
Борисов говорит, что no-cache таки кеширует, но сессионно, в память, и после закрытия браузера не сохраняет кеш на диск. Надежнее использовать no-store.
Спецификацию пытался читать, но там все муторно, даже если бы было по-русски.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.2
>If the no-cache directive does not specify a field-name, then...
Если директива no-cache не определяет(указывает,уточняет?) имя поля (какого еще поля?), тогда ...
>a cache MUST NOT use the response to satisfy a subsequent request without successful revalidation with the origin server.
кеш НЕ ДОЛЖЕН использовать ответ чтобы удовлетворить последующий запрос без успешной ревалидации с оригинальным сервером.
Что? Кеш ответ сервера не должен использовать, или может быть наоборот, ответ из кеша не должен браться? Какой еще revalidation? Что они под этим подразумевают? Я снова должен гадать? Может, имеется ввиду last-modified? Не был ли изменен контент?
>This allows an origin server to prevent caching even by caches that have been configured to return stale responses to client requests.
Это позволяет оригинальному серверу (ну у нас сервер большой оригинал прост))), все сервера обыватели, а у нас оригинальный)
предотвратить кеширование даже кешами (кем? они сами себя кешируют, что ли? хотел бы я сам у себя откешировать, да не дотягиваюсь), которые настроены возвращать несвежие (азазаза) ответы на запросы клиентов.
>If the no-cache directive does specify one or more field-names, then a cache MAY use the response to satisfy a subsequent request, subject to any other restrictions on caching
Если директива no-cache указывает один или несколько имен полей(давайте гадать: заголовков?), тогда кеш МОЖЕТ (видимо, зависит от звезд) использовать ответ чтобы удовлетворить следующий запрос, подчиненный любому другому ограничению по кешированию.
>However, the specified field-name(s) MUST NOT be sent in the response to a subsequent request without successful revalidation with the origin server.
Как бы то ни было, указанные имена полей(заголовков?) НЕ ДОЛЖНЫ быть посланы в ответе на последующий запрос без успешной проверки сервером-оригиналом(тамадой? затейником? нет, зачем они уточняют про оригинальность сервера? что, проверить запрос можно каким-то другим сервером, а не тем с которого был оригинальный контент?)
>This allows an origin server to prevent the re-use of certain header fields in a response, while still allowing caching of the rest of the response.
Это позволяет оригинальному блин серверу предотвратить переиспользование определенных заголовков в ответе, пока разрешено кеширование остального(?) заропса.
Все, я устал читать это говно. Пусть горят в аду те хуесосы, которые пишут подобные мануалы.
Остается поверить на слово Борисову. no-cache кеширует в память, пока жива сессия, no-store строго запрещает любое кеширование.
>IE9- по умолчанию кеширует все ответы, не снабжённые антикеш-заголовком. Другие браузеры этого не делают. Чтобы этого избежать, сервер должен добавить в ответ соответствующие антикеш-заголовки, например Cache-Control: no-cache.
Борисов говорит, что no-cache таки кеширует, но сессионно, в память, и после закрытия браузера не сохраняет кеш на диск. Надежнее использовать no-store.
Спецификацию пытался читать, но там все муторно, даже если бы было по-русски.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.2
>If the no-cache directive does not specify a field-name, then...
Если директива no-cache не определяет(указывает,уточняет?) имя поля (какого еще поля?), тогда ...
>a cache MUST NOT use the response to satisfy a subsequent request without successful revalidation with the origin server.
кеш НЕ ДОЛЖЕН использовать ответ чтобы удовлетворить последующий запрос без успешной ревалидации с оригинальным сервером.
Что? Кеш ответ сервера не должен использовать, или может быть наоборот, ответ из кеша не должен браться? Какой еще revalidation? Что они под этим подразумевают? Я снова должен гадать? Может, имеется ввиду last-modified? Не был ли изменен контент?
>This allows an origin server to prevent caching even by caches that have been configured to return stale responses to client requests.
Это позволяет оригинальному серверу (ну у нас сервер большой оригинал прост))), все сервера обыватели, а у нас оригинальный)
предотвратить кеширование даже кешами (кем? они сами себя кешируют, что ли? хотел бы я сам у себя откешировать, да не дотягиваюсь), которые настроены возвращать несвежие (азазаза) ответы на запросы клиентов.
>If the no-cache directive does specify one or more field-names, then a cache MAY use the response to satisfy a subsequent request, subject to any other restrictions on caching
Если директива no-cache указывает один или несколько имен полей(давайте гадать: заголовков?), тогда кеш МОЖЕТ (видимо, зависит от звезд) использовать ответ чтобы удовлетворить следующий запрос, подчиненный любому другому ограничению по кешированию.
>However, the specified field-name(s) MUST NOT be sent in the response to a subsequent request without successful revalidation with the origin server.
Как бы то ни было, указанные имена полей(заголовков?) НЕ ДОЛЖНЫ быть посланы в ответе на последующий запрос без успешной проверки сервером-оригиналом(тамадой? затейником? нет, зачем они уточняют про оригинальность сервера? что, проверить запрос можно каким-то другим сервером, а не тем с которого был оригинальный контент?)
>This allows an origin server to prevent the re-use of certain header fields in a response, while still allowing caching of the rest of the response.
Это позволяет оригинальному блин серверу предотвратить переиспользование определенных заголовков в ответе, пока разрешено кеширование остального(?) заропса.
Все, я устал читать это говно. Пусть горят в аду те хуесосы, которые пишут подобные мануалы.
Остается поверить на слово Борисову. no-cache кеширует в память, пока жива сессия, no-store строго запрещает любое кеширование.
>> window.FileReader
> Это еще кто?
Это HTML5 объект для чтения содердимого файлов. Ты можешь с его помощью читать содержимое выбранного в input файла. И соответственно можешь обрабатывать файлы на клиенте.
http://www.html5rocks.com/ru/tutorials/file/dndfiles/
https://developer.mozilla.org/ru/docs/Web/API/FileReader
Если ты не понимаешь какой-то код из статей, то задавай уточняющие вопросы.
И дам еще раз ссылку: https://learn.javascript.ru/xhr-forms - не забудь прочесть.
Первое что ты должен понять — кто посылает заголовок и чем он управляет. В данном случае Cache-Control может слать и сервер и клиент и этот заголовок говорит прокси и кешам о том, можно ли использовать кешированный ответ и при каких условиях.
> Если директива no-cache не определяет(указывает,уточняет?) имя поля (какого еще поля?)
Прокрути страницу повыше где описывается синтаксис заголовка Cache-Control:
> "no-cache" [ "=" <"> 1#field-name <"> ]
Это значит что заголовок может иметь вид
Cache-Control: no-cache="fiend-name"
И имеется в виду то что написано в кавычках. Там можно писать имена заголовков. Сервер может сказать этим: «ок, ты можешь закешировать страницу но при отдаче из кеша не должен отдавать перечисленные заголовки без ревалидации (отправки запроса на сервер), ты должен либо сделать ревалидацию, либо вырезать указанные заголовки»
Я ни разу в жизни не встречал когда это нужно. Я видел только Cache-Control: no-cache. Эта опция (вместе с field-name) фактически позволяет задать заголовки ответа которые никогда не должны отдаваться из кеша без ревалидации. Без field-name она говорит что нельзя отдавать кешированный ответ без ревалидации.
no-store более жесткая опция, она запрещает сохранять ответ в кеш. Это нужно для чувствительных данных, которые не должны сохраняться на диск никогда.
Я также замечу что Cache-Control больше ориентирован на управление промежуточными прокси. Ну например своства public/private говорят можно ли отдать ответ из кеша другому клиенту или нельзя. Ну к примеру если речь идет о странице доступ к которой закрыт паролем (личный кабинет), разуемеется нельзя одному пользоватлю отдать страницу личного кабинета другого даже если у этих страниц одинаковый URL. Для таких случаев надо ставить private. С другой стороны если страница или файл общедоступны и не меняется (например картинка лежащая на диске) то для такого случая можно ставить public.
Для браузера public/private не имеет смысла так как у него один пользователь. Это актуально для кеширующих серверов.
> Что? Кеш ответ сервера не должен использовать, или может быть наоборот, ответ из кеша не должен браться?
Это значит что кеширующий сервер должен либо не отдавать сохраненные данные, либо должен предварительно сделать ревалидацию и только потом отдавать. То есть запрос на исходный сервер будет отправляться в любом случае.
> Какой еще revalidation? Что они под этим подразумевают?
Ревалидация это отправка запроса на исходный сервер с целью проверить актуальен он еще или уже нет. Ну к примеру на сервере поменяли файл-картинку. Очевидно что копия картинки в кеше уже неактуальна, и если браузер сделает ревалидацию (отправит запрос) он об этом узнает и сервер пришлет новую версию файла.
Ревалидация делается путем отправки GET запроса, к которому клиент добавляет 1 или 2 заголовка (If-Modified_since, If-ETag_None) которые описывают закешированный клиентом ресурс. Сервер отвечает либо кодом 304 (ок, твой кеш актуален, используй его) без тела ответа, либо если файл на сервере изменился, отвечает обычным кодом 200 и передает файл.
Заметь что если сервер не умеет делать ревалидацию и отдавать код 304, он просто проинорирует заголовки и отдаст обычный ответ с кодом 200. То есть эта схема надежная и работает даже если сервер очень простой и не понимает часть заголовков. И в этом сила HTTP что ты не обязан реализовывать все его возможности как в клиенте, так и в сервере.
Это описано ниже: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4
Кеширование сложная тема но если внимательно прочесть стандарт то думаю разобраться можно. На практике требуется деоать такие вещи:
— запрещать кеширование для страниц и файлов которые постоянно меняются, чтобы пользователь не увидел устаревшие данные
— одобрять кеширование без ревалидации для файлов которые никогда не поменяются и которые нужно брать сразу из кеша не отправляя запросов
— не ломать кеширование по умолчанию, когда браузер хранит файл в кеше но посылает запрос для проверки актуален ли он
С кешированием связаны такие заголовки:
Cache-Control
Vary
Last-Modified
If-Modified-Since
Etag
If-ETag-None (не помню точное написание)
Expires
и HTTP-код 304
Кроме стандарта я могу дать подборку статей на русском, найди там про кеширование, там конечно все описано кратко но сойдет для обзора, а потом уже можно браться за стандарт: http://webo.in/articles/archive/
Если после кеширования тебя еще заинтересуют другие методы клиентской оптимизации, есть книга: http://speedupyourwebsite.ru/books/speed-up-your-website/
Также открой инспектор в браузере Ctrol + SHift + I, вкладку Network, открой любой сайт и посмотри какие кеширующие заголовки из перечисленных используются.
И конечно я с удовольствием объясню любую непонятную вещь.
Первое что ты должен понять — кто посылает заголовок и чем он управляет. В данном случае Cache-Control может слать и сервер и клиент и этот заголовок говорит прокси и кешам о том, можно ли использовать кешированный ответ и при каких условиях.
> Если директива no-cache не определяет(указывает,уточняет?) имя поля (какого еще поля?)
Прокрути страницу повыше где описывается синтаксис заголовка Cache-Control:
> "no-cache" [ "=" <"> 1#field-name <"> ]
Это значит что заголовок может иметь вид
Cache-Control: no-cache="fiend-name"
И имеется в виду то что написано в кавычках. Там можно писать имена заголовков. Сервер может сказать этим: «ок, ты можешь закешировать страницу но при отдаче из кеша не должен отдавать перечисленные заголовки без ревалидации (отправки запроса на сервер), ты должен либо сделать ревалидацию, либо вырезать указанные заголовки»
Я ни разу в жизни не встречал когда это нужно. Я видел только Cache-Control: no-cache. Эта опция (вместе с field-name) фактически позволяет задать заголовки ответа которые никогда не должны отдаваться из кеша без ревалидации. Без field-name она говорит что нельзя отдавать кешированный ответ без ревалидации.
no-store более жесткая опция, она запрещает сохранять ответ в кеш. Это нужно для чувствительных данных, которые не должны сохраняться на диск никогда.
Я также замечу что Cache-Control больше ориентирован на управление промежуточными прокси. Ну например своства public/private говорят можно ли отдать ответ из кеша другому клиенту или нельзя. Ну к примеру если речь идет о странице доступ к которой закрыт паролем (личный кабинет), разуемеется нельзя одному пользоватлю отдать страницу личного кабинета другого даже если у этих страниц одинаковый URL. Для таких случаев надо ставить private. С другой стороны если страница или файл общедоступны и не меняется (например картинка лежащая на диске) то для такого случая можно ставить public.
Для браузера public/private не имеет смысла так как у него один пользователь. Это актуально для кеширующих серверов.
> Что? Кеш ответ сервера не должен использовать, или может быть наоборот, ответ из кеша не должен браться?
Это значит что кеширующий сервер должен либо не отдавать сохраненные данные, либо должен предварительно сделать ревалидацию и только потом отдавать. То есть запрос на исходный сервер будет отправляться в любом случае.
> Какой еще revalidation? Что они под этим подразумевают?
Ревалидация это отправка запроса на исходный сервер с целью проверить актуальен он еще или уже нет. Ну к примеру на сервере поменяли файл-картинку. Очевидно что копия картинки в кеше уже неактуальна, и если браузер сделает ревалидацию (отправит запрос) он об этом узнает и сервер пришлет новую версию файла.
Ревалидация делается путем отправки GET запроса, к которому клиент добавляет 1 или 2 заголовка (If-Modified_since, If-ETag_None) которые описывают закешированный клиентом ресурс. Сервер отвечает либо кодом 304 (ок, твой кеш актуален, используй его) без тела ответа, либо если файл на сервере изменился, отвечает обычным кодом 200 и передает файл.
Заметь что если сервер не умеет делать ревалидацию и отдавать код 304, он просто проинорирует заголовки и отдаст обычный ответ с кодом 200. То есть эта схема надежная и работает даже если сервер очень простой и не понимает часть заголовков. И в этом сила HTTP что ты не обязан реализовывать все его возможности как в клиенте, так и в сервере.
Это описано ниже: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4
Кеширование сложная тема но если внимательно прочесть стандарт то думаю разобраться можно. На практике требуется деоать такие вещи:
— запрещать кеширование для страниц и файлов которые постоянно меняются, чтобы пользователь не увидел устаревшие данные
— одобрять кеширование без ревалидации для файлов которые никогда не поменяются и которые нужно брать сразу из кеша не отправляя запросов
— не ломать кеширование по умолчанию, когда браузер хранит файл в кеше но посылает запрос для проверки актуален ли он
С кешированием связаны такие заголовки:
Cache-Control
Vary
Last-Modified
If-Modified-Since
Etag
If-ETag-None (не помню точное написание)
Expires
и HTTP-код 304
Кроме стандарта я могу дать подборку статей на русском, найди там про кеширование, там конечно все описано кратко но сойдет для обзора, а потом уже можно браться за стандарт: http://webo.in/articles/archive/
Если после кеширования тебя еще заинтересуют другие методы клиентской оптимизации, есть книга: http://speedupyourwebsite.ru/books/speed-up-your-website/
Также открой инспектор в браузере Ctrol + SHift + I, вкладку Network, открой любой сайт и посмотри какие кеширующие заголовки из перечисленных используются.
И конечно я с удовольствием объясню любую непонятную вещь.
>>This allows an origin server to prevent caching even by caches that have been configured to return stale responses to client requests.
> Это позволяет оригинальному серверу
Имеется в виду сервер который стоит в конце цепочки и который пишется в адресной строке. Ну например cloudflare выполняет роль прокси и кеша, а 2ch.hk это оригинальный сервер. Твой браузер шлет запросы к 2ch.hk, но этот домен указвает на cloudflare который проксирует/кеширует твои запросы и является посредником.
> редотвратить кеширование даже кешами которые настроены возвращать несвежие (азазаза) ответы на запросы клиентов.
Имеются в виду промежуточные кеши (либо кеш в браузере). HTTP дает определенную гибкость, он не задает правила как должен себя вести кеш, а только очерчивает рамки. А администратор или разработчик кеша может крутить настройки в этих рамках. например, кешировать более агрессивно либо более осторожно. Агрессивное кеширование в браузере укоряет загрузку сайтов. но может вести к отдаче неактуального контента в сложных случаях. Агрессивное кеширование на cloudflare может снизить нагрузку на оригинальный сервер двача. Потому сервер должен отдавать грамтные заголовки управляющие кешированием.
Этот абзац говорит что опция no-cache позволяет предотвратить отдачу неактуальных данных даже в случае агрессивного кеширования.
> Если директива no-cache указывает один или несколько имен полей(давайте гадать: заголовков?)
Заголовоков
> тогда кеш МОЖЕТ (видимо, зависит от звезд)
Зависит от его настроек заданных разработчиком или админимтратором.
> что, проверить запрос можно каким-то другим сервером, а не тем с которого был оригинальный контент?
Ну ты уже передергиваешь. Если мы не напишем «оригинальный» то будет непонятно о каком именно сервере речь.
> Остается поверить на слово Борисову. no-cache кеширует в память, пока жива сессия, no-store строго запрещает любое кеширование.
Не рекомендую.
У тебя сложности с пониманием из-за того что ты взял середину стандарта, и соответственно не читал те места где описывается тот или иной термин. Но я могу помочь, пояснив непонятные вещи, чтобы тебе не перечитывать весь стандарт.
Также, в начале стандарта есть словарик терминов: http://www.w3.org/Protocols/rfc2616/rfc2616-sec1.html#sec1.3
>>This allows an origin server to prevent caching even by caches that have been configured to return stale responses to client requests.
> Это позволяет оригинальному серверу
Имеется в виду сервер который стоит в конце цепочки и который пишется в адресной строке. Ну например cloudflare выполняет роль прокси и кеша, а 2ch.hk это оригинальный сервер. Твой браузер шлет запросы к 2ch.hk, но этот домен указвает на cloudflare который проксирует/кеширует твои запросы и является посредником.
> редотвратить кеширование даже кешами которые настроены возвращать несвежие (азазаза) ответы на запросы клиентов.
Имеются в виду промежуточные кеши (либо кеш в браузере). HTTP дает определенную гибкость, он не задает правила как должен себя вести кеш, а только очерчивает рамки. А администратор или разработчик кеша может крутить настройки в этих рамках. например, кешировать более агрессивно либо более осторожно. Агрессивное кеширование в браузере укоряет загрузку сайтов. но может вести к отдаче неактуального контента в сложных случаях. Агрессивное кеширование на cloudflare может снизить нагрузку на оригинальный сервер двача. Потому сервер должен отдавать грамтные заголовки управляющие кешированием.
Этот абзац говорит что опция no-cache позволяет предотвратить отдачу неактуальных данных даже в случае агрессивного кеширования.
> Если директива no-cache указывает один или несколько имен полей(давайте гадать: заголовков?)
Заголовоков
> тогда кеш МОЖЕТ (видимо, зависит от звезд)
Зависит от его настроек заданных разработчиком или админимтратором.
> что, проверить запрос можно каким-то другим сервером, а не тем с которого был оригинальный контент?
Ну ты уже передергиваешь. Если мы не напишем «оригинальный» то будет непонятно о каком именно сервере речь.
> Остается поверить на слово Борисову. no-cache кеширует в память, пока жива сессия, no-store строго запрещает любое кеширование.
Не рекомендую.
У тебя сложности с пониманием из-за того что ты взял середину стандарта, и соответственно не читал те места где описывается тот или иной термин. Но я могу помочь, пояснив непонятные вещи, чтобы тебе не перечитывать весь стандарт.
Также, в начале стандарта есть словарик терминов: http://www.w3.org/Protocols/rfc2616/rfc2616-sec1.html#sec1.3
Те вещи, что ты описал, могут быть тебе полезны даже если ты не будешь писать на Питоне (но я думаю, будешь). Они раширяют кругозор и могут подсказать решение какой-то задачи.
Насчет генераторов — помни что код пишется для людей. Если твой декоратор делает чтение, понимание и изменение кода проще, это хорошо. Если надо перерыть половину исходников чтобы его понять, и у него куча тонкостей и подводных камней, то плохо.
Декораторы функций интересная фича в Питоне (в PHP нет декораторов, но можно сделать аннотации через комментарии, в Доктрине они используются). В этом языке вообще много хорошего, и мне нравится его подход, что синтаксии должен быть понятен и лаконичен.
> А по поводу джуниора в яндекс
Боюсь, у меня нет списка требований но у яндекса есть сайт с вакансиями и там все описано, в том числе что они хотят видеть: https://yandex.ru/jobs/
Изучи его.
>>508686
Я поясню что минус является спецсимволом только внутри квадратных скобок, за их пределами он обычный символ.
Если надо указать минус в квадратных скобках можно либо ставить его в самый конец либо (что имхо читабельнее) экранировать бекслешем:
[a-z-]
[a-z\-]
Давай начнем с более простого: что вообще такое кэш?
Я думал, что это тупо контент, файлы (html, картинки, стили), которые браузер сохраняет куда-то на диск. Помню когда сидел на винде, хром у меня загаживал до 2 гб своим кешем.
>Cache-Control может слать и сервер и клиент и этот заголовок говорит прокси и кешам о том, можно ли использовать кешированный ответ и при каких условиях
Погоди, на стороне сервера тоже есть какое-то кеширование?
А что значит "заголовок говорит прокси и кешам"? Кеш это программа что ли? Как он может принимать данные? Про прокси я кстати вообще смутно понимаю, что это. Кажется, промежуточный сервер.
А, поэтому те чудилы и говорили про "оригинальный" сервер.
Расскажи про прокси, на примере хотя бы двача.
>например cloudflare выполняет роль прокси и кеша, а 2ch.hk это оригинальный сервер. Твой браузер шлет запросы к 2ch.hk, но этот домен указвает на cloudflare который проксирует/кеширует твои запросы и является посредником.
Я понял только слово "посредник".
cloudflare кеширует запрос от браузера и перенаправляет(?) на оригинальный сервер, который хз где. Тот отдает контент (кому? прокси или клиенту?)
>Cache-Control: no-cache. Эта опция (вместе с field-name) фактически позволяет задать заголовки ответа которые никогда не должны отдаваться из кеша без ревалидации. Без field-name она говорит что нельзя отдавать кешированный ответ без ревалидации.
>no-store более жесткая опция, она запрещает сохранять ответ в кеш.
Ну в принципе то, что я и говорил: no-cache требует проверки, был ли изменен контент перед тем как взять его из кеша, а no-store устанавливает полный запрет на кеширование.
Это все, что я хотел знать на данный момент.
>я могу дать подборку статей на русском http://webo.in/articles/archive/
ОК, почитаю, если там по-человечески объясняется.
>там конечно все описано кратко
Это и требуется. У меня нет ни времени ни желания читать тысячи страниц какой-то хрени. Жизнь уходит безвозвратно.
>>508802
Немного прояснил, ок.
>У тебя сложности с пониманием из-за того что ты взял середину стандарта, и соответственно не читал те места где описывается тот или иной термин.
Я это читать не буду от корки до корки, я еще не дошел до такого задротства. Вбил в поиск cache-control и прочитал абзац.
Ладно, у меня слегка взорвался мозг, я еще с аяксом не разобрался.
Давай начнем с более простого: что вообще такое кэш?
Я думал, что это тупо контент, файлы (html, картинки, стили), которые браузер сохраняет куда-то на диск. Помню когда сидел на винде, хром у меня загаживал до 2 гб своим кешем.
>Cache-Control может слать и сервер и клиент и этот заголовок говорит прокси и кешам о том, можно ли использовать кешированный ответ и при каких условиях
Погоди, на стороне сервера тоже есть какое-то кеширование?
А что значит "заголовок говорит прокси и кешам"? Кеш это программа что ли? Как он может принимать данные? Про прокси я кстати вообще смутно понимаю, что это. Кажется, промежуточный сервер.
А, поэтому те чудилы и говорили про "оригинальный" сервер.
Расскажи про прокси, на примере хотя бы двача.
>например cloudflare выполняет роль прокси и кеша, а 2ch.hk это оригинальный сервер. Твой браузер шлет запросы к 2ch.hk, но этот домен указвает на cloudflare который проксирует/кеширует твои запросы и является посредником.
Я понял только слово "посредник".
cloudflare кеширует запрос от браузера и перенаправляет(?) на оригинальный сервер, который хз где. Тот отдает контент (кому? прокси или клиенту?)
>Cache-Control: no-cache. Эта опция (вместе с field-name) фактически позволяет задать заголовки ответа которые никогда не должны отдаваться из кеша без ревалидации. Без field-name она говорит что нельзя отдавать кешированный ответ без ревалидации.
>no-store более жесткая опция, она запрещает сохранять ответ в кеш.
Ну в принципе то, что я и говорил: no-cache требует проверки, был ли изменен контент перед тем как взять его из кеша, а no-store устанавливает полный запрет на кеширование.
Это все, что я хотел знать на данный момент.
>я могу дать подборку статей на русском http://webo.in/articles/archive/
ОК, почитаю, если там по-человечески объясняется.
>там конечно все описано кратко
Это и требуется. У меня нет ни времени ни желания читать тысячи страниц какой-то хрени. Жизнь уходит безвозвратно.
>>508802
Немного прояснил, ок.
>У тебя сложности с пониманием из-за того что ты взял середину стандарта, и соответственно не читал те места где описывается тот или иной термин.
Я это читать не буду от корки до корки, я еще не дошел до такого задротства. Вбил в поиск cache-control и прочитал абзац.
Ладно, у меня слегка взорвался мозг, я еще с аяксом не разобрался.
>заумную
Если ты не понимаешь, что там написано, это не значит что там что-то умное.
У ОПа всегда стоит \n в начале поста. Стиль скучный и нудный.
Я пишу хуйню с претензией на петросянство. Стиль выбран агрессивно-ебланский.
Опознать не сложно.
>Я чувствую пора писать урок по HTTP так как тема важная, а нигде нормально не объяняется.
Неистово сосачую.
Никто в здравом уме не будет с нуля заучивать наизусть беспорядочный справочник, нужны короткие последовательные статьи с доступным объяснением.
> Давай начнем с более простого: что вообще такое кэш?
Кеш это промежуточная система на пути между клиентом и оригинальным сервером. Кеш может быть отдельным сервером с запущенной на нем программой, а может быть компонетом в другой программе (кеш браузера).
На практике это может быть:
— кеш браузера, без которого современные сайты бы тормозили так как на каждой странице надо заново загружать десятки файлов
— прокси/кеш который может поставить твой работодатель чтобы экономить трафик который создают сотрдники, а также ограничивать посещение развлекательных сайтов. Если 2 человека открывают вконтактик, незачем 2 раза скачивать один и тот же файл с яваскриптом. Если ты сидишь дома то с таким кешем ты не столкнешься.
— прокси/кеш на стороне сервера, он еще называется reverse proxy. Например двач использует cloudflare в качестве прокси/кеша для защиты от атак, снижения трафика и нагрузки на сервер за счет кеширования на стороне cloudflare
Кеши бывают shared (общий) и non-shared (личный) по числу пользователей. Кеш в браузере non-shared, другие 2 кеша это shared.
> Я думал, что это тупо контент, файлы (html, картинки, стили), которые браузер сохраняет куда-то на диск. Помню когда сидел на винде, хром у меня загаживал до 2 гб своим кешем.
это наверно правильнее назвать кешированные файлы или хранилище кеша.
> хром у меня загаживал до 2 гб своим кешем.
Это же настраивается
> Погоди, на стороне сервера тоже есть какое-то кеширование?
Посмотри на список выше. Кешировать может сам браузер (а мы можем захотеть ему запретить/разрешить это) а также промежуточные сервера, например cloudflare, обойти которые ты не можешь.
> Кеш это программа что ли? Как он может принимать данные?
Кеш это система (отдельная программа или компонент программы в случае кеша в браузере) которая стоит между клиентом и оригинальным сервером:
клиент — кеш в браузере — корпоративный прокси — кеш на cloudflare — 2ch.hk
Кеш в браузере это компонент браузера
Корпоративный прокси это севрер на котором запущена программа-прокси в которую встроен кеш
cluodflare это сервер, на котором запущена программа-прокси с встроенным в нее кешем
Ах да, «прокси» значит посредник.
> Как он может принимать данные?
Так как кеш стоит посередине то он может видеть и отправляемые и получаемые данные. А кеш встроенный в браузер видит даже больше информации, например он знает кто инициировал запрос (клик по ссылке, аякс-запрос, кнопка «назад») и может в зависимости от этого менять настройки кеширования. Ну например кнопка «назад» может использовать очень агрессивное кеширование так как скорее всего пользователь хочет видеть то, что он видел ранее и неактуальные данные тут не проблема, а вот скорость работы гораздо важнее. А нажатие Ctrl + F5 может переключать кеш в наиболее осторожный режим с обязатеьной ревалидацией любых данных.
> Про прокси я кстати вообще смутно понимаю, что это. Кажется, промежуточный сервер.
да
> loudflare кеширует запрос от браузера и перенаправляет(?) на оригинальный сервер, который хз где. Тот отдает контент (кому? прокси или клиенту?)
Браузер шлет запрос на 2ch.hk думая что имеет дело с оригинальным сервером. Но этот домен указывает на сервер cloudflare, который принимает запрос, анализирует его и либо проксирует к оригинальному серверу (адрес которого админы не раскрывают в целях безопасности этого сервера) либо может отдать ответ из своего кеша не дергая сервер двачей. Ну к примеру картинки тут никогда не обновляются. Следовательно их можно агрессивно кешировать на стороне cloudflare и значительно сократить трафик и число запросов к оригинальному серверу.
Поведение кеша cloudflare задается 2 вещами: настройками в панели управления (можно управлять агрессивностью) и заголовками от клиента или сервера.
> на оригинальный сервер, который хз где. Тот отдает контент (кому? прокси или клиенту?)
Отдает прокси чтобы не раскрывать свой Ip адрес. А прокси отдает пользователю.
Так как IP оригинального сервера неизвестен, не получится например сканировать его порты, искать уязвимости через них, подбирать пароли к ssh, и ддосить труднее так как cloudflare умеет отсекать или ослаблять атаки.
>>508817
Я думаю это хорошо, если трудно отличить.
> Давай начнем с более простого: что вообще такое кэш?
Кеш это промежуточная система на пути между клиентом и оригинальным сервером. Кеш может быть отдельным сервером с запущенной на нем программой, а может быть компонетом в другой программе (кеш браузера).
На практике это может быть:
— кеш браузера, без которого современные сайты бы тормозили так как на каждой странице надо заново загружать десятки файлов
— прокси/кеш который может поставить твой работодатель чтобы экономить трафик который создают сотрдники, а также ограничивать посещение развлекательных сайтов. Если 2 человека открывают вконтактик, незачем 2 раза скачивать один и тот же файл с яваскриптом. Если ты сидишь дома то с таким кешем ты не столкнешься.
— прокси/кеш на стороне сервера, он еще называется reverse proxy. Например двач использует cloudflare в качестве прокси/кеша для защиты от атак, снижения трафика и нагрузки на сервер за счет кеширования на стороне cloudflare
Кеши бывают shared (общий) и non-shared (личный) по числу пользователей. Кеш в браузере non-shared, другие 2 кеша это shared.
> Я думал, что это тупо контент, файлы (html, картинки, стили), которые браузер сохраняет куда-то на диск. Помню когда сидел на винде, хром у меня загаживал до 2 гб своим кешем.
это наверно правильнее назвать кешированные файлы или хранилище кеша.
> хром у меня загаживал до 2 гб своим кешем.
Это же настраивается
> Погоди, на стороне сервера тоже есть какое-то кеширование?
Посмотри на список выше. Кешировать может сам браузер (а мы можем захотеть ему запретить/разрешить это) а также промежуточные сервера, например cloudflare, обойти которые ты не можешь.
> Кеш это программа что ли? Как он может принимать данные?
Кеш это система (отдельная программа или компонент программы в случае кеша в браузере) которая стоит между клиентом и оригинальным сервером:
клиент — кеш в браузере — корпоративный прокси — кеш на cloudflare — 2ch.hk
Кеш в браузере это компонент браузера
Корпоративный прокси это севрер на котором запущена программа-прокси в которую встроен кеш
cluodflare это сервер, на котором запущена программа-прокси с встроенным в нее кешем
Ах да, «прокси» значит посредник.
> Как он может принимать данные?
Так как кеш стоит посередине то он может видеть и отправляемые и получаемые данные. А кеш встроенный в браузер видит даже больше информации, например он знает кто инициировал запрос (клик по ссылке, аякс-запрос, кнопка «назад») и может в зависимости от этого менять настройки кеширования. Ну например кнопка «назад» может использовать очень агрессивное кеширование так как скорее всего пользователь хочет видеть то, что он видел ранее и неактуальные данные тут не проблема, а вот скорость работы гораздо важнее. А нажатие Ctrl + F5 может переключать кеш в наиболее осторожный режим с обязатеьной ревалидацией любых данных.
> Про прокси я кстати вообще смутно понимаю, что это. Кажется, промежуточный сервер.
да
> loudflare кеширует запрос от браузера и перенаправляет(?) на оригинальный сервер, который хз где. Тот отдает контент (кому? прокси или клиенту?)
Браузер шлет запрос на 2ch.hk думая что имеет дело с оригинальным сервером. Но этот домен указывает на сервер cloudflare, который принимает запрос, анализирует его и либо проксирует к оригинальному серверу (адрес которого админы не раскрывают в целях безопасности этого сервера) либо может отдать ответ из своего кеша не дергая сервер двачей. Ну к примеру картинки тут никогда не обновляются. Следовательно их можно агрессивно кешировать на стороне cloudflare и значительно сократить трафик и число запросов к оригинальному серверу.
Поведение кеша cloudflare задается 2 вещами: настройками в панели управления (можно управлять агрессивностью) и заголовками от клиента или сервера.
> на оригинальный сервер, который хз где. Тот отдает контент (кому? прокси или клиенту?)
Отдает прокси чтобы не раскрывать свой Ip адрес. А прокси отдает пользователю.
Так как IP оригинального сервера неизвестен, не получится например сканировать его порты, искать уязвимости через них, подбирать пароли к ssh, и ддосить труднее так как cloudflare умеет отсекать или ослаблять атаки.
>>508817
Я думаю это хорошо, если трудно отличить.
Да там не то что справочник, многие аноны, увы. не понимают вообще как именно браузер связывается с сервером, что такое заголовки, методы, а это критически важно так как из-за этого они потом не понимают как работает Слим и что делает метод $app->get, что еще за get такой? (очевидно метод $app->get называется так постому что устанавливает обработчик который надо вызвать если мы получили запрос методом GET с указанным URL). И аякс нельзя изучать, и формы, без знания основ HTTP.
curl -v 'http://ya.ru'
Объяснение опций смоти объяснялкой, сайт explain shell
Как отправить POST запрос нагугли на Stack overflow, запросом вроде curl send post request
Не путай команду curl и расширение PHP.
(Enter)
tput reset (Enter)
Ctrl + L
Починил генерацию и запись токенов в базу.
Ещё при выводе страницы на экран вместе с формой отрисовывается непонятная единичка под ней. Результатом чего это может быть?
Прошёлся по всему своему коду, возвращаемые функциями значения записываются в переменные. Вроде бы.
И ещё: в таблице есть поле local, в котором хранится значение типа bit. При записи нового абитуриента значение этого поля успешно сохраняется. Но при вытаскивании из базы в $abiturient->local записывается пустая строка "". Почему так?
>хром у меня загаживал до 2 гб своим кешем.
ЕБАТЬ, а я думаю, куда блядь у меня память пропадает, что даже картинку сохранить нельзя? Ебаный хром, приходится ребутать компьютер из-за этой хуйни.
https://github.com/Si0n/register3
Переделал по рекомендациям.
Такие вот вопросы есть: почему сообщения на стене не обновляются после отправки, там же вроде перезагружается фул страница, и фото меняется спустя минуту-полторы хотя в папке уже давно новое фото лежит.
Повторы вредны тем, что если захочешь что-то изменить, то поправлять придется в N местах, а не в одном. Ладно, 2-3 повтора. А представь, что у тебя проект из сотен файлов. Можно конечно пробежаться заменой в какой-нибудь иде, но это не дело.
Так что все повторяющиеся выражения нужно брать в переменные (или константы для путей к файлам, например).
Повторяющиеся куски кода нужно оборачивать в функции.
Так а что насчет решения?
> Ещё при выводе страницы на экран вместе с формой отрисовывается непонятная единичка под ней. Результатом чего это может быть?
echo функция
<?= функция
Скорее всего какая-то функция возвращает true а при выводе оно превращается в единицу.
Открой исходник страницы в браузере Ctrl +U посмотри в каком месте единица и найди это место в шаблоне.
> И ещё: в таблице есть поле local, в котором хранится значение типа bit. При записи нового абитуриента значение этого поля успешно сохраняется. Но при вытаскивании из базы в $abiturient->local записывается пустая строка "". Почему так?
Обычно для да/нет используют TINYINT NOT NULL, или ENUM.
> При записи нового абитуриента значение этого поля успешно сохраняется.
Попробуй в консоли mysql или в phpmyadmin сделать SELECT local FROM ... и посмотри что выведется. MySQL возвращает битовое поле не числом, а байтом с кодом 0 или 1, чтобы увидеть число надо его преобразовать например как описано в этом посте: http://stackoverflow.com/a/2032258
Также, убери CREATE DATABASE/DROP DATABSAE/USE из дампа так как у других людей база может называться по другому (или они могут захотеть сделать несколько баз).
Также, в файле dbconfig должны быть только настройки, а не код создания PDO. Этот код можно перенести в bootstrap. Опции тоже лучше вынести так как их менять не планируется.
>>508881
В настройках можно ограничить размер кеша. Я ставлю там что-то вроде 15 мегабайт.
Алсо у меня еще диск загаживает скайп, который пишет свои многомегабайтные логи пока на диске есть место.
>>508913
> Такие вот вопросы есть: почему сообщения на стене не обновляются после отправки, там же вроде перезагружается фул страница, и фото меняется спустя минуту-полторы хотя в папке уже давно новое фото лежит.
Скорее всего это связано с кешированием картинки браузером. Вот как можно это проверить:
— открой отладчик (Ctrl + Shift + i) в браузере на вкладке Network. Открой страницу профиля. Загрузи новое фото, страница перезагрузится и отобразит старую картинку. В этот момент посмотри запрос на загрузку картинки в отладчике, посмотри какие у него заголовки, если не разберешься, скопипасть/заскриншоть его сюда.
Сделав это мы поймем, проблема в кеше или чем-то другом.
>>509063
Потому что копипаста это зло и ее надо искоренять на ранних этапах обучения. когда в коде одно и то же скопировано несколько раз, это затрудняет исправление багов и доработку так как исправление тебе тоже приходится делать несколько раз. Также, при копировании кода легко допустить ошибку.
Этот принцип назывется DRY - dont repeat yourself.
На твоем коде из 10 строчек конечно это просто небольшое неудобство, но в реальных проектах десятки и сотни тысяч строк и копипаста осложняет жизнь тем кто потом работает над этим кодом.
Не копипасть.
Теперь все верно.
> Ещё при выводе страницы на экран вместе с формой отрисовывается непонятная единичка под ней. Результатом чего это может быть?
echo функция
<?= функция
Скорее всего какая-то функция возвращает true а при выводе оно превращается в единицу.
Открой исходник страницы в браузере Ctrl +U посмотри в каком месте единица и найди это место в шаблоне.
> И ещё: в таблице есть поле local, в котором хранится значение типа bit. При записи нового абитуриента значение этого поля успешно сохраняется. Но при вытаскивании из базы в $abiturient->local записывается пустая строка "". Почему так?
Обычно для да/нет используют TINYINT NOT NULL, или ENUM.
> При записи нового абитуриента значение этого поля успешно сохраняется.
Попробуй в консоли mysql или в phpmyadmin сделать SELECT local FROM ... и посмотри что выведется. MySQL возвращает битовое поле не числом, а байтом с кодом 0 или 1, чтобы увидеть число надо его преобразовать например как описано в этом посте: http://stackoverflow.com/a/2032258
Также, убери CREATE DATABASE/DROP DATABSAE/USE из дампа так как у других людей база может называться по другому (или они могут захотеть сделать несколько баз).
Также, в файле dbconfig должны быть только настройки, а не код создания PDO. Этот код можно перенести в bootstrap. Опции тоже лучше вынести так как их менять не планируется.
>>508881
В настройках можно ограничить размер кеша. Я ставлю там что-то вроде 15 мегабайт.
Алсо у меня еще диск загаживает скайп, который пишет свои многомегабайтные логи пока на диске есть место.
>>508913
> Такие вот вопросы есть: почему сообщения на стене не обновляются после отправки, там же вроде перезагружается фул страница, и фото меняется спустя минуту-полторы хотя в папке уже давно новое фото лежит.
Скорее всего это связано с кешированием картинки браузером. Вот как можно это проверить:
— открой отладчик (Ctrl + Shift + i) в браузере на вкладке Network. Открой страницу профиля. Загрузи новое фото, страница перезагрузится и отобразит старую картинку. В этот момент посмотри запрос на загрузку картинки в отладчике, посмотри какие у него заголовки, если не разберешься, скопипасть/заскриншоть его сюда.
Сделав это мы поймем, проблема в кеше или чем-то другом.
>>509063
Потому что копипаста это зло и ее надо искоренять на ранних этапах обучения. когда в коде одно и то же скопировано несколько раз, это затрудняет исправление багов и доработку так как исправление тебе тоже приходится делать несколько раз. Также, при копировании кода легко допустить ошибку.
Этот принцип назывется DRY - dont repeat yourself.
На твоем коде из 10 строчек конечно это просто небольшое неудобство, но в реальных проектах десятки и сотни тысяч строк и копипаста осложняет жизнь тем кто потом работает над этим кодом.
Не копипасть.
Теперь все верно.
http://plnkr.co/edit/aV9NzQYEbEJqZ1tD96aC?p=preview
Вот тут лучше видно:
http://run.plnkr.co/Szp9fwuAKJd0yznu/
Как выравнять это выпадающее меню по горизонтале по центру дива
В куках токен есть, я проверил. В $values['token'] ставится null.
Выбрасываемые в лог ошибки (которых, на мой взгляд, нет) прилагаются.
Что-то я не пойму. чо нет простого скриптика, который открывает файл с любым расширением, находит строку и реплейсит ее с другой строкой? как это через fopen сделать? на массив контент разбивать чели?
А теперь снят.
http://ideone.com/fKw7jk причем на остальных сайтах он работает, а на нужном мне нет.
Да, кстати, вот такой скрипт мне возвращает в body, больше ничего нет. Если чекнуть переменную $data через var_dump то там пустая строка
>string(1011) " "
Собаканы, подскажите нубу в чем загвоздка.
Осваиваю сейчас нод.жс и столкнулся с проблемой, для простоты упрощу, но суть остается неизменна:
есть переменная someVar, в ней лежит строкой разметка страницы, читстый хтмл, эту переменную я отдаю response.write(someVar); чтобы он ее отобразил. В итоге не сранице я вижу строку разметки, а не результат(отрисованую страницу). Подскажите ЧЯДНТ?
План такой. Генерим куки вечные, записываем куки в redis ключем, с временем хранения 5 минут. дальше тупо считаем к-во этой хуёты. как идея7
С учётом того что информацию которую мы будем хранить в дивах выводится из таблицы в базе данных при помощи цикла foreach
>>509389
Администратор сайта не хочет чтобы его парсили. Займись чем-нибудь другим или парси страницы, сохраненные из браузера, или пиши браузерное расширение.
>>509514
> дальше тупо считаем к-во этой хуёты. как идея7
Как ты собрался их считать? Redis это не SQL и SELECT COUNT там нет. Ты конечно можешь считать общее число ключей, но это не надежно так как стоит тебе туда записать что-нибудь еще и оно будет влиять на цифру.
В редисе есть всякие структуры данных, может какая-то из них подойдет? В любом случае, все это будет работать только на маленьком числе пользователей так как подсчет числа ключей это O(N).
Алсо число пользователей можно смотреть в гугл аналитике.
Алсо я уверен что эта цифра никому не нужна и ты занимаешься бессмысленной работой.
>>509520
Если вопрос по верстке, то ты же можешь открыть исходник страницы и посмотреть код.
Если по тому как сделать вывод из базы данных в таблицу, то это обширная тема и тебе сначала надо изучить:
— SQL
— PDO или mysqli
— HTML/CSS
>>509389
Администратор сайта не хочет чтобы его парсили. Займись чем-нибудь другим или парси страницы, сохраненные из браузера, или пиши браузерное расширение.
>>509514
> дальше тупо считаем к-во этой хуёты. как идея7
Как ты собрался их считать? Redis это не SQL и SELECT COUNT там нет. Ты конечно можешь считать общее число ключей, но это не надежно так как стоит тебе туда записать что-нибудь еще и оно будет влиять на цифру.
В редисе есть всякие структуры данных, может какая-то из них подойдет? В любом случае, все это будет работать только на маленьком числе пользователей так как подсчет числа ключей это O(N).
Алсо число пользователей можно смотреть в гугл аналитике.
Алсо я уверен что эта цифра никому не нужна и ты занимаешься бессмысленной работой.
>>509520
Если вопрос по верстке, то ты же можешь открыть исходник страницы и посмотреть код.
Если по тому как сделать вывод из базы данных в таблицу, то это обширная тема и тебе сначала надо изучить:
— SQL
— PDO или mysqli
— HTML/CSS
http://ideone.com/IkfeZc
В массиве case содержиться информация в таком виде [id товара в таблице] = "количество товара"
Сама эта часть немного не в ООП стиле, но сам магазин в ООП стиле, там есть повторяющийся код, как его убрать что бы он был компактнее?
Посмотри отладчиком браузера (Ctrl + Shift + I) на вкладке Network какой Content-Type у ответа. Чтобы браузер воспринимал его как HTML, должно быть text/html; charset=utf-8
>>509260
Значит ошибка в твоем коде. SVG состоит из таких же байтов что и другие файлы.
>>509251
> Выбрасываемые в лог ошибки (которых, на мой взгляд, нет) прилагаются.
Ну как же это нет когда они есть. Undefined index значит что в массиве COOKIE нет нужной куки.
> В куках токен есть, я проверил.
Ты это проверил сделав var_dump($_COOKIE) или же на стороне браузера? Если ты проверяешь в браузере то ты делаешь неправильно. Проверять надо то что видит PHP а не то что видит браузер.
Это не то же самое так как для куки могут быть указаны домен и путь и на одной странице они видны, а на другой нет. Чтобы этого не было, при выставлении куки всегда ставь path = /
Просто на Stackoverflow, в одной из тем, из которой я и взял код выше, кто-то написал, что абсолютно любой сайт можно спарсить с помощью cURL и невозможно полностью это запретить. То есть можно сделать так, что сервер просто не заметит разницы между curl запросом и браузером, но в моем случае видимо чего-то не хватает.
>>509161
Флоаты нельзя отцентрировать, они могут быть прижаты только влево или вправо (точнее, можно, с помощью пары оберток, довольно громоздко и хрупко: http://w3pro.ru/article/vyravnivanie-blokov-po-tsentru )
Гораздо проще сделать пункты меню инлайн-блоками. Инлайн-блок ведет себя как обычное слово, а значит к нему применимо text-align.
Можешь показать что показывает отладчик и что видно в браузере?
>>509635
Видимо чего-то не хватает. Возьми отладчик браузера или сетевой анализатор типа Wireshark и проанализируй что не так.
>>509628
Не вижу ни строки ООП. Код запутанный и в нем ошибки.
Если честно, какой-то кошмар, serialize, unserialize. Ты в курсе что кука имеет ограничение по объему и браузер просто удалит твою корзину если туда положить много товаров?
также, ты в курсе что setcookie не меняет содержимое массива COOKIE и если твою функцию вызвать несколько раз то сохранится только последний товар?
также использовать unserialize над данными пришедшими от пользователя, небезопасно — в некоторых случаях это позволит пользователю выполнять определенные дейтсвия (так как unserialize может создавать объекты дял которых потом вызовется деструктор. Если ээтот деструктор например удаляет файл, то злоумышленник получает возможность удалить любой файл).
Чтобы не рисковать, надо использовать сессию (неактивная сессия умирает через 20 минут) или корзину в базе данных (что лучше), а в куке хранить только идентификатор сессии или корзины.
Ну и не заниматься изобретением велосипедов, а посмотреть или спросить как другие делают.
> там есть повторяющийся код, как его убрать что бы он был компактнее
В функцию если речь о php коде.
С FormData разобрался. Как всегда, оказалось что там кода на две строчки
var formData = new FormData(document.forms.formName);
xhr.send(formData);
А непонятной писанины в мануалах и документации на сотню страниц.
С другой стороны, узнал много нового про формирование post-запроса, как выглядит тело, заголовки, разделители.
Пробовал руками склеивать тело запроса, даже получилось.
Я так понял, что объект FormData не поддерживается недобраузером (ие), а также всякими мобильными операми и некоторыми андроидами. А еще старыми сафари.
Так что ради кроссбраузерности придется писать запасную функцию, где тело запроса будет формироваться руками.
>разберись с тем что такое Blob
Будет сделано.
По поводу курла я в том смысле, что хочется не пользуясь браузером посмотреть результат выполнения php-скрипта, например. Тем более в ситуации, когда php ждет пост-переменных. Я же не могу через адресную строку браузера обратиться постом, не писать же xhr под каждый чих.
Тем более, что я пока плохо знаю аякс, именно ради его изучения и пригодился бы курл. Вот я отправил xhr.send(data), жду response. Он мне выводит пустую строку. Почему? Вот поэтому и нужно проверить, что же возвращает php.
>>508846
Точно нет внятных мануалов по курлу? Ман баша выдает 66 экранов (я считал) нудного перечисления опций.
Так не пойдет. Сначала нужно выучить базовые вещи, потом подробности, снежным комом. Тем более я подозреваю что большая часть этих опций устарела или используется крайне редко.
Вот мне хочется сделать запрос методом HEAD, мне нафиг не нужны мегабайты html, которые вернутся гетом, мне нужно только заголовки потестить. Как мне в этом талмуде найти head? Кстати, там нет поиска, типа ctrl + F, как в браузере?
А, разобрался. Поиск слешом, повторить поиск n.
Ненавижу линуксоидов, они наверное самоутверждаются этим бессмысленным задротством.
Под каждую программу свои сочетания клавиш. Ну ладно, у меня память хорошая, но жаль засирать ее таким мусором.
Я бы хотел на старости вспоминать счастливые моменты вместе с дорогими людьми, а не сочетание клавиш для поиска в каком-нибудь емаксе.
> Я так понял, что объект FormData не поддерживается недобраузером (ие), а также всякими мобильными операми и некоторыми андроидами. А еще старыми сафари.
> Так что ради кроссбраузерности придется писать запасную функцию, где тело запроса будет формироваться руками.
Чтобы добавить файл в тело запроса, тебе надо прочесть его содержимое. Эта возможность появилась не так давно, потому часть «недобраузеров» в принципе не позволяет составить запрос руками.
Я предлагаю сделать проще и для недобраузеров вообще не использовать аякс. То есть в них при нажатии кнопки отправки будет обычная неаяксовая отправка. А в новых — все красиво, с полоской прогресса, догрузкой при обрыве и тд. Так ты получишь максимальный охват с небольшими трудозатратами.
То есть тебе надо освоить feature testing и сделать код который проверит наличие всех нужных фич.
> недобраузером (ие)
Вообще у ИЕ есть разные версии и различия между ними очень большие, я думаю что самые новые скорее всего поддерживают.
> Как всегда, оказалось что там кода на две строчки
Это ты просто берешь данные из заполненной формы. Но FormData еще позволяет добавлять данные из кода, без формы.
>По поводу курла я в том смысле, что хочется не пользуясь браузером посмотреть результат
Это хорошая идея так как видны все заголовки, например. Ну и можно просматривать любые типы данных. Да, это полезно.
> Вот я отправил xhr.send(data), жду response. Он мне выводит пустую строку. Почему?
Это лучше смотреть отладчиком браузера на вкладке network. Также, можно ставить точку останова в скрите, смотреть значения переменных, проходить код пошагово. Обязательно научись это делать, это тебе не раз поможет при поиске причин ошибок.
Статьи:
http://learn.javascript.ru/debugging-chrome (коротко на русском)
http://habrahabr.ru/post/143767/ (кратко на русском, старая статья)
http://habrahabr.ru/company/2gis/blog/246557/
https://developer.chrome.com/devtools (подробно на англ.)
Обязательно освой этот инструмент.
Кстати, он еще при верстке помогает, можно прямо на странице менять значения свойств и перетаскивать дивы.
> Я так понял, что объект FormData не поддерживается недобраузером (ие), а также всякими мобильными операми и некоторыми андроидами. А еще старыми сафари.
> Так что ради кроссбраузерности придется писать запасную функцию, где тело запроса будет формироваться руками.
Чтобы добавить файл в тело запроса, тебе надо прочесть его содержимое. Эта возможность появилась не так давно, потому часть «недобраузеров» в принципе не позволяет составить запрос руками.
Я предлагаю сделать проще и для недобраузеров вообще не использовать аякс. То есть в них при нажатии кнопки отправки будет обычная неаяксовая отправка. А в новых — все красиво, с полоской прогресса, догрузкой при обрыве и тд. Так ты получишь максимальный охват с небольшими трудозатратами.
То есть тебе надо освоить feature testing и сделать код который проверит наличие всех нужных фич.
> недобраузером (ие)
Вообще у ИЕ есть разные версии и различия между ними очень большие, я думаю что самые новые скорее всего поддерживают.
> Как всегда, оказалось что там кода на две строчки
Это ты просто берешь данные из заполненной формы. Но FormData еще позволяет добавлять данные из кода, без формы.
>По поводу курла я в том смысле, что хочется не пользуясь браузером посмотреть результат
Это хорошая идея так как видны все заголовки, например. Ну и можно просматривать любые типы данных. Да, это полезно.
> Вот я отправил xhr.send(data), жду response. Он мне выводит пустую строку. Почему?
Это лучше смотреть отладчиком браузера на вкладке network. Также, можно ставить точку останова в скрите, смотреть значения переменных, проходить код пошагово. Обязательно научись это делать, это тебе не раз поможет при поиске причин ошибок.
Статьи:
http://learn.javascript.ru/debugging-chrome (коротко на русском)
http://habrahabr.ru/post/143767/ (кратко на русском, старая статья)
http://habrahabr.ru/company/2gis/blog/246557/
https://developer.chrome.com/devtools (подробно на англ.)
Обязательно освой этот инструмент.
Кстати, он еще при верстке помогает, можно прямо на странице менять значения свойств и перетаскивать дивы.
> Точно нет внятных мануалов по курлу?
curl --help набери, будет кратко
Алсо набери в гугле linux curl send post stackoverflow — там есть готовые команды. Понять что значат опции можно через explain shell.
Там все опции учить не надо, я их вообще не помню, кроме 2-3 основных и гуглю если что.
> Как мне в этом талмуде найти head?
Набери в гугле stackoverflow linux curl head request
Там есть ключ, задающий метод запроса.
Кстати у меня есть урок про особенности ИЕ, держи, может быть пригодится: https://gist.github.com/codedokode/855e3970124687b26a1c
Ты ж мне сам кидал эту ссылку на caniuse http://caniuse.com/#search=formdata
Только 10 и 11 поддерживают FormData, и то частично (не поддерживают json-response)
Я в курсе насчет отладчика. Там дело было не в этом, php действительно возвращал пустую строку, потому что я не проставил заголовок xhr.setRequestHeader('Content-Type: multipart/form-data')
Без этого заголовка нужно читать из php://input через file_get_contents, например.
Но чтобы отслеживать такие моменты я и взялся за курл.
Ну ладно, я еще просто не привык к тому, что нет нормальных учебников, где все последовательно излагается. Приходится либо гуглить конкретный вопрос, либо читать стену текста в документации, большая часть которой не уперлась.
А что будет, если пользователь закроет страницу, не догрузив на сервер файл? Или только закрытие браузера убьет все соединения?
Как же без полосочки прогресса, нехорошо получается. Средствами php там какие-то пляски с сессией и куками, наверное я таки сделаю на всякий случай запасной вариант с ручным формированием запроса в обход FormData.
По поводу драг-дропа, как он реализуется? Понятно что я все равно прикручу jquery и не буду морочиться, но хотелось бы понимать как работает нативный код.
Подскажи, в каком направлении гуглить
(черт бы побрал ваш гугл, должен быть учебник блин, в котором все пошагово расписано. Сплошная безблагодатность)
>>509654
Не вываливай на меня все сразу. Я бережно сохраняю все твои материалы в закладки, но не успеваю все вызубрить. Тем более что там немаленькие такие объемы.
>>509656
Бывай, ихтиандр.
>Браузер ИЕ глубоко интегрируется в систему, потому портабельных версий ИЕ нет. Откатить версию ИЕ на более старую тоже нельзя.
Можно. Удаляем как обычно через панель администратора, после перезагрузки появляется более старая версия.
https://support.microsoft.com/ru-ru/kb/2821327/ru
Наверное, ты имел ввиду, что нельзя иметь несколько копий эксплорера.
> (не поддерживают json-response)
Ну так он тебе и не нужен ведь. Здесь наверно имеется в виду что в этих браузерах XSR не позволяет выставить json в поле responseType (который задает как надо интерпретировать ответ, https://developer.mozilla.org/ru/docs/Web/API/XMLHttpRequest#Properties )
Надо проверять яваскриптом наличие конкретныхфич, как я писал где-то выше.
> Приходится либо гуглить конкретный вопрос, либо читать стену текста в документации, большая часть которой не уперлась.
Лучше загуглить вопрос, найти ответ, а в документации посмотреть использованные там функции.
> А что будет, если пользователь закроет страницу, не догрузив на сервер файл?
Скорее всего запрос будет прерван, соединение разорвано, а php скрипт не запустится (так как разрыв проиойдет до запуска скрипта, на этапе приема тела запроса).
> Как же без полосочки прогресса, нехорошо получается. Средствами php там какие-то пляски с сессией и куками, наверное я таки сделаю на всякий случай запасной вариант с ручным формированием запроса в обход FormData.
Средствами PHP — это PHP при приеме POST запроса с файлом может писать куда-то (в apc кеш в памяти?) прогресс. И ты можешь паралельно с заказчкой файла слать запросы на сервер чтобы прочитать этот процент. Можно даже отменить загрузку.
Также, был какой-то модуль для nginx который делал отслеживание прогресса на уровне nginx (который делает это с меньшими затратами ресурсов).
Но это старый и, как ты видишь из описания, довольно неэффективный способ, так как шлется большое число запросов на сервер. Сейчас в новых браузерах ты можешь получать прогресс закачки из объект XHR, так как браузер знает какой процент запроса уже отпарвлен. И эти лишние запросы теперь не нужны.
Конечно такая фича только в новых браузерах (ну как в новых, FF c версии 3.5 поддерживает). Это часть XHR Level 2.
https://developer.mozilla.org/ru/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#Monitoring_progress
Потому я думаю, незачем слать запросы и возиться с настройкой PHP, сделай прогресс за сет возможностей XHR2, а если этого события в браузере нет, то не выводи полоску (впрочем в тех браузерах где нет событий проресса, скорее всего и аякс отправка не заработает, и придется откатиться до обычной отправки формы)
Проверить наличие поддержки я думаю можно по наличию поля onprogress у объекта XHR. В моем файерфоксе оно например есть.
> наверное я таки сделаю на всякий случай запасной вариант с ручным формированием запроса в обход FormData.
Я тебе повторю еще раз: в старых браузерах скорее всего нет не только FormData, но и возможности читать содержимое файлов (а это нужно чтобы добавить содержимое в тело запроса). Значит твой код пригодится только в очень маленькой части браузеров, где читать файл можно, а FormData нет. Я даже не уверен что такие есть, и мне кажется, лучше делить браузеры на 2 группы, новые и старые, а не на 3.
Но ты можешь написать это если хочешь попрактиковаться, сделай свой класс аналогичный FormData.
Если ты захочешь это сдедать, у меня есть кое-что тебе в помощь. Это код, которым тестируют FormData разработчики фаерйокса. Если ты хочешь написать свой аналог, то эти тесты должны работать и с ним:
https://dxr.mozilla.org/mozilla-central/source/dom/html/test/formData_test.js
Ну как минимум ты можешь посмотреть в этом файле примеры кода работы с FormData.
(кстати, заметь сколько у них тестов: https://dxr.mozilla.org/mozilla-central/source/dom/html/test — и это далеко не все. Такой сложнейший продкут, как браузер, нельзя разрабатывать без тысяч тестов).
> По поводу драг-дропа, как он реализуется?
При перетаскивании файла на элементе срабатывают события dragenter, dragmove, dragleave, drop. ПРичем ты должен реагировать на них особым образом, чтобы показать что готов принять файл, если ты это не сделаешь то ты потеряешь шанс его принять (и браузер просто откроет перетащенный в него файл).
Процесс описан тут:
кратко: http://www.html5rocks.com/ru/tutorials/file/dndfiles/
подробнее: https://developer.mozilla.org/ru/docs/Web/API/DataTransfer
https://developer.mozilla.org/ru/docs/Web/Guide/HTML/Drag_and_drop
хабр, хорошие статьи от яндекса и мейл ру, остальные так себе:
http://habrahabr.ru/company/yandex/blog/154151/
http://habrahabr.ru/company/mailru/blog/113508/
http://habrahabr.ru/post/125424/
http://habrahabr.ru/sandbox/33378/
http://habrahabr.ru/post/109079/
не копипасть код с хабра, качество там так себе.
Ах да. При отправке файла на сервер нежелательно читать его в память целиком так как если файл большой то браузер отъест много памяти. Лучше бы по частям или с использованием FormData, который, я надеюсь, читает файл потоком.
> я все равно прикручу jquery
jquery никак тебе не поможет. Помочь сможет сторонняя библиотека для загрузки файлов.
Но для изучения стоит сначала сделать страницу-полигон и на ней ловить события, смотреть что приходит и добиться чтобы на ней работало перетаскивание файлов (и вставка через Ctrl + V если осилишь). Когда добьешься, можно этот код перенести на файлообменник или взять стороннюю библиотеку.
Кстати, если ты выложишь эту страницу-полигон например на github pages (или другой хостинг), я ее потестирую на своих браузерах.
Не забудь тестировать в разных браузерах, так как у них свои особенности. Не забудь протестировать перетаскивание не только файлов с диска, но и картинки с сайта или картинки из редактора текста.
> (не поддерживают json-response)
Ну так он тебе и не нужен ведь. Здесь наверно имеется в виду что в этих браузерах XSR не позволяет выставить json в поле responseType (который задает как надо интерпретировать ответ, https://developer.mozilla.org/ru/docs/Web/API/XMLHttpRequest#Properties )
Надо проверять яваскриптом наличие конкретныхфич, как я писал где-то выше.
> Приходится либо гуглить конкретный вопрос, либо читать стену текста в документации, большая часть которой не уперлась.
Лучше загуглить вопрос, найти ответ, а в документации посмотреть использованные там функции.
> А что будет, если пользователь закроет страницу, не догрузив на сервер файл?
Скорее всего запрос будет прерван, соединение разорвано, а php скрипт не запустится (так как разрыв проиойдет до запуска скрипта, на этапе приема тела запроса).
> Как же без полосочки прогресса, нехорошо получается. Средствами php там какие-то пляски с сессией и куками, наверное я таки сделаю на всякий случай запасной вариант с ручным формированием запроса в обход FormData.
Средствами PHP — это PHP при приеме POST запроса с файлом может писать куда-то (в apc кеш в памяти?) прогресс. И ты можешь паралельно с заказчкой файла слать запросы на сервер чтобы прочитать этот процент. Можно даже отменить загрузку.
Также, был какой-то модуль для nginx который делал отслеживание прогресса на уровне nginx (который делает это с меньшими затратами ресурсов).
Но это старый и, как ты видишь из описания, довольно неэффективный способ, так как шлется большое число запросов на сервер. Сейчас в новых браузерах ты можешь получать прогресс закачки из объект XHR, так как браузер знает какой процент запроса уже отпарвлен. И эти лишние запросы теперь не нужны.
Конечно такая фича только в новых браузерах (ну как в новых, FF c версии 3.5 поддерживает). Это часть XHR Level 2.
https://developer.mozilla.org/ru/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#Monitoring_progress
Потому я думаю, незачем слать запросы и возиться с настройкой PHP, сделай прогресс за сет возможностей XHR2, а если этого события в браузере нет, то не выводи полоску (впрочем в тех браузерах где нет событий проресса, скорее всего и аякс отправка не заработает, и придется откатиться до обычной отправки формы)
Проверить наличие поддержки я думаю можно по наличию поля onprogress у объекта XHR. В моем файерфоксе оно например есть.
> наверное я таки сделаю на всякий случай запасной вариант с ручным формированием запроса в обход FormData.
Я тебе повторю еще раз: в старых браузерах скорее всего нет не только FormData, но и возможности читать содержимое файлов (а это нужно чтобы добавить содержимое в тело запроса). Значит твой код пригодится только в очень маленькой части браузеров, где читать файл можно, а FormData нет. Я даже не уверен что такие есть, и мне кажется, лучше делить браузеры на 2 группы, новые и старые, а не на 3.
Но ты можешь написать это если хочешь попрактиковаться, сделай свой класс аналогичный FormData.
Если ты захочешь это сдедать, у меня есть кое-что тебе в помощь. Это код, которым тестируют FormData разработчики фаерйокса. Если ты хочешь написать свой аналог, то эти тесты должны работать и с ним:
https://dxr.mozilla.org/mozilla-central/source/dom/html/test/formData_test.js
Ну как минимум ты можешь посмотреть в этом файле примеры кода работы с FormData.
(кстати, заметь сколько у них тестов: https://dxr.mozilla.org/mozilla-central/source/dom/html/test — и это далеко не все. Такой сложнейший продкут, как браузер, нельзя разрабатывать без тысяч тестов).
> По поводу драг-дропа, как он реализуется?
При перетаскивании файла на элементе срабатывают события dragenter, dragmove, dragleave, drop. ПРичем ты должен реагировать на них особым образом, чтобы показать что готов принять файл, если ты это не сделаешь то ты потеряешь шанс его принять (и браузер просто откроет перетащенный в него файл).
Процесс описан тут:
кратко: http://www.html5rocks.com/ru/tutorials/file/dndfiles/
подробнее: https://developer.mozilla.org/ru/docs/Web/API/DataTransfer
https://developer.mozilla.org/ru/docs/Web/Guide/HTML/Drag_and_drop
хабр, хорошие статьи от яндекса и мейл ру, остальные так себе:
http://habrahabr.ru/company/yandex/blog/154151/
http://habrahabr.ru/company/mailru/blog/113508/
http://habrahabr.ru/post/125424/
http://habrahabr.ru/sandbox/33378/
http://habrahabr.ru/post/109079/
не копипасть код с хабра, качество там так себе.
Ах да. При отправке файла на сервер нежелательно читать его в память целиком так как если файл большой то браузер отъест много памяти. Лучше бы по частям или с использованием FormData, который, я надеюсь, читает файл потоком.
> я все равно прикручу jquery
jquery никак тебе не поможет. Помочь сможет сторонняя библиотека для загрузки файлов.
Но для изучения стоит сначала сделать страницу-полигон и на ней ловить события, смотреть что приходит и добиться чтобы на ней работало перетаскивание файлов (и вставка через Ctrl + V если осилишь). Когда добьешься, можно этот код перенести на файлообменник или взять стороннюю библиотеку.
Кстати, если ты выложишь эту страницу-полигон например на github pages (или другой хостинг), я ее потестирую на своих браузерах.
Не забудь тестировать в разных браузерах, так как у них свои особенности. Не забудь протестировать перетаскивание не только файлов с диска, но и картинки с сайта или картинки из редактора текста.
А, значит мои знания устарели. Раньше откатить точно было нельзя. Видимо начиная с 10 версии он стал более отделен от самой системы.
Спасибо за информацию.
> Наверное, ты имел ввиду, что нельзя иметь несколько копий эксплорера.
Да, это тоже.
Посмотрел в отладчике - таки да, написано что текст/плейн, в коде(строка с разметкой страницы) отдаю мета с указание текст/хтмл. Это на стороне нод.джс что-то? Пытался нагуглить какие-то настройки связанные с этим, но пока безуспешно.
> в коде(строка с разметкой страницы) отдаю мета с указание текст/хтмл.
HTML код это не заголовок. Кто тебе сказал что content-type можно задавать в коде?
Все, разобрался в чем дело. Я по глупости в response.writeHeader() текст/плейн оставил, вот сервер и возвращал мне его. Извините, что побеспокоил. Алсо, может кто подскажет в каком иде удобней с джс работать? В частности с нодом, а то я сижу в шторме, но там неудобно, нет автодополнения на нодовские фичи.
Анон из джстреда подсказал - просто поставить плагин на пхпшторм. Сейчас поставил, буду смотреть что и как. Так что имей в виду, что выход таи есть, лол.
http://php.net/manual/ru/language.namespaces.dynamic.php#language.namespaces.dynamic
Если после строки с неймспейсом написать инклюд, то подключенные классы, функции и константы будут относиться к тому пространству, какое прописано в подключаемом файле, или текущем? Из примера на php.net очевидно, что к подключаемому. Но тогда где заканчивается тот неймспейс, что мы объявляли в начале файла перед инклюдом? Получается, что инклюд прерывает неймспейс?
<?php
namespace Hello\World;
class MyClass {}
include 'anotherFile.php';
$classname = 'MyClass';
$myClass = new $classname;
Почему создается экземпляр класса из подключаемого файла, а не из текущего неймспейса? Пространство Hello\World существует только до include?
Я с ним не работал, но слышал что кроме пхпшторм есть еще вебшторм, специально для js и nodejs.
И как грамотно импортировать неймспейсы?
Я пока знаю только, что можно прописать
use Hello\World\MyClass;
тогда ниже можно обращаться к этому файлу без указания пространства, просто MyClass.
Но даже в моем маленьком проекте 6 таких классов, не хотелось бы добавлять в index.php 6 строк.
use Hello\World; не прокатит?
Я имею ввиду, мне удастся отделаться одной строчкой импортирования, если у меня много классов в пространстве Hello\World?
Нет, только что сделал эксперимент, не работает.
Кстати, а где прописывать use? В самом начале скрипта, или после автозагрузчика?
Я использую композер, может эти use можно запихать куда-то в его автозагрузку?
Порылся в его файлах загрузки, там какие-то непонятные ужасы.
> Если после строки с неймспейсом написать инклюд,
Неймспейс не распространяется на подключенные файлы, только на тот в котором он стоит. Это не Си++, у нас инклуд работает по другому.
> Но тогда где заканчивается тот неймспейс,
Неймспейс действует в пределах одного файла
> Почему создается экземпляр класса из подключаемого файла, а не из текущего неймспейса?
Ты что-то напутал
>>509710
> Но даже в моем маленьком проекте 6 таких классов, не хотелось бы добавлять в index.php 6 строк.
В этом ничего плохого
> use Hello\World; не прокатит?
Прокатит но придется писать World\MyClass
> Кстати, а где прописывать use? В самом начале скрипта, или после автозагрузчика?
В самом начале, после namespace, до всего остального
> Я использую композер, может эти use можно запихать куда-то в его автозагрузку?
Нельзя
Чтобы не мучаться, надо использовать IDE или плагин к редактору который сам вставляет use и namespace. В саблайме это например PHP Companion
> Если после строки с неймспейсом написать инклюд,
Неймспейс не распространяется на подключенные файлы, только на тот в котором он стоит. Это не Си++, у нас инклуд работает по другому.
> Но тогда где заканчивается тот неймспейс,
Неймспейс действует в пределах одного файла
> Почему создается экземпляр класса из подключаемого файла, а не из текущего неймспейса?
Ты что-то напутал
>>509710
> Но даже в моем маленьком проекте 6 таких классов, не хотелось бы добавлять в index.php 6 строк.
В этом ничего плохого
> use Hello\World; не прокатит?
Прокатит но придется писать World\MyClass
> Кстати, а где прописывать use? В самом начале скрипта, или после автозагрузчика?
В самом начале, после namespace, до всего остального
> Я использую композер, может эти use можно запихать куда-то в его автозагрузку?
Нельзя
Чтобы не мучаться, надо использовать IDE или плагин к редактору который сам вставляет use и namespace. В саблайме это например PHP Companion
Инклуд не включает второй файл внутрь первого. Он скорее похож на вызов функции, то есть мы выполняем подключенный файл, а потом продолжаем выполнять исходный.
>Ты это проверил сделав var_dump($_COOKIE) или же на стороне браузера? Если ты проверяешь в браузере то ты делаешь неправильно. Проверять надо то что видит PHP а не то что видит браузер.
>
>Это не то же самое так как для куки могут быть указаны домен и путь и на одной странице они видны, а на другой нет. Чтобы этого не было, при выставлении куки всегда ставь path = /
Я проверял с помощью var_dump.
Тут вот что вскрылось: setcookie() срабатывает через раз. Я код не меняю, только чищу БД и куки браузера. То есть, проблема, скорее всего, не на стороне PHP.
В браузере куки разрешены, удаляются при выходе.
В чём может быть проблема?
А чо у тебя на гитхабе?
>> Почему создается экземпляр класса из подключаемого файла, а не из текущего неймспейса?
>Ты что-то напутал
Нет, это на php.net что-то напутано. Еще раз, вот пример:
http://php.net/manual/ru/language.namespaces.dynamic.php#language.namespaces.dynamic
в файле example1.php глобальное пространство
<?php
class classname {__construct(){echo __METHOD__;}}
в файле example2.php объявлен конкретный неймспейс и в нем одноименный класс
<?php namespace namespacename;
class classclass classname {__construct(){echo __METHOD__;}}
include 'example1.php';
$a = 'classname';
$class = new $a; // выведет classname::__construct, а не namespacename\classname::__construct, как я ожидаю. Почему? Разве мы не в пространстве имен namespacename? Почему они тогда не используют ни слеш в начале \classname для того чтобы показать, что это глобальный класс, ни импорт?
Получается, что namespacename в файле example2.php распространяется только до строки include. После строки инклюд нам почему-то нужно обращаться уже через \namespacename\classname, хотя мы же в нем вроде бы находимся?
Скорее всего там сидит шлюха-секретутка, которая не знает что такое гитхаб. Она распознает только документы в формате ворда и презентаций.
Еще может быть это контора верстальщиков или сиэмесников, они тупые и не знают языков, они ждут что ты им пришлешь ссылки на свои работающие сайты на говнохостингах.
Я в одну такую дно-контору послал "резюме" со ссылкой на гитхаб, а они мне говорят "выложите на хостинг, чтобы мы могли посмотреть".
Зачем, блджад? Это же очевидное дно.
Я в одну такую контору даже ходил 2 дня на "испытательный срок", охуел от их тупости, теперь решительно посылаю таких нахуй.
----------------------------------------------------------
На постоянной основе требуется программист PHP.
Требования к кандидату
Хорошее знание HTML, CSS;
Знание и понимание принципов юзабилити, семантики верстки;
PHP / MySQL на базовом уровне;
Опыт работы с одной или более CMS (Joomla, WordPress, Magento, Bitrix, Drupal, OpenCart)
Желательные навыки:
Опыт верстки на HTML5/CSS3;
Технический английский;
Опытработы с JavaScript,jQuery / Mootols/ etc.;
Понимание принципов ООП;
Также приветствуется:
Опыт работы с Bootstrap либо аналогичными UI-фреймворками;
Понимание основ SEO;
Умение при необходимости разбираться в чужом коде;
-----------------------------------------------------------
Все вакансии как под копирку (их в прямом смысле копипастит секретутка).
Вот другой вариант. Здесь адекватные требования к программисту (но тоже очевидно, что текст вакансии где-то скопировала секретутка):
-----------------------------------------------------------
Требования к соискателю
Опыт работы\tдо 1 года
Уровень образования высшее
Вакансия PHP программист
Рабочее время: полный рабочий день (график работы оговаривается отдельно и утверждается с руководителем проектов, офис открыт с 9.00-22:00. К студентам и и учёбе относимся с пониманием).
Зарплата: достойная (зависит от квалификации претендента).
Основные обязанности: PHP программирование.
Требования (знания, опыт):
- опыт работы с PHP5 и его объектной моделью, знание его отличий от PHP4;
- большим плюсом будет знание MVC, опыт работы с Zend Framework;
- PHP (работа c базами данных,текстовыми файлами, GD, ftp, сессиями, шаблонами, административный интерфейс, системы управления контентом);
- MySQL (PHPMyAdmin, знание языка SQL, проектирование БД);
- HTML/ DHTML, DOM, CSS, JavaScript , AJAX (все эти знания понадобяться в работе);
- умение работать в команде соблюдая стандарты кодирования;
- опыт работы с системами контроля версий, bugtracking-системами;
- английский язык на уровне переписки (чтение, понимание и переписка);
Интересует:
- серьезное отношение к работе;
- ответственность;
- заинтересованность в росте компании;
- достойный уровень оплаты и условий труда гарантируется;
Нам необходимы разносторонние и легко приспосабливаемые специалисты. Технологии, с которыми работают наши клиенты, динамично изменяются.
Ваши резюме высылать по адресу: [email]
В заголовке указывать PHP, Ваш город. Например: PHP, Kiev
Резюме высылать ТОЛЬКО в тексте письма, т. е. любые письма с вложенными файлами будут УДАЛЯТЬСЯ (пизда тупая блять. кто вообще пустил женщин в айти?)
Контакты:
ФИО:\tЛеся (nuff said)
------------------------------------------------------------------
Действительно профессиональные грамотные вакансии начинаются cо слов MIDDLE и SENIOR.
Хотя ОП нас тут так натаскивает, что может я к осени и докачаюсь до миддла (в смысле до того уровня, что эти клоуны подразумевают под миддлом)
----------------------------------------------------------
На постоянной основе требуется программист PHP.
Требования к кандидату
Хорошее знание HTML, CSS;
Знание и понимание принципов юзабилити, семантики верстки;
PHP / MySQL на базовом уровне;
Опыт работы с одной или более CMS (Joomla, WordPress, Magento, Bitrix, Drupal, OpenCart)
Желательные навыки:
Опыт верстки на HTML5/CSS3;
Технический английский;
Опытработы с JavaScript,jQuery / Mootols/ etc.;
Понимание принципов ООП;
Также приветствуется:
Опыт работы с Bootstrap либо аналогичными UI-фреймворками;
Понимание основ SEO;
Умение при необходимости разбираться в чужом коде;
-----------------------------------------------------------
Все вакансии как под копирку (их в прямом смысле копипастит секретутка).
Вот другой вариант. Здесь адекватные требования к программисту (но тоже очевидно, что текст вакансии где-то скопировала секретутка):
-----------------------------------------------------------
Требования к соискателю
Опыт работы\tдо 1 года
Уровень образования высшее
Вакансия PHP программист
Рабочее время: полный рабочий день (график работы оговаривается отдельно и утверждается с руководителем проектов, офис открыт с 9.00-22:00. К студентам и и учёбе относимся с пониманием).
Зарплата: достойная (зависит от квалификации претендента).
Основные обязанности: PHP программирование.
Требования (знания, опыт):
- опыт работы с PHP5 и его объектной моделью, знание его отличий от PHP4;
- большим плюсом будет знание MVC, опыт работы с Zend Framework;
- PHP (работа c базами данных,текстовыми файлами, GD, ftp, сессиями, шаблонами, административный интерфейс, системы управления контентом);
- MySQL (PHPMyAdmin, знание языка SQL, проектирование БД);
- HTML/ DHTML, DOM, CSS, JavaScript , AJAX (все эти знания понадобяться в работе);
- умение работать в команде соблюдая стандарты кодирования;
- опыт работы с системами контроля версий, bugtracking-системами;
- английский язык на уровне переписки (чтение, понимание и переписка);
Интересует:
- серьезное отношение к работе;
- ответственность;
- заинтересованность в росте компании;
- достойный уровень оплаты и условий труда гарантируется;
Нам необходимы разносторонние и легко приспосабливаемые специалисты. Технологии, с которыми работают наши клиенты, динамично изменяются.
Ваши резюме высылать по адресу: [email]
В заголовке указывать PHP, Ваш город. Например: PHP, Kiev
Резюме высылать ТОЛЬКО в тексте письма, т. е. любые письма с вложенными файлами будут УДАЛЯТЬСЯ (пизда тупая блять. кто вообще пустил женщин в айти?)
Контакты:
ФИО:\tЛеся (nuff said)
------------------------------------------------------------------
Действительно профессиональные грамотные вакансии начинаются cо слов MIDDLE и SENIOR.
Хотя ОП нас тут так натаскивает, что может я к осени и докачаюсь до миддла (в смысле до того уровня, что эти клоуны подразумевают под миддлом)
>Зарплата: достойная (зависит от квалификации претендента)
Поясните за эту хуйню, а то мне кажется я обламываюсь постоянно на этом пункте. Вот я знаю хтмл, ксс, пыху, осваиваю джс, немного в жиквере шарю, мускуль юзаю и т.д. Написал два проекта неплохих для нубаса, прихожу - говорю. знаю, что мои знания новичка, но я ведь на джуна претендую и готов учиться учиться и все такое, а мне ок - сколько вы хотите? Я посмотрел среднюю зп на доу и там порядка 400 баксов на джуна, потому говорю 300. МЫ ВАМ ПЕРЕЗВОНИМ. Сколько блядь просить то? А то на собеседовании на все ответил, тестовое сделал, не всратый, прилично одет и красиво говорю, но сука меня бортуют просто везде. ЧЯДНТ?
Я же не знаю, куда ты ходишь на собеседования.
Если это сиэмесники, то они могут и зажать 300 баксов, можно и подешевле макаку найти. Кроме того ты хорошо должен знать всякие вордпрессы-битриксы. Спроси лучше в /web, какие у них там требования.
Если контора профессионалов, то скорее всего проблема не в зарплате, а в уровне знаний.
> на собеседовании на все ответил
Уверен, что правильно? Они же не скажут "неправильно, ты хуй", это же не двач. В реальной жизни нельзя говорить то что думаешь, лицемерие превозносится под именем вежливости.
>тестовое сделал
Качественно ли сделал? Просто)) сделать может любой гамадрил, а ты попробуй сделать большое задание от ОПа, посмотришь сколько замечаний он напишет. И это не придирки, а исправление грубейших ошибок.
Файлообменник, например. Вроде это пока самое сложное, хотя там еще какое-то про тесты вроде было.
Это не смешно.
Человек, который писал текст вакансии, явно имеет смутное представление о том, чем занимается программист. Ну каким-то там программированием.
Ладно, если бы только секретутка-hr отличалась безграмотностью. Беда в том, что в таких конторах вообще нет (или крайне мало) специалистов.
То есть придешь устраиваться джуниором в надежде получить опыт, а у кого учиться блин?
Поэтому адекватные вакансии начинаются с миддлов, но там соответствующие требования. Ты должен быть уже прошаренным, чтобы без тормозов влиться в быстрый темп работы и поспевать за коллегами.
В худшем случае коллег вообще не будет, то есть в вакансии почти прямым текстом пишут: мы не шарим, ищем шарящего чувака, готовы платить много бабла. Если у тебя нет опыта, то иди нахуй, потому что у нас его тоже нет.
Ну это в мухосранях так дела обстоят, у вас в дэесах наверно любого школьника со знанием синтаксиса сразу на 30 тысяч берут.
Так что буду наверное еще год учиться у опа, пока он (или я) не помрет, или пока я не прокачаюсь до высокого уровня.
Зря я этот флуд затеял, но все равно сегодня-завтра перекат.
http://jsfiddle.net/tbvo7dsy/
Понять бы еще, как оно работает, было бы вообще здорово.
>Если вопрос по верстке, то ты же можешь открыть исходник страницы и посмотреть код.
>
>Если по тому как сделать вывод из базы данных в таблицу, то это обширная тема и тебе сначала надо изучить:
>
>— SQL
>— PDO или mysqli
>— HTML/CSS
Я в курсе как выводить из базы данных, я просто не понимаю в какой хтмл в данном случае надо завернуть вывод, что бы например каждая строка из базы данных располагалось в отдельном диве, этих дивов было 4 ряд и например 4 вглубь, ну как здесь http://www.saitadmin.ru/faili_na_razdacu/css/table_div2.html, в голову приходит поставить счётчки вывода и каждый раз когда он достигает определённого значения взависимости от количества дивов перескакивает на другой див, ну кажется это очень раково, вообщем мне надо вывести из базы данных данные примерно как в этом интернет магазине nikeboots.ru, вопрос только в хтмл обвёртке для вывода.
Например, зачем мы указываем контент-тайп вот здесь
<div ondragstart="event.dataTransfer.setData('text/plain',null)"...>
Удалил, продолжает работать.
Читаем в документации (developer.mozilla.org)
Set the data for a given type. If data for the type does not exist, it is added at the end, such that the last item in the types list will be the new format. If data for the type already exists, the existing data is replaced in the same position. That is, the order of the types list is not changed when replacing data of the same type.
void setData(
in String type,
in String data
);
Очень полезная информация, спасибо блин. Кто вообще составляет подобные роботообразные мануалы? Их хоть человек пишет, или они автоматически высираются программой?
Я догадываюсь, что setData не устанавливает данные, как свидетельствует ее название, а добавляет (корректнее тогда было бы назвать addData).
Так, ну и зачем мы ondragstart добавляем какие-то пустые данные NULL типа 'text/plain'?
Читаем майкрософт:
https://msdn.microsoft.com/en-us/library/ms536744(v=vs.85).aspx
setData method
(Deprecated.) Assigns data in a specified format to the dataTransfer object or the clipboardData object.
О, оно уже assign (назначает, присваивает) данные определенного формата к объекту dataTransfer.
Так, ну и что тогда означает NULL? Я опять-таки догадываюсь, что если передать NULL, то данные не добавятся к текущему объекту, а уже существующие данные поменяют тип.
То есть вот таким уебанским способом мы определяем тип уже имеющихся данных dataTransfer.setData('text/plain',null)
Не исключено, что какая-то из моих многочисленных догадок в цепочке оказалась неверной или неточной, пусть тогда меня поправят.
Но вопрос о том, зачем мы тут устанавливаем этот content-type не раскрыт по-прежнему. Что это дает? Я удалил, без него вроде работает.
Можно разбить массив результатов на куски с помощью array_chunk и обходить их 2 вложенным циклами.
>>509943
> зачем мы указываем контент-тайп вот здесь
Для этого полезно знать как вообще работает drag-n-drop и буфер обмена в операционных системах c GUI. Вот смотри, на дворе 1985 год, разрабатываются первые версии виндоуз и macos, и есть программа A, например редактор Ворд. Пользователь копирует фрагмент содержимого, переключается в программу B (например почтовый клиент или браузер или графический редактор или программа для создания презентаций) и жмет «вставить».
Вопрос: что должна передать программа A программе B и в каком формате? Обычный текст? HTML? Markdown? SGML? XML? JSON? бинарные данные в формате Word? PDF?
Как бы ты сделал? Когда будешь думать на эту тему, вспомни что существует огромное множетво программ и форматов файлов, причем новые форматы будут появляться и в будущем. Как бы ты сделал обмен данными? Наша цель добиться максимальной совместимости, чтобы пользоватль в идеале мог скопировать что угодно куда угодно.
По поводу этого, пока что не нашёл ничего более умного чем при выводе из базы данных забить всё в массив и потом по индекс выводить в каждой ячейке в такой структуре http://www.saitadmin.ru/faili_na_razdacu/css/table_div2.html но так не делается верно?
Ну ок, это в принципе понял. Мы устанавливаем content-type, как в заголовках.
В новых браузерах работает и без этого, но лучше на всякий случай ставить.
Один метод вроде разобрал. Осталось еще штук двадцать, и я смогу сделать хелловорлд. Круто, что тут сказать.
Нет, ты понял но не совсем.
В ОС для случаев переноса/копирования контента придумана такая штука. программа-отправитель создает список, в котором содержится контент в разных форматах (которые она знает). Сначала идут самые мощные форматы (в случае с вордом например бинарный формат ворда, который поймет разве что другая программа из MS office), затем более простые. Ну к примеру при копировании текста из ворда данные могут идти в таком порядке:
- проприетарный формат ворда
- HTML
- RTF
- plain text (текст без форматирования)
Получатель просматривает список и берет первый знакомый ему формат. Например браузер понимает HTML и он возьмет текст в формате HTML. Блокнот не понимает, и он возьмет plain text.
Соответственно когда ты делаешь штуку, котрую можно перетаскивать, ты должен об этом помнить и создавать такой список с содержимым в нужном (или в нужных) форматах.
> Например, зачем мы указываем контент-тайп вот здесь
Жаль что ты этого не понял. Это и есть создание списка с данными которые пользователь собирается перетянуть. При событии начала перетаскивания ты должен задать эти данные, которые получит принимающая программа.
Тут автор правда решил не заморччиваться и добавил null вместо текста, то есть при перетаскивании в тот же блокнот ничего не вставится.
Мне кажется, тут у тебя непонимание что это за драг-н-дроп. Это не для перетаскивания элементов на странице (это можно делать и без HTML5, ловя события mousedown/up/move). Это полноценное взаимодействие с другими программами и возможность перетаскивать контент в/из браузера. Например с помощью HTML5 drag and drop ты можешь нарисовать картинку в браузерном приложении и перетащить ее в ворд.
> В новых браузерах работает и без этого, но лучше на всякий случай ставить.
Не заработает так как без указания типа принимабщей программе неочевидно в каком формате данные, и она их не возьмет. Она берет только знакомые ей форматы.
Попробуй в setData(..., null) вместо null поставить текст, и перетащи блок в текстовый редактор или еще куда-нибудь.
Теперь конкретные вопросы.
я необучаемый?
На данный момент могу создать гостевуху с формой отправки сообщения и выводом n-кол ва сообщений на ней.
-Страницу с регистрацией\авторизацией.
-Тоже страница с регистрацией, но она создает что то типа "профиля" - Имя, фамилия, аватарка.
Этого достаточно для того, что бы пойти попробовать себя в качестве джуна на реальной работе?
Что, по вашему, лучше: еще немного закрепить имеющиеся на данный и ходить по собеседованиям и проситься работать за еду в надежде на то, что в рабочих условиях я получу новые знания или задрачивать учебники \ задания \ пхп- треды до посинения и повляения уверенности что ТЕПЕРЬ ТО Я ТОЧНО ГОТОВ РАБОТАТЬ?
Ага, теперь кажется понял.
Драг-дроп не для перетягиваний элементов в браузере, а для взаимодействия между программами. (Пойду гуглить, надеюсь найду что-то внятное)
При перетягивании элемента в по странице понятно можно не указывать тип контента, потому что мы эти данные таскаем в пределах одной программы, т.е. браузера.
Если говорить конкретно о setData, то он либо добавляет новые данные, либо устанавливает например content-type уже существующим (если передан NULL).
>>509965
Попробовал написать setData ('text/plain', 'хуй') и перетащить в саблайм, ноль реакции почему-то. Ну неважно.
>>509967
Да, программирование - это беспросветная учеба с утра до ночи. Если ты ставишь цель стать профессионалом и зарабатывать очень много денег.
Поэтому обязательно нужен энтузиазм. Мне лично нравится этим заниматься. Хотя подгорает от того, что друзья и родственники смотрят как на говно, что я до сих пор нигде не работал. Поэтому я бешено тороплюсь.
Тебя никто не заставляет учиться именно программированию. Поверхностное знание php у тебя есть, учи теперь wordpress, drupal и joomla, или что там сейчас модно.
Программисты презрительно отзываются о cms, но это дело вкуса. Нам нравятся нестандартные задачи, головоломки, от монотонной работы тошнит.
Тебе наоборот может даже понравится за 200-300 баксов целыми днями напролет копировать и поправлять говносайты, сделанные школьником-хрелансером.
Если хорошо знать api друпала и вордпресса, то можно рассчитывать и на большую зарплату. Наверное.
У меня вот тут https://jsfiddle.net/hkxe3bod/embedded/result/ работает перетаскивание в саблайм (из фаерфокса). Ты точно все правильно сделал?
> Драг-дроп не для перетягиваний элементов в браузере, а для взаимодействия между программами.
В первую очередь для взаимодействия, да, но можно и для перетаскивания в браузере использовать. Но он все равно заточен больше на перенос данных.
> ри перетягивании элемента в по странице понятно можно не указывать тип контента, потому что мы эти данные таскаем в пределах одной программы
Скорее потому что мы потом эти данные все равно не пытаемся прочесть.
> Если говорить конкретно о setData, то он либо добавляет новые данные, либо устанавливает например content-type уже существующим (если передан NULL).
Нет, неверно. null просто значит «пустой текст», я думаю он там превращается в '' (пустая строка)
Ты не можешь установить другой тип уже добавленным данным.
Вот кстати на MDN статья про общераспространенные типы данных: https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Recommended_Drag_Types
>>509974
> Если хорошо знать api друпала и вордпресса, то можно рассчитывать и на большую зарплату. Наверное.
Если ты умеешь быстро работать и выполнять большие объемы задач то думаю и с вордпрессом можно хорошо зарабатывать. Просто за счет количества. Ну и на вордпрессе в принципе нормальные сайты тоже делают, тот же siliconrus изначально на вордпрессе был. Другой вопрос что таких хороших заказов меньше, да и не каждый с ними справится.
Во-первых по твоей ссылке стоит setData('text/plain', null). Пикрелейтед.
Во-вторых с текстом тоже не работает setData('text/plain', 'hello world')
(В смысле саблайм не реагирует. Я ожидаю, что у меня этот текст окажется в документе саблайма. А никакой реакции)
Браузер хромиум 43
>Ты не можешь установить другой тип уже добавленным данным.
https://developer.mozilla.org/ru/docs/Web/API/DataTransfer#setData.28.29
If data for the type already exists, the existing data is replaced in the same position.
Короче, я тогда не понимаю, чего автор добивается при помощи setData ('text/plain', null). Извини конечно, что я заебываю с этим примером, но если не поймешь одну строчку, потом другую, третью, в результате нихрена непонятно как оно работает, и остается только скопипастить.
Хотя я до сих пор думал, что бесплатная версия отличается от платной только заголовком UNREGISTERED и заебывающим всплывающим окном, которое выпрашивает деньги.
Так вот, setData ('text/plain', null) перетаскивается что интересно null (как текст, то есть строка 'null').
setData ('text/plain', 'hello world') получаем заветный hello world.
Ок. Ну ладно, я пошел гуглить принципы технологии drag&drop. Взаимодействие с ОС и прочие увлекательные вещи.
Вакаба шатается. Надеюсь этот пост не будет отправлен 2-3 раза.
P.S. Оп - ты лучший, у тебя просто отличнейший курс по PHP, именно то, что он настолько легко и доступно составлен повлияло на то, что я все-таки начал его изучать.
Точно, попроуй еще один вариант тогда: https://jsfiddle.net/hkxe3bod/1/embedded/result/
У меня в ФФ все работает, и в Хроме, при перетаскивании дива вставляется текст.
> If data for the type already exists, the existing data is replaced in the same position.
так это ты не устанавливаешь другой тип. Ты заменяешь старые данные того же типа. То есть если у тебя в списке уже есть данные text/plain и ты пытаешься добавить еще данных с таким типом то они заменяют те, чо были. Заменяеются данные, а не их тип.
При этом в dataTransfer может быть несколько данных разного типа.
> Короче, я тогда не понимаю, чего автор добивается при помощи setData ('text/plain', null).
Я тоже. Наверно он не знал что написать в setData и решил поставить null. В любом случае идея в том что ты должен в начале перетаскивания заполнить transferData данными, иначе какой смысл что-то перетаскивать?
Кстати, я в примере обнаружил интересную фичу: ты не обязан перетаскивать именно див. Ты можешь взять выделить любой текст в любом приложении и перетащить его на див или даже файл. Он реагирует на любые перетаскиваемые данные.
Скорее всего проблемы из-за особенностей саблайма под твой дистрибутив линукс. Видимо перетаскивание он поддерживает не во всех графических средах.
Ответ неправильынй получается, должно быть 61270 во втором банке.
Также, нельзя выходить изцикла если сумма < 5000 так как на нее могут начислиться проценты и получится больше 5000, а ты это не учел.
>>509967
Если изучать все постепенно, а не браться сразу за сложное, все можно понять.
> На данный момент могу создать гостевуху с формой отправки
В разных компаниях требования разные.
> еще немного закрепить имеющиеся на данный и ходить по собеседованиям и проситься работать за еду в надежде на то, что в рабочих условиях я получу новые знания
Ты можешь их и не получить если например найдешь какую-то дноконтору где тебя посадят править верстку на вордпрессе.
А так, помотри вакансии, почитай требования.
Если хочешь учиться, у нас в ОП посте хорошие задачи про список студентов и файлообменник.
>>509991
В Оп посте есть задачки на SQL, JS, есть Путь HTML. Там правда теории особо нет, но задчки очень полезные, те кто их решли, стали значительно лучше эти технологии знать.
Алсо, я бы хотел чтобы бамплимит подняли хотя бы до 700-800 постов. Треды переполняются с огромной скоростью.
Добро пожаловать в 2015.
Кроме того, с недавнего времени я тут сру.
Обещаю поумерить скорость постинга, не флудить и задавать только конкретные, а не абстрактные вопросы.
Задачи это неплохо, конечно, но хотелось бы для начала теории почитать перед решением задач.
Действительно. Ну в таком случае пошел читать. Спасибо.
https://github.com/soulsteel/studentProject
Заранее спасибо за конструктивную критику.
Чтобы знать, могу ли я стать полноценным пхп-программистом или забить.
Только попробовав программировать. К тому же, имей ввиду, что тебе должно как минимум нравиться заниматься этим, иначе далеко не уйдёшь.
Вот этот прав. Я, когда выполняю очередную задачу опа, поебавшись день-другой да-да, я даун, прямо-таки фонтанирую от радости, что моя программа заработала. Мне это нравится.
Кстати. Решаю сейчас задачу про айпад. Вчера ебался весь вечер с ней, а сегодня утром встал и написал, как будто во сне уже обдумал все решение.
Только есть одно но: в условии строуберрибанка есть плата за открытие счета, которую надо сделать единожды, а не через цикл. Не могу понять, как сделать это. Помогите, антошки.
Решаю эту же задачу, только понять, что делать совсем не могу.наверн я совсем тупой
Подскажите, что как.
Сама задача : Школьник решил купить айфон и для этой цели взял кредит. Сумма кредита — 40000 р., банк каждый месяц начисляет 3% за пользование кредитом и 1000 р. комиссии (да, а ты думал, обойдешься процентами?). После этого, тоже каждый месяц, наш герой идет в банк и платит 5000 р (сэкономленных на школьных завтраках). Вопрос, когда он избавится от долга? Во сколько школьнику обошелся айфон?
То есть, каждый месяц банк начисляет процент и комиссию, увеличивая долг, и каждый месяц школьник его потихоньку выплачивает.
Исправь и переделай программу, чтобы она работала нормально. Например, эта версия позволяет школьнику переплатить за кредит, так, что банк ему становится должен — это плохо! Подсказка: перед тем, как платить, надо проверять, сколько осталось долга, и если он меньше 5000, то платить только остаток и завершать цикл через break
Это копия, сохраненная 24 июля 2015 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.