Двач.hk не отвечает.
Вы видите копию треда, сохраненную 13 августа 2015 года.

Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее

Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
33 Кб, 500x500
157 Кб, 1024x683
321 Кб, 1024x576
223 Кб, 640x359
Клуб изучающих PHP #54 #510035 В конец треда | Веб
Добро пожаловать в наш уютный тредик. Тут мы изучаем язык PHP (а также JS/CSS/HTML/SQL), решаем задачки и даже делаем простые сайты! Зачем? Кто-то хочет научиться программировать, кто-то - делать сайты, кто-то - просто размять мозги и заняться чем-то полезным.

Почему PHP? Потому что фейсбук и википедия на нем написаны, и вакансий море, и учить легко.

Это тред для начинающих. Не написал за свою жизнь ни одной программы? Ты наш человек.

Устанавливать пока что ничего не требуется, разве что редактор кода вроде Sublime Text 3, Notepad++, Netbeans PHP или PhpStorm (с ним будет удобнее).

Предыдущий тред был тут: >>503607

Что самое главное для программиста? Умение аккуратно оформлять код (читай второй пост).

Правила: ведем себя воспитанно, помогаем новичкам, постим ссылки на решения задачек, ОП их проверяет и дает советы и замечания. ОП отвечает даже на самые нубские вопросы. ОП заходит где-то раз в день-два, не жди его, решай задачки дальше.

У нас есть уроки по основам 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) когда тебе не надо тратить время на поиск заказов и переговоры с неадекватными заказчиками.
56 Кб, 500x644
34 Кб, 650x384
Прочти #2 #510036
Код нужно написать не как попало, а аккуратно и по правилам. Почему? Потому, что на неакуратно написанный код не хочется даже смотреть.

Если тебе лень выравнивать код руками, закачай его на 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, то рассказать об этом стоит в каком-нибудь другом треде.

Ах да. Если тебе кажется, что что-то в учебнике или задачах можно сделать лучше — пиши, обратная связь всегда очень полезна.
56 Кб, 500x644
34 Кб, 650x384
Прочти #2 #510036
Код нужно написать не как попало, а аккуратно и по правилам. Почему? Потому, что на неакуратно написанный код не хочется даже смотреть.

Если тебе лень выравнивать код руками, закачай его на 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, то рассказать об этом стоит в каком-нибудь другом треде.

Ах да. Если тебе кажется, что что-то в учебнике или задачах можно сделать лучше — пиши, обратная связь всегда очень полезна.
#3 #510048
Аноны, которых я проверю, но не сегодня:

>>507754 Анон, зацени файлообменник: http://rocketfiles.zz.mu/

>>507767 https://github.com/V3N0m21/Uppu3

>>508294 https://github.com/blackberryJam/abiturients

>>508913 https://github.com/Si0n/register3

Другие аноны:

>>506998

Ответ неправильынй получается, должно быть 61270 во втором банке.

Также, нельзя выходить изцикла если сумма < 5000 так как на нее могут начислиться проценты и получится больше 5000, а ты это не учел.
#4 #510051
Если я кого-то пропустил, напомните о себе.
#5 #510071
>>510048
Роскошный дизайн все-таки у этого чувака с рокетфайлз.
Интересно бы знать, где подсмотрел макет, и как называется такой стиль.
Схоронил себе названия шрифтов (BravoRegular для заголовков, ArianAMUSerifRegular для контента).

Давеча прочитал книгу Robin Williams (как ни странно, это она, а не он) "Дизайн для недизайнеров". Несмотря на дурацкое название, книга оказалась ну очень хорошей. Объясняются именно принципы хорошего дизайна, такие как контрастность, группировка смысловых элементов, выравнивание по базовым линиям, повторение элементов, резервирование большого кол-ва пустого пространства, благодаря чему страница выглядит неперегруженной и легкой.

Вот в этой работе все есть. Все элементы выровнены, шрифты грамотно подобраны, хорошая контрастность и акцент внимания посетителя на важных объектах, большое количество свободного места.
Для сравнения можно посмотреть работы быдлокодеров http://rutracker.org/forum/viewtopic.php?t=2891516 Так верстать нельзя.
Все как один уныло копируют стандартные темы вордпресса с небольшими вариациями, иногда с жалкой претензией на оригинальность, вроде аляповатых вензелей, или большого количества картинок на заднем плане, которые утомляют и перегружают интерфейс.

Кстати, вопрос по шрифтам. Можно ли сейчас использовать ну любой шрифт, какой я найду в интернете? Раньше шрифт обязан был быть на машине пользователя, но сейчас как бы 21 век, и можно выбросить на помойку ариал с таймсом, все красивые шрифты вроде бы можно подгрузить джаваскриптом с каких-нибудь облачных хранилищ гугла или яндекса, как я слышал.
Какие есть недостатки у такого подхода?

>>510051
Ты мне за неймспейсы не до конца пояснил. >>509823
#6 #510074
>>510071
Нет, даже не внешние хранилища. Шрифт можно сохранить у себя на сервере http://rocketfiles.zz.mu/app/templates/default/css/fonts.css

Но с этим наверняка связана куча подводных камней, интересная тема.
http://htmlbook.ru/css/font-face

>Браузер Internet Explorer до версии 9.0 поддерживает только шрифты формата EOT (не нужны)


>Opera в некоторых случаях может не показывать на веб-странице текст выбранным шрифтом, заменяя его стандартным. Причём для локальных документов всё работает корректно. Это происходит в тех случаях, когда имя пользователя в Windows написано кириллицей.


http://caniuse.com/#search=font-face
Опера-мини подкачала.

Еще сюрпризы?
#7 #510078
>>510071

Приятно конечно читать такие отзывы :3 Дизайн я честно спиздил отсюда: http://www.xfilesharingtemplates.com/classic-xfilesharing-pro-theme.html

Изначально хотел другой шаблон у них спиздить, там где космос и ракета с космонавтами на фоне, долго сидел в фотошопе и гугле, пытаясь что-то родить более-менее стоящее, но в итоге плюнул на это дело, т.к. годных картинок близких по стилю друг к другу я не нашел. А сам рисовать не умею. В итоге пришлось другой выбрать, попроще.

Кстати, у них сайт какой-то ебанутый. Когда заходишь туда, то через некоторое время тебе какой-то долбоеб начинает писать навязчиво, мол хули ты тут лазиешь? Один даже грозился меня по ай пи забанить, лол.

Любые шрифты через font-face подключаются. Если где-то в старых версиях IE или еще где-то не поддерживается, то и хрен с ними. Шрифты то эти для красивостей, функционал сайта никак не пострадает.
#8 #510100
>>510071

Да, у него есть способности к хорошему оформлению, к подбору гармонирующих шрифтов/цветов, но там есть и небольшие косяки, например некоторые иконки бессмысленные (и лучше были использовать просто абстрактный маркер), да и для файлообменника мне дизайн кажется перегруженным (например блоки с булшит-текстом имхо лишние), мне больше нравится такой стиль: http://ya.ru/, это конечно мое имхо, но я бы выпилил галочку, булшит-тексты, плашку под формой, уменьшил логотип раза в 2, ужал футер, шапку бы сделал чуть менее тяжелой.

Некоторые надписи плоховато читаются из-за слишком узких и мелких букв, некоторые места (форма логина вверху) слишком слабоконтрастны.

На большой ширине экрана (можно увидеть, уменьшив масштаб) табы на форме разваливаются — значит, они сверстаны неправильно.

В анимации переключения табов тоже есть косяк — некоторые элементы (кнопка загрузить например, чекбокс) просто мигают, но остаются на своих местах. Зачем тогда их анимировать? Это только отвлекает внимание, они не должны мигать.

В поле для ссылки забыт паддинг слева/справа.

Красная буква N в футере наверно лучше бы смотрелась если была чуть посветлее, так как она на темном фоне.

На большой ширине экрана ссылки в футере сильно растекаются в ширину, надо было ограничить ее, чтобы она примерно совпадала с шириной булшит блока.

Но это все в общем не очень значительные замечания, в общем сделано хорошо. Я уверен, что если анон будет дальше развиваться, читать книги по юзабилити и дизайну, изучать другие сайты, сидеть на дрибббле, он вполне сможет стать хорошим дизайнером.

А вот это вот серьезный косяк:

>\t<meta name="viewport" content="user-scalable=no">


Анон, ты явно откуда-то это скопировал и зря, ты делаешь свой сайт непригодным на мобильных устройствах. Где тут вообще логика, почему надо запрещать изменение масштаба?

Бутстрап мне кажется тут не особо нужен, так как от него в дизайне нет и следа, никакие виджеты не используются.
#9 #510102
>>510035
Вот объясните мне, как сделать это:
У меня есть time13.php нужно запускать его каждые 13 секунд доступ в ssh есть

На хабре какая-то длинная статья - я нихуя не понял. жаваскриптовский Set Time Out применить к пхпшному include time.php не получается. Что же делать?
#10 #510104
>>510071

> Все как один уныло копируют стандартные темы вордпресса


Может им просто мало денег платят и они спешат. А может конечно просто не умеют нормально делать.

> Кстати, вопрос по шрифтам. Можно ли сейчас использовать ну любой шрифт, какой я найду в интернете?


Тут есть вопрос авторского права. Ты не можешь просто так скопировать себе любой шрифт.

Но есть сайты вроде google fonts где собраны свободные для использования в интернетах шрифты.

Если ты хочешь хостить их на своем сайте, почитай статьи, разным браузерам нужны разные форматы, и надо писать специальный CSS код чтобы везде работало.

> Какие есть недостатки у такого подхода?


раньше мануал PHP использовал стандартный шрифт. Я щелкал по ссылке из гугла, он открывался и сразу был доступен. Теперь они решили поставить модные шрифты, которые в сумме (8 начертаний) весят больше мегабайта. Пока шрифт не загружен, браузер не отрисовывает текст. Часто бывает, что я кликаю по ссылке в гугле и секунд 5-10 смотрю на страницу без текста.

Это явно пример того, как делать не надо.

Но с другой стороны, если ты делаешь промосайт с оригинальным дизайном, там это уместно, но стоит заняться оптимизацией всего этого дела, есть разные способы, например вырезание лишних символов.
#11 #510105
>>510102
while []; do
time13.php
sleep 13
done;
#12 #510107
>>510100

Косяки из-за того, что у меня по сути нет нормального PSD макета и я все по ходу делаю, прикидывая на глаз. Из-за этого приходится переделывать потом и про некоторые вещи забываю. В частности, изначально я хотел адаптивную версию делать, поэтому и использовал бутстрап. Но потом в процессе передумал.

Когда уже есть готовый макет со всем необходимым, то в разы проще все это делается, без всяких глупых косяков.
#13 #510108
>>510071

> Ты мне за неймспейсы не до конца пояснил


Я могу ошибаться, но по моему там написано что когда ты используешь динамический вызов класса или функции:

new $a
$b()

то ты должен использовать абсолютное имя, и текущий неймспейс к нему сам не добавляется.

Если бы ты писал так:

new Class
func()

То все бы работало как надо.

Я думаю, это происходит по той причине, что неймспейсы обрабатываются на этапе компиляции, PHP просто заменяет краткие имена на полные. А имя в твоей переменной он разумеется в этот момент заменить не может.
#14 #510111
>>510108
А, вот оно что. Акцент делался именно на динамическом вызове (это когда имя класса или функции является строкой, хранящейся в переменной, да?).

Мутный мануал, сложно что-то понять. Хотя конечно по сравнению с другими технологиями, где в доках даже не делается попыток что-то объяснить, этот еще ничего, да.

Эх, сплошная безблагодатность с такой учебой. Хорошо хоть ты иногда понятно объясняешь.
#15 #510112
>>510078

Ну по моему оригинал смотрится хуже.

Насчет font-face надо нагуглить правильный способ подключения, там довольно заморочная конструкция, где-то на хабре это есть (это может? правда довольно старая статья http://habrahabr.ru/post/113136/ ) и на fontsquirrel генератор хороий код генерирует.

>>510107

Ну да, но за запрет масштабирования все же тебе большой минус.

>>510102

Добавляешь в крон, или что лучше, в автозагрузку под супервизором вечноживущий php-скрипт который раз в 13 секунд запускает то что надо.

Ну и желательно какой-то таймаут сделать, чтобы он прибивал его при превышении времени или не запускал новую копию пока старая не завершится.

В помощь тебе posix функции:

http://php.net/manual/ru/book.posix.php
http://www.google.ru/search?aq=f&sourceid=chrome&ie=UTF-8&q=php+pcntl
#16 #510113
>>510107

Да бутстрап не нужен для адаптивности, вся адаптивность сводится к дописыванию нескольких @media правил. Мне кажется в твоем случае тебебольше училий приходится тратить на обход стилей бустрапа и с нуля было бы проще написать и код был бы чище.
#17 #510119
>>510107

Ну и я тебе советую еще почитать книги по юзабилити (если ты еще не читаешь). Дизайн это не только подбор шрифтов и цветов, это еще проектирование взаимодействия пользователя с приложением. Соответственно, если в нем не разбираться, можно сделать красивую, но не очень удобную форму.

Из того, что я сам читал, могу посоветовать:

Алан Купер, Психбольница — небольшая книга вводного уровня, которая в основном посвящена примерам неправильного проектирования и к чему это приводит, и на этих примерах автор наглядно показывает почему проектирование взаимодействия важная вещь.

Раскин, Интерфейс — книга небольшая, рассказывет про разные элементы компьютерных интферйесов и подходы к их проектированию. Раскин известный чел, он проектировал ОС для первых макинтошей и многие привычные элементы интерейса он же и придумал.

Он расскажет почему плохи режимы, как померять эффективность интерфейса, как подписывать кнопки, почему нам нужны гермафродитные кабели.

Ну и есть еще большая, толстая, подробная книга, это Алан Купер, об интерфейсе. Там рассказывается не только про элементы интерфйеса, но и про подходы к проектированию, например, про сценарии и персонажей.

Это те книги котрые у меня есть и которые я сам читал, наверно есть еще и другие.

Ну и еще я читал книгу «Живая Типографика», это книга про буквы и шрифты, она интересная, в ней много картинок и после ее прочтения такие шутки станут тебе очень понятны: https://pbs.twimg.com/media/BJlXnQzCUAQVo9_.jpg:large

А, и еще, советую смотреть работы других дизайнеров, на дрибббле, на behance.
#18 #510124
>>510105
Правильный код?

do {
include 'time13.php';
sleep(13);
done;
}
while [];
#19 #510126
бумп из прошлого треда: https://github.com/Si0n/register3
#20 #510127
>>510124
что в while писать? он на пустых скобках ошибку выдает.
#21 #510129
>>510102
Короче я нихуя не понял, чо нужно делать и поставлю просто вот это
<META HTTP-EQUIV='Refresh' CONTENT='13; URL=time13.php'>
#22 #510148
>>510035
Тут же можно нубские вопросы создавать вот я и создам, что если я создам библиотеку со всеми словами что используются на сайте и в коде вместо них будет что-то вроде указателей насколько сократится разамер сайта и как повлияет на скорость загрузки? а что если подобной херней прострадать в плюсах (не веб)?
#23 #510151
>>510129
Поставь в «iframe», а нужен тебе был AJAX, со временем разберёшься.
#24 #510153
>>510148

Это уже сделали, называется архиватор. Ресурсы можно передавать по сети в сжатом виде, сервера умеют сжимать данные, а браузеры — распаковывать.

Почитай например про gzip — он делает то что ты описал

http://habrahabr.ru/post/221849/
http://habrahabr.ru/post/235553/

В общем такие вещи надо делать не руками, а автоматизиорованно.
#25 #510155
>>510153
можно сжать сразу весь сайт?
#26 #510199
>>510113

Без бутстрапа этих @media правил будет нихуя не несколько.

>>510119

Спасибо конечно за ссылки, но я не веб-дизайнер и становится им не собираюсь. Книжки может читану конечно.
#27 #510258
Куки в суперглобальный массив записываются только после передачи HTTP-заголовка, да?
#28 #510275
Есть одна форма. Она может быть заполнена верно или нет. В зависимости от этого мы выводим сообщение об ошибках с их перечислением или о том, что форма заполнена успешно. В первом случае под сообщение берётся красная плашка, во втором -- зелёная.
Какое решение вижу я: после анализа переданных через форму данных скрипт записывает в переменную сообщения об ошибках (или о том, что всё верно) и тип самого сообщения (красное, зелёное). Эта переменная -- массив.
Вопрос: как правильнее передавать переменную между скриптами: через cookie+serialize(), а после вывода стирать куку или воспользоваться возможностями сессий?
Да, делаю задачу про студентов.
#29 #510284
Всем здоровья.

Мне тут нужно postgresql на debian поставить, а он вот что пишет

И локаль по пизде пошла, уже 3 часа тыкаюсь и поправить не могу

Помогите по старой памяти, госопда.
#30 #510285
>>510275
ОП мне советовал пользоваться его уроком по формам https://github.com/codedokode/pasta/blob/master/forms.md
Там не нужно будет передавать данные между скриптами
43 Кб, 796x358
90 Кб, 773x590
#31 #510286
>>510284
Скрины проебал
#32 #510289
>>510285
Всё равно не вижу, как реализовать это без передачи данных. Данные студента-то передавать между скриптами не требуется, да.
Но речь о других данных.
Вот сам класс: https://github.com/blackberryJam/abiturients/blob/master/app/classes/UserpageController.php
Закомменченный кусок кода -- создание описанного массива.
#33 #510293
>>510289
Я и говорю, что сами $errors и $values не надо передавать между скриптами, проверка на них должна быть в том же скрипте где и их заполнение.
#34 #510297
>>510293
А если я хочу их вывести в хтмл? values-то ладно, они в БД пишутся, вытащить можно. А errors?
#35 #510299
Подойдет эта книжка для изучения sql + mysql Бьюли Алан "Изучаем SQL" 2007 г. Или оче старая?
#36 #510303
>>510289
Если нужно вывести сообщение об успешной регистрации (или о неправильно введенных данных), то можно отредиректить на ту же страницу гетом, а данные об успехе/ошибке передать через гет-переменную ?reg=ok или ?reg=error&field=fieldName&value=falseValue

В шаблоне уже подставлять значения ошибок. Например:
if (isset($_GET['error'])) {
if(isset($_GET['fieldName']) and isset($_GET['falseValue'])) {
$errorMsg = "Поле $fieldName может содержать только символы русского алфавита, вы ввели $falseValue";
}
}

Я бы сделал так. Но лучше подожди опа, я не уверен что это лучший способ.
Можно еще передавать данные через сессии и куки, но это муторно и неудобно, мне кажется.
#37 #510307
>>510303

>Можно еще передавать данные через сессии и куки, но это муторно и неудобно, мне кажется.


Почему неудобно? Ну куки -- да, там только строку можно передать (если не использовать serialize), а с сессиями, по-моему, очень просто: стартуем сессию, кладём данные в суперглобальный массив, вытаскиваем их в другом скрипте.
#38 #510315
>>510297
Подключи в конце скрипта шаблон формы где проверишь ошибки и выведешь их + $values
#39 #510319
>>510315
Если бы всё так было просто. У нас же после задания значений values и errors редирект и exit.
#40 #510320
>>510319
Ну так редирект идет на тот же файл, или нет?

В скрипте index.php можно написать
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// обработка запроса
}
// а здесь формируем шаблон для вывода. Данные об ошибке берешь либо из сессии, либо из гет-переменных, неважно.
#41 #510323
>>510320

>Данные об ошибке берешь либо из сессии, либо из гет-переменных, неважно.


Ну так вопрос и был в том, какой из способов наиболее оптимальный и правильный. Куки, сессии, гет-переменные или (лол) отдельная таблица под ошибки в БД?
#42 #510336
>>510299
Книг выходит очень много, вряд ли здесь найдется человек, который читал их все, эту в частности и может дать рецензию. Я посмотрел на рутрекере, хомячки вроде в восторге. Но говорят, что переведена кривовато.

А так mysql развивается не так бурно, как php например. Так что 2007 год вполне сойдет, 95% информации актуально.
За это время может добавились какие-то новые возможности, но если ты начинающий, то главное понять базовые вещи, а какие-то нововведения можно изучить потом.

Лично мне понравилась книга Бейли "Изучаем SQL" 2012 года, издательство O'Reilly.
Очень большой акцент делается именно на когнитивной части, то есть чтобы учащемуся было приятно и интересно (хотя со смищными картинками они перестарались конечно). Есть на торрентах.

Когда дойдешь до изучения более сложных вещей, тех же юниксов например, офигеешь от отвратительной подачи материала.
На учащегося вываливают гору бессвязной справочной информации, мол сиди и зубри наизусть. На такое согласится только совсем опущенный унтерменш без личной жизни.
#43 #510362
>>510336

>А так mysql развивается не так бурно, как php например. Так что 2007 год вполне сойдет, 95% информации актуально.


Да, я и имел ввиду это, спс
#44 #510379
>>510323

Прочел мой урок про формы? Ты редиректишь только при успешной обработке формы (чтобы при обновлении страницы запрос не отсылался). при ошибке надо не редиректить, а выводишь форму с ошибками.

А ты редиректишь всегда. Из-за этого и проблемы. Посомтри алогритм обработки форм внимательно, там мы при ошибке не редиректим.
#45 #510382
>>510379
Ок, понял.
185 Кб, 719x698
#46 #510386
Ребята, работал ли кто-нибудь с mailchimp?
Не могу сообразить, как у них в api v3 все работает, и где мой php класс.
Очень надо.
#47 #510389
>>510303

Это плохой способ, так как при редиректе мы теряем введенные в поля значения. У меня в уроке про формы описан алгоритм, почему бы просто не сделать как там написано? Все тогда будет работать.

Решения с куками, сессиями и таблицами не пройдут, и не надейтесь. Нечего велосипедостроительством заниматься.
#48 #510390
Почему в вебе до сих пор редко используют 3D?
http://special.habrahabr.ru/slemma/
#49 #510396
>>510390

А что текст в 3Д лучше читается чем плоский?

Алсо у меня например WebGL не работает на ноуте вообще. Так как видеокарта не поддерживается. ТОлько CSS трансформации работают, но без аппаратного ускорения.
#50 #510406
>>510396
Для логотипчиков и иконок вполне можно. По-моему неплохо
#51 #510416
>>510389

>Решения с куками, сессиями и таблицами не пройдут, и не надейтесь. Нечего велосипедостроительством заниматься.


С выводом ошибок проблемы нет.
А если мы хотим вывести сообщение о том, что данные успешно добавлены/обновлены? После редиректа.
#52 #510425
>>510416

Есть варианты с использованием кук/сессий (flash сообщения), а можно просто при редиректе параметр добавлять: /index.php?message=saved
#53 #510443
>>510425

>flash сообщения


Тогда такой вариант нормален?

setcookie('messageSuccess', $messageSuccess, time() + 600);
header('Location: ...');
exit;

А вывод делаем таким:
if (array_key_exists('messageSuccess', $_COOKIE)) {
render($_COOKIE['messageSuccess']);
setcookie('messageSuccess', '', time() - 1);
} else {
render();
}
#54 #510451
>>510443

Только не стоит вписывать систему сообщений прямо в код. Сделай функции или методы для установки сообщения, прочтения сообщения, удаления. Также, вместо текста сообщения лучше хранить идентификатор, так как объем кук ограничен.

Куки имеют недостаток, что они менее надежны (например: при загрузке страницы произошла ошибка, пользователь обновил страницу, но сообщение он уже не увидит) и что они общие для всех табов, и в неудачном случае сообщение от одного таба может вывестись в другом (хотя это конечно надо постараться так сделать).
#55 #510452
>>510443

Ну да, это сойдет, если вынести все в отдельные функции.
#56 #510453
>>510451
Значит, правильнее использовать сессии аналогичным образом? Сохранять, а после вывода чистить.
#57 #510457
>>510453

Так сессии тоже общие для всех вкладок и точно также сообщение не будет прочитано при ошибке загрузки страницы.

Исправить проблему с выводом сообщения при обрывах связи можно, если удалять сообщение не на севрере, а на клиенте, яваскриптом, после того как страница точно загрузилась. Но по моему не стоит с этим заморачиваться, это лишнее усложнение, в принципе не очень страшно если уведомление потеряется.
#58 #510462
>>510457
Хорошо, вернусь к теме подобных сообщений, когда познакомлюсь с JS.
#59 #510468
>>510462

Сделай пока по-простому как-нибудь.
#60 #510472
>>510468
Я, наверное, пока уберу все эти цветные плашки. Просто текстом ошибки выведу. А успешно отредактировалось или нет -- и так видно по содержанию формы.
#61 #510479
>>510472

Нет, надо бы сделать уведомление. Потому что когда ты просто получаешь форму, непонятно все ли в порядке или это баг какой-то.

> Я, наверное, пока уберу все эти цветные плашки. Просто текстом ошибки выведу.


А это зачем? Мы же вроде говорили про flash уведомления, а не про ошибки в форме.
#62 #510484
>>510479
Ну сначала у меня была мысль сделать общий механизм как для успешного варианта отправки формы, так и не успешного (с выводом ошибок).
Но теперь сделаю вывод ошибок как в уроке, а генерировать успешное сообщение будет другая часть кода.
#63 #510504
Решил поизучать заголовки ответа сервера.
Например
Connection:Keep-Alive
Гугл перекинул меня на википедию https://ru.wikipedia.org/wiki/Постоянное_HTTP-соединение
Постоянное HTTP-соединение — использование одного TCP-соединения для отправки и получения множественных HTTP-запросов и ответов вместо открытия нового соединения для каждой пары запрос-ответ.

Учитывая, что я не знаю что такое TCP-соединение, мне это мало о чем говорит. Я догадываюсь, что соединяясь с указанным хостом example.com, клиент будет запрашивать все последующие ресурсы (картинки, стили, скрипты) через одно и то же соединение, а не открывать каждый раз новое.
По ссылке про TCP в вики совсем непонятная фигня.

ОП, кроме талмуда Олифер по сетевым технологиям, есть чо покороче? Я посмотрел по оглавлению, TCP объясняется на 482 странице, я дошел только до 58. Я так с голоду помру, пока дочитаю. А пропускать скорее всего нельзя, иначе будет непонятно.

curl -v http://test/hello.php
Hostname was NOT found in DNS cache
Trying 127.0.0.1...
Connected to test (127.0.0.1) port 80 (#0)
Это и DNS-адреса где-то кешируются получается?

> GET /hello.php HTTP/1.1


> User-Agent: curl/7.35.0


> Host: test


> Accept: /


Что такое Accept
/* ?

О, нашел какой-то симпатичный бложек по http. Надо почитать. ОП, посмотри опытным взором, хороший источник или нет:
http://www.http11.ru/
Дизайн выглядит приятно (это важно, я не буду читать неотформатированную стену текста), и вроде бы аффтар жжот.
#63 #510504
Решил поизучать заголовки ответа сервера.
Например
Connection:Keep-Alive
Гугл перекинул меня на википедию https://ru.wikipedia.org/wiki/Постоянное_HTTP-соединение
Постоянное HTTP-соединение — использование одного TCP-соединения для отправки и получения множественных HTTP-запросов и ответов вместо открытия нового соединения для каждой пары запрос-ответ.

Учитывая, что я не знаю что такое TCP-соединение, мне это мало о чем говорит. Я догадываюсь, что соединяясь с указанным хостом example.com, клиент будет запрашивать все последующие ресурсы (картинки, стили, скрипты) через одно и то же соединение, а не открывать каждый раз новое.
По ссылке про TCP в вики совсем непонятная фигня.

ОП, кроме талмуда Олифер по сетевым технологиям, есть чо покороче? Я посмотрел по оглавлению, TCP объясняется на 482 странице, я дошел только до 58. Я так с голоду помру, пока дочитаю. А пропускать скорее всего нельзя, иначе будет непонятно.

curl -v http://test/hello.php
Hostname was NOT found in DNS cache
Trying 127.0.0.1...
Connected to test (127.0.0.1) port 80 (#0)
Это и DNS-адреса где-то кешируются получается?

> GET /hello.php HTTP/1.1


> User-Agent: curl/7.35.0


> Host: test


> Accept: /


Что такое Accept
/* ?

О, нашел какой-то симпатичный бложек по http. Надо почитать. ОП, посмотри опытным взором, хороший источник или нет:
http://www.http11.ru/
Дизайн выглядит приятно (это важно, я не буду читать неотформатированную стену текста), и вроде бы аффтар жжот.
136 Кб, 981x702
#64 #510527
Ищу дизайнеров для обмена знаний. Хочу запилить для себя CSS-фреймворк, но мне не хватает красивых элементов. Я поделюсь своими рюшечками, а вы своими. А то заебалось сохранять куски кода на jsbin.com, а потом искать пару часов в закладках. На пике часть рюшечек, остальное где-то валяется.

Отзовитесь, няши.

inb4: не туда зашёл
#65 #510553
>>510504

Сейчас кратко расскажу что такое TCP (и как работает интернет). По умолчанию, протокол IP на котором построен интернет, имеет такие особенности:

— узлы сети могут обмениваться небольшими (до 1.5Кб) пакетами друг с другом
— каждая подключеннная к сети сетевая карта имеет уникальный IP адрес, который позволяет определить отправителя/получателя пакета. заметь, я пишу «каждая сетевая карта» так как у узла может быть несколько сетевых карт, причем подключенных к разным или одной сети
— пакеты доставляются по принципу «best effort», нет гарантий что пакеты придут в том же порядке в котром отправлены, и что они придут вообще

Конечно возможность обмениваться пакетами с любым узлом сети в мире это хорошо и в даже наверно можно считать научным достижением, но с такой системой работать неудобно. Что если тебе надо послать информации больше чем 1.5 килобайта? Как пересылать большие файлы? Что делать если пакет не придет? Если на компьютере запущено несколько работающих с сетью программ, как понять для какой из них пришел пакет? Как сделать двунаправленный надежный канал передачи?

Для решения этих проблем сделаны более высокоуровневые протоколы.

Проблема маленьких пакетов решается тем, что информация разбивается на части и в пакет пишется номер этой части (заметь что по прежнему есть проблема, а что если одна из частей не придет?). Проблема какой программе адресован пакет решается добавлением в пакет числа — номера порта. Программа, желающая работать с сетью, резервирует в ОС уникальный номер порта для себя («открывает порт»).

Ты еще можешь услышать термин «сокет». Сокет — это специальная структура, которая описывает UDP или TCP соединение между 2 узлами и соединение идентифицируется 2 IP адресами и 2 номерами портов (получателя и отправителя). То есть UDP и TCP соединения устанавливаются между программой-отправителем и получателем, а не просто узлами.

Вот эти протоколы:

— сигнальный (сигнальный значит что он не передает файлы и данные, а только сообщения вроде того что узел недоступен) протокол ICMP — он позволяет передавать в IP пакетах информационные сообщения, например роутер может отправить сообщение о том что узел-адресат недоступен. Команды ping/traceroute (проверка доступности хоста и проверка каким путем идут пакеты), про которые ты наверно слышал, работают, посылая ICMP echo request пакеты, на которые хосты отвечают. ICMP не использует порты.

Он неплохо описан тут: https://ru.wikipedia.org/wiki/ICMP

— протокол передачи датаграмм UDP. Этот протокол позволяет отправить датаграмму (кусок данных) на указанный порт указанного узла. Он разбивает датаграмму на части, передает в виде нескольких IP пакетов, а на другом узле собирает. Если один из пакетов не пришел, то UDP отбрасывает его. UDP таким образом не гарантирует доставку, но решает проблему маленьких пакетов приходящих в случайном порядке. UDP используется там где нужна минимальная задержка, а потери данных приемлемы — передача голоса, видео в скайпе, сетевые игры

— протокол TCP. Это надежный протокол, который организует двунаправленный канал связи с заданным портом на заданном узле. Он позволяет пересылать по этому каналу в обе стороны поток данных неограниченной длины. TCP также исплоьзует подтверждение полученных данных и повторную пересылку пакетов при их потере. Скорость передачи подбирается автоматически в зависимости от скорости сети и числа потерь пакетов. Платить за это приходится чуть большей задержкой, так как при TCP мы должны ждать подтверждения того, что удаленный узел получил данные. TCP исплоьзуется в большинстве других протоколов, в том числе HTTP.

Заметь, главная разница в том что UDP просто шлет датаграммы, без подтверждений что они получены, а TCP устанавлвивает именно надежный канал передачи данных, который либо передает данные без ошибок, либо разрывается (и отправитель об этом знает).

Ну и передача видео/голоса по TCP плохая идея, так как тот при утере пакета сначала какое-то время ждет пока он придет, а потом отправляет просьбу выслать его повторно, и если этот пакет с просьбой теряется, то мы получаем еще большую задежрку. Потому голос/видео передают по UDP, причем используются такие кодеки, которые могут работать при потере части данных, ухудшая при этом качество картинки/звука.

Собственно возвращаясь к Keep_Alive. Без него для каждого нового запроса создается новое TCP соединение. С ним мы переиспользуем существющее соединение, посылая новый запрос после получения ответа от сервера. Также, есть pipelining — это когда отправитель шлет запросы не дожидаясь получения ответа, и соответственно потом получает несклоько ответов сразу.

Профит в том что мы экономим время на установку нового соединения, котрое требует обмен 3 пакетами (TCP handshake). Если пакет идет допустим из России в США 100 мс, то 3 пакета это 300 мс.

Для того чтобы это работало, получатель должен как-то понять что сервер закончил передавать данные (по умочланию признаком завершения является закрытие соединения сервером). для этого сервер должден либо указать длину тела ответа с помощью Conetnt-Length, либо использовать способ передачи вроде TRansfter-Encoding: chunked который содержит признак конца данных.

Бложек выглядит нормально но он по моему просто заточен под набирание веса в Гугле.

Почитай-ка вот эти статьи, они конечно по отдельности не идеальны, но вместе, я думаю, дают общую картину:

http://kunegin.com/ref3/tcp/glava4.htm
http://habrahabr.ru/post/209144/
http://book.itep.ru/4/44/udp_442.htm
http://www.chin28.narod.ru/d10.1.htm

Для полного понимания конечно было бы хорошо написать программу-клиент и программу-сервер, которые бы обменивались UDP датаграммами или общались через TCP соединение. Например, что-нибудь вроде чата между 2 консольными программами. Это было бы конечно полезно, но я не знаю, есть ли у тебя на жто время.

Но позже если ты например захочешь изучить вебсокеты, знание TCP и сетевого программирования было бы полезно.

В качестве мини-практики можешь сделать такие вещи:

— попробуй попинговать узлы ya.ru, google.com командой вроде ping goog.com
— попробуй определить путь к узлу, исплоьзуя команду tracert google.com (traceroute если у тебя линукс/мак)
— попробуй соединиться с каким-либо узлом и вручную сделать HTTP-запрос. Для этого установи telnet-соединение (протокол telnet это почти что голый TCP и таким образом команда telnet дает нам TCP канал с указанными хостом/портом) командой

telnet ya.ru 80

Порт 80 это порт используемый по умолчанию для http.

затем набери

GET / HTTP/1.0 (Enter)
Host: ya.ru (Enter)
(Enter)

И получи ответ. Набирать надо быстро (там есть таймаут), если ты не уверен что справишься, можешь набрать текст в редакторе и скопировать.

Если telnet плохо работает или еще чем-то тебе не нравится, можно скачать программу putty (под Windows) или netcat (под линукс) и работать через нее.

Времени это много не занимает, но попробовать сделать HTTP запрос полезно чтоыб лучше понять этот протокол. Попробуй почувстовать себя в роли браузера.
#65 #510553
>>510504

Сейчас кратко расскажу что такое TCP (и как работает интернет). По умолчанию, протокол IP на котором построен интернет, имеет такие особенности:

— узлы сети могут обмениваться небольшими (до 1.5Кб) пакетами друг с другом
— каждая подключеннная к сети сетевая карта имеет уникальный IP адрес, который позволяет определить отправителя/получателя пакета. заметь, я пишу «каждая сетевая карта» так как у узла может быть несколько сетевых карт, причем подключенных к разным или одной сети
— пакеты доставляются по принципу «best effort», нет гарантий что пакеты придут в том же порядке в котром отправлены, и что они придут вообще

Конечно возможность обмениваться пакетами с любым узлом сети в мире это хорошо и в даже наверно можно считать научным достижением, но с такой системой работать неудобно. Что если тебе надо послать информации больше чем 1.5 килобайта? Как пересылать большие файлы? Что делать если пакет не придет? Если на компьютере запущено несколько работающих с сетью программ, как понять для какой из них пришел пакет? Как сделать двунаправленный надежный канал передачи?

Для решения этих проблем сделаны более высокоуровневые протоколы.

Проблема маленьких пакетов решается тем, что информация разбивается на части и в пакет пишется номер этой части (заметь что по прежнему есть проблема, а что если одна из частей не придет?). Проблема какой программе адресован пакет решается добавлением в пакет числа — номера порта. Программа, желающая работать с сетью, резервирует в ОС уникальный номер порта для себя («открывает порт»).

Ты еще можешь услышать термин «сокет». Сокет — это специальная структура, которая описывает UDP или TCP соединение между 2 узлами и соединение идентифицируется 2 IP адресами и 2 номерами портов (получателя и отправителя). То есть UDP и TCP соединения устанавливаются между программой-отправителем и получателем, а не просто узлами.

Вот эти протоколы:

— сигнальный (сигнальный значит что он не передает файлы и данные, а только сообщения вроде того что узел недоступен) протокол ICMP — он позволяет передавать в IP пакетах информационные сообщения, например роутер может отправить сообщение о том что узел-адресат недоступен. Команды ping/traceroute (проверка доступности хоста и проверка каким путем идут пакеты), про которые ты наверно слышал, работают, посылая ICMP echo request пакеты, на которые хосты отвечают. ICMP не использует порты.

Он неплохо описан тут: https://ru.wikipedia.org/wiki/ICMP

— протокол передачи датаграмм UDP. Этот протокол позволяет отправить датаграмму (кусок данных) на указанный порт указанного узла. Он разбивает датаграмму на части, передает в виде нескольких IP пакетов, а на другом узле собирает. Если один из пакетов не пришел, то UDP отбрасывает его. UDP таким образом не гарантирует доставку, но решает проблему маленьких пакетов приходящих в случайном порядке. UDP используется там где нужна минимальная задержка, а потери данных приемлемы — передача голоса, видео в скайпе, сетевые игры

— протокол TCP. Это надежный протокол, который организует двунаправленный канал связи с заданным портом на заданном узле. Он позволяет пересылать по этому каналу в обе стороны поток данных неограниченной длины. TCP также исплоьзует подтверждение полученных данных и повторную пересылку пакетов при их потере. Скорость передачи подбирается автоматически в зависимости от скорости сети и числа потерь пакетов. Платить за это приходится чуть большей задержкой, так как при TCP мы должны ждать подтверждения того, что удаленный узел получил данные. TCP исплоьзуется в большинстве других протоколов, в том числе HTTP.

Заметь, главная разница в том что UDP просто шлет датаграммы, без подтверждений что они получены, а TCP устанавлвивает именно надежный канал передачи данных, который либо передает данные без ошибок, либо разрывается (и отправитель об этом знает).

Ну и передача видео/голоса по TCP плохая идея, так как тот при утере пакета сначала какое-то время ждет пока он придет, а потом отправляет просьбу выслать его повторно, и если этот пакет с просьбой теряется, то мы получаем еще большую задежрку. Потому голос/видео передают по UDP, причем используются такие кодеки, которые могут работать при потере части данных, ухудшая при этом качество картинки/звука.

Собственно возвращаясь к Keep_Alive. Без него для каждого нового запроса создается новое TCP соединение. С ним мы переиспользуем существющее соединение, посылая новый запрос после получения ответа от сервера. Также, есть pipelining — это когда отправитель шлет запросы не дожидаясь получения ответа, и соответственно потом получает несклоько ответов сразу.

Профит в том что мы экономим время на установку нового соединения, котрое требует обмен 3 пакетами (TCP handshake). Если пакет идет допустим из России в США 100 мс, то 3 пакета это 300 мс.

Для того чтобы это работало, получатель должен как-то понять что сервер закончил передавать данные (по умочланию признаком завершения является закрытие соединения сервером). для этого сервер должден либо указать длину тела ответа с помощью Conetnt-Length, либо использовать способ передачи вроде TRansfter-Encoding: chunked который содержит признак конца данных.

Бложек выглядит нормально но он по моему просто заточен под набирание веса в Гугле.

Почитай-ка вот эти статьи, они конечно по отдельности не идеальны, но вместе, я думаю, дают общую картину:

http://kunegin.com/ref3/tcp/glava4.htm
http://habrahabr.ru/post/209144/
http://book.itep.ru/4/44/udp_442.htm
http://www.chin28.narod.ru/d10.1.htm

Для полного понимания конечно было бы хорошо написать программу-клиент и программу-сервер, которые бы обменивались UDP датаграммами или общались через TCP соединение. Например, что-нибудь вроде чата между 2 консольными программами. Это было бы конечно полезно, но я не знаю, есть ли у тебя на жто время.

Но позже если ты например захочешь изучить вебсокеты, знание TCP и сетевого программирования было бы полезно.

В качестве мини-практики можешь сделать такие вещи:

— попробуй попинговать узлы ya.ru, google.com командой вроде ping goog.com
— попробуй определить путь к узлу, исплоьзуя команду tracert google.com (traceroute если у тебя линукс/мак)
— попробуй соединиться с каким-либо узлом и вручную сделать HTTP-запрос. Для этого установи telnet-соединение (протокол telnet это почти что голый TCP и таким образом команда telnet дает нам TCP канал с указанными хостом/портом) командой

telnet ya.ru 80

Порт 80 это порт используемый по умолчанию для http.

затем набери

GET / HTTP/1.0 (Enter)
Host: ya.ru (Enter)
(Enter)

И получи ответ. Набирать надо быстро (там есть таймаут), если ты не уверен что справишься, можешь набрать текст в редакторе и скопировать.

Если telnet плохо работает или еще чем-то тебе не нравится, можно скачать программу putty (под Windows) или netcat (под линукс) и работать через нее.

Времени это много не занимает, но попробовать сделать HTTP запрос полезно чтоыб лучше понять этот протокол. Попробуй почувстовать себя в роли браузера.
#66 #510559
>>510527
Яндексом повеяло. Причем я сначала подумал что это и есть элементы яндекса, пока не прочитал пост.
#67 #510561
>>510559
Так и есть. Часть из них спиздил здеся, но я хочу сиэсэски допилить напильником.
https://ru.bem.info/libs/bem-components/v2.2.1/
#68 #510564
>>510527

Сделай страницу где слева будет виджет, а справа готовый HTML c ним. Такую страницу можно генерировать автоматически если например хранить код каждого виджета в отдельном файле. Я видел такие штуки, и это довольно удобно.
#69 #510566
>>510561

И кстати, раз ты используешь БЭМ-компоненты, можно генерировать эту страницу сразу из них. Это можно делать на PHP или node.js, что тебе ближе.
#70 #510577
>>510566

>можно генерировать эту страницу сразу из них


У меня цель не техническая, а дизайнерская. Хочу визуально улучшить существующие элементы, чтобы всё не выглядело как дефолтное говно.

>>510564
В этом и смысл. За основу взял бутстрап.
#71 #510579
>>510577

>Это можно делать на PHP или node.js

104 Кб, 977x582
#72 #510597
>>510553

>Сейчас кратко расскажу...


>6973 символа



Ты в своем репертуаре. Надеюсь, это паста, и ты не писал это руками.
Блин, придется читать, человек мне это писал, старался знаешь.

Давай я сокращу это и выпишу в конспект основные тезисы:
По IP протоколу узлы (т.е. физ.устройства, сетевые карты) могут обмениваться малыми объемами данных (пакетами). Пакеты как-то неудачно нумеруются, приходят не обязательно в том порядке, что их отправили, и вообще часть может быть потеряна.
Так.
Для устранения вышеупомянутых проблем есть протоколы более высокого уровня типа ICMP, UPD и TCP. Данными обмениваются теперь не узлы (сетевые карты), а специальный софт, программное обеспечение. Ну вот как у нас есть взаимодействие клиент-сервер (мозилла-апач, например).

Пока смутно понимаю, что такое порт. Это что-то вроде идентификатора соединения в сетевой карте?
Таким образом, при работе по ICMP протоколу получается программки даже не открывают соединение с узлом(я так понял, имеется ввиду сетевая карта), у серверочка (как его зовут?) только запрашивается служебная информация: есть ли возможность создать соединение (открыть порт), или нет.

Дальше. UPD уже позволяет отправить какие-то данные на указанный порт указанного узла (сет.карты), где эти данные уже разбиваются на маленькие пакеты и скармливаются IP протоколу. Таким образом UPD выступает как бы посредником, оберткой над этим делом. Решает проблему упорядоченности данных, но не решает проблему потери.

TCP отличается надежностью, шлет повторные запросы на пропавшие пакеты, таким образом гарантируется целостность, пусть и ценой потери некоторой скорости.

>при keep-alive отправитель шлет запросы не дожидаясь получения ответа, и соответственно потом получает несклоько ответов сразу.


А когда соединение разрывается? Как происходит этот процесс? Ну вот у меня запрос на GET /index.php HTTP/1.1
Устанавливается TCP-соединение с example.com. Приходит полностью html или другой контент, который нам вернул php. А дальше браузер видит ссылочку на стили:
/css/main.css
Соответственно ему нужно получить и этот файл, потом картинки и т.д.
Так вот, если первый запрос завершился 200 OK, то соединение продолжает некоторое время висеть открытым, или как? Как он умудряется получив данные от index.php по тому же каналу, или соединению получить прочие ресурсы? Или браузер закроет соединение только полностью отрисовав в памяти DOM?
Если спустя время пользователь кликнет по кнопочке, на которой у меня висит аякс-запрос, то это будет уже новое соединение?

>Для полного понимания конечно было бы хорошо написать программу-клиент и программу-сервер, которые бы обменивались UDP датаграммами


Ты меня с кем-то путаешь. Это слишком сложно, и я не знаю тех языков, на которых подобное пишется (си, я подозреваю).
Ссылки как обычно схоронил, завтра уже почитаю. Ты меня своей пастой сильно утомил, еще какие-то левые статьи читать.

>попробуй попинговать узлы ya.ru


ну пик1. Что мне с ним дальше делать? Я вижу размер пакета (64 байта), айпи яндекса (93.158.134.3), номер пакета, время установки соединения (ну или эмуляции этого соединения, мы же с портом не коннектимся), и какой-то ttl.

>traceroute


выдало
1. x x x (три звездочки)
2. x x x (три звездочки)
3. какой-то url и айпи, скорее всего провайдера 30.702 ms 30.731 ms 30.718 ms
4. похожая строка
5. x x x (три звездочки)
6. 173.194.113.201 (173.194.113.201) 32.533 ms 11.306 ms 11.851 ms
Чего он мне гугл только с пятой попытки нашел?

telnet ya.ru 80
Говорит 400 bad request
104 Кб, 977x582
#72 #510597
>>510553

>Сейчас кратко расскажу...


>6973 символа



Ты в своем репертуаре. Надеюсь, это паста, и ты не писал это руками.
Блин, придется читать, человек мне это писал, старался знаешь.

Давай я сокращу это и выпишу в конспект основные тезисы:
По IP протоколу узлы (т.е. физ.устройства, сетевые карты) могут обмениваться малыми объемами данных (пакетами). Пакеты как-то неудачно нумеруются, приходят не обязательно в том порядке, что их отправили, и вообще часть может быть потеряна.
Так.
Для устранения вышеупомянутых проблем есть протоколы более высокого уровня типа ICMP, UPD и TCP. Данными обмениваются теперь не узлы (сетевые карты), а специальный софт, программное обеспечение. Ну вот как у нас есть взаимодействие клиент-сервер (мозилла-апач, например).

Пока смутно понимаю, что такое порт. Это что-то вроде идентификатора соединения в сетевой карте?
Таким образом, при работе по ICMP протоколу получается программки даже не открывают соединение с узлом(я так понял, имеется ввиду сетевая карта), у серверочка (как его зовут?) только запрашивается служебная информация: есть ли возможность создать соединение (открыть порт), или нет.

Дальше. UPD уже позволяет отправить какие-то данные на указанный порт указанного узла (сет.карты), где эти данные уже разбиваются на маленькие пакеты и скармливаются IP протоколу. Таким образом UPD выступает как бы посредником, оберткой над этим делом. Решает проблему упорядоченности данных, но не решает проблему потери.

TCP отличается надежностью, шлет повторные запросы на пропавшие пакеты, таким образом гарантируется целостность, пусть и ценой потери некоторой скорости.

>при keep-alive отправитель шлет запросы не дожидаясь получения ответа, и соответственно потом получает несклоько ответов сразу.


А когда соединение разрывается? Как происходит этот процесс? Ну вот у меня запрос на GET /index.php HTTP/1.1
Устанавливается TCP-соединение с example.com. Приходит полностью html или другой контент, который нам вернул php. А дальше браузер видит ссылочку на стили:
/css/main.css
Соответственно ему нужно получить и этот файл, потом картинки и т.д.
Так вот, если первый запрос завершился 200 OK, то соединение продолжает некоторое время висеть открытым, или как? Как он умудряется получив данные от index.php по тому же каналу, или соединению получить прочие ресурсы? Или браузер закроет соединение только полностью отрисовав в памяти DOM?
Если спустя время пользователь кликнет по кнопочке, на которой у меня висит аякс-запрос, то это будет уже новое соединение?

>Для полного понимания конечно было бы хорошо написать программу-клиент и программу-сервер, которые бы обменивались UDP датаграммами


Ты меня с кем-то путаешь. Это слишком сложно, и я не знаю тех языков, на которых подобное пишется (си, я подозреваю).
Ссылки как обычно схоронил, завтра уже почитаю. Ты меня своей пастой сильно утомил, еще какие-то левые статьи читать.

>попробуй попинговать узлы ya.ru


ну пик1. Что мне с ним дальше делать? Я вижу размер пакета (64 байта), айпи яндекса (93.158.134.3), номер пакета, время установки соединения (ну или эмуляции этого соединения, мы же с портом не коннектимся), и какой-то ttl.

>traceroute


выдало
1. x x x (три звездочки)
2. x x x (три звездочки)
3. какой-то url и айпи, скорее всего провайдера 30.702 ms 30.731 ms 30.718 ms
4. похожая строка
5. x x x (три звездочки)
6. 173.194.113.201 (173.194.113.201) 32.533 ms 11.306 ms 11.851 ms
Чего он мне гугл только с пятой попытки нашел?

telnet ya.ru 80
Говорит 400 bad request
#73 #510640
>>510597

> Пакеты как-то неудачно нумеруются,


Пакеты не нумеруются в протоколе IP вообще никак, это делается в UDP/TCP, чтобы понять в каком порядке их потом собирать, когда они придут. Как иначе?

> Пока смутно понимаю, что такое порт. Это что-то вроде идентификатора соединения в сетевой карте?


Это число от 1 до 65535. Он есть только в UDP и TCP. Когда программа хочет принимать UDP или TCP, она говорит ОС: я хочу открыть TCP порт 2000 на прием. И ОС может ответить одно их двух:

— ок, порт открыт, держи сокет (идентификатор), все датаграммы (или соединения) пришедшие на этот порт ты будешь получать через этот сокет.

— нет, этот порт уже занят другой программой (такое получается если ты например пытаешься запустить Апач второй раз при уже запущенном)

А если программа (клиент) хочет передавать датаграммы или установить соединенеи, то ОС дает ей любой свободный номер порта, так как тут не принципиально какой он будет.

Например порт 80 испольузется по умолчанию в HTTP и например программа-веб-сервер на сайте ждет соединений именно на него. На других портах какие-то другие программы или ничего нет.

Вот список некоторых общеизвестных номеров портов: https://ru.wikipedia.org/wiki/%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA_%D0%BF%D0%BE%D1%80%D1%82%D0%BE%D0%B2_TCP_%D0%B8_UDP

Номера в списке выдает организация IANA, но ты можешь исплозьзовать любые, просто список это скорее рекомендация разрабочтикам, чтобы они, делая свой новый протокол не использовали уже занятый порт, ведь тогда их программа будет конфликтовать с другими на том же компьютере.

Под линуксом и маком порты ниже 1024 может открыть только программа с правами администратора. Это сделано для защиты от таких ситуаций:

— программа-сервер ssh (удаленный доступ к командной строке на линуксе), слушающая порт 21, упала из-за ошибки и порт освободился (или например веб-сервер Апач на 80 порту упал из-за ошибки)
— злоумышленник-пользователь сервера, не имеющий прав администратора, запустил свою программу слушающую этот порт и собирающущую пароли и любые данные которые слали Апачу/ssh. Заняв порт он не дает ssh/Апачу открыть его после перезапуска.

Ну к примеру на хостинге много обычных пользователей и нельзя чтобы они могли открыть порт вместо Апача или ssh.

Таким образом если номер порта меньше 1024 то ты знаешь что программа на нем запущена администратором сервера, а не обычным пользователем.

> Это что-то вроде идентификатора соединения в сетевой карте?


Нет, это на уровне ОС, у нее есть список какой порт какой программой открыт и соответственно кому надо передавать пришедшие на этот порт данные. Сетевая карта работает на более низком уровне и просто передает ОС пришедшие пакеты не особо в них разбираясь.

> Таким образом, при работе по ICMP протоколу получается программки даже не открывают соединение с узлом(я так понял, имеется ввиду сетевая карта), у серверочка (как его зовут?) только запрашивается служебная информация: есть ли возможность создать соединение (открыть порт), или нет.


Это при UDP/TCP так. Программа-сервер открывает порт для приема соединений либо программа-клиент просит ОС установить соединение с данными Ip/портом.

В ICMP портов нет и понять какой программе адресован пакет невозможно. Потому под линуксом программа ping использует права администратора, чтобы заставить ОС отдавать ей все пришедшие ICMP-пакеты (без прав админа это сделать нельзя разумеется). Если ты запустишь несколько ping одновременно, они не путаются, так как добавляют в пакеты какие-то свои номера, но это не порт.

Порт идентифицирует программу, не соединение. Соединение идентифицирует 4 числа: IP отправителя/получаетля, порт отправителя/получателя. Таким образом, один порт может использоваться для множества соединений. Например веб-сервер может принимать одновременно сотни соединений на один порт 80 при условии что они приходят от разных IP/портов.

То есть у веб-сервера который слушает порт 80, обычно есть много сокетов (сокет это что-то вроде идентификатора соединения на уровне ОС):

— «слушающий сокет» на порт 80, через который он получает от ОС новые сокеты при подсоединении клиентов к этому порту
— сокеты установленных соединений с клиентами

(это уже особенности того как работает ОС)

> приходят не обязательно в том порядке, что их отправили,


Да, потому что пакеты могут идти разными путями, а также маршрутизатор может по каким-то причинам пересылать их в другом порядке.

> UPD уже позволяет отправить какие-то данные на указанный порт указанного узла (сет.карты), где эти данные уже разбиваются на маленькие пакеты и скармливаются IP протоколу.


У сетевой карты нет портов, порт это просто число по которому ОС идентифицирует программу. У сетевого интерфейса есть только IP адрес и он отправляет/принимает все подряд.

> А когда соединение разрывается? Как происходит этот процесс?


В TCP соединение закрывать может передающая сторона, причем закрывает она этим канал только в одну сторону, на передачу. К примеру, клиент, послав запрос может сразу закрыть канал от клиента к серверу, но оставить открытым канал в обратную сторону (а каждое соединение, как ты помнишь двунаправленное).

Если закрыть канал в обе стороны, очевидно, соединение считается полностью закрытым.

Закрытие делается отправкой специального TCP-пакета с флагом FIN. Он значит «я закончил передавать данные». Получив такой пакет, другая сторона отправляет пакет с флагами FIN + ACK, то есть подтверждает закрытие одного из направлений передачи данных.

Также, есть сброс соединения. Он делается пакетом RST. Он обозначает либо отказ устанавливать соединение, либо если послан после установки, обозначает разрыв соединения. ОС шлет пакеты RST в случае если:

— пришел пакет с попыткой установить соединение на несуществующий порт, на котором никто не слушает (также можно настроить ОС чтобы она ничего не отправляла в ответ, для защиты от сканирования портов)
— программа, которая открыла порт, упала/завершилась. В этом слуае ОС закрывает все открытые ей соединения, посылая пакеты RST

Вот есть длинная, но с графиками, статья про виды пакетов TCP:

http://www.soslan.ru/tcp/tcp18.html
http://www.opennet.ru/docs/RUS/tcpip/#c4_tcp

Кстати, есть программы которые позволяют перрехватывать проходящие через сетевую карту пакеты. Например кроссплатформенный и бесплатный wireshark (с графическим интерфейсом). Можешь поставить его и попробовать, только закрой лишние программы а то будет трудно разобраться. В нем будут видны все свойства пакетов, флаги, порядок установки и разрыва соединения.

Также, команда netstat -abn покажет все открытые соединения и слушающие порты. попробуй ее запустить.
#73 #510640
>>510597

> Пакеты как-то неудачно нумеруются,


Пакеты не нумеруются в протоколе IP вообще никак, это делается в UDP/TCP, чтобы понять в каком порядке их потом собирать, когда они придут. Как иначе?

> Пока смутно понимаю, что такое порт. Это что-то вроде идентификатора соединения в сетевой карте?


Это число от 1 до 65535. Он есть только в UDP и TCP. Когда программа хочет принимать UDP или TCP, она говорит ОС: я хочу открыть TCP порт 2000 на прием. И ОС может ответить одно их двух:

— ок, порт открыт, держи сокет (идентификатор), все датаграммы (или соединения) пришедшие на этот порт ты будешь получать через этот сокет.

— нет, этот порт уже занят другой программой (такое получается если ты например пытаешься запустить Апач второй раз при уже запущенном)

А если программа (клиент) хочет передавать датаграммы или установить соединенеи, то ОС дает ей любой свободный номер порта, так как тут не принципиально какой он будет.

Например порт 80 испольузется по умолчанию в HTTP и например программа-веб-сервер на сайте ждет соединений именно на него. На других портах какие-то другие программы или ничего нет.

Вот список некоторых общеизвестных номеров портов: https://ru.wikipedia.org/wiki/%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA_%D0%BF%D0%BE%D1%80%D1%82%D0%BE%D0%B2_TCP_%D0%B8_UDP

Номера в списке выдает организация IANA, но ты можешь исплозьзовать любые, просто список это скорее рекомендация разрабочтикам, чтобы они, делая свой новый протокол не использовали уже занятый порт, ведь тогда их программа будет конфликтовать с другими на том же компьютере.

Под линуксом и маком порты ниже 1024 может открыть только программа с правами администратора. Это сделано для защиты от таких ситуаций:

— программа-сервер ssh (удаленный доступ к командной строке на линуксе), слушающая порт 21, упала из-за ошибки и порт освободился (или например веб-сервер Апач на 80 порту упал из-за ошибки)
— злоумышленник-пользователь сервера, не имеющий прав администратора, запустил свою программу слушающую этот порт и собирающущую пароли и любые данные которые слали Апачу/ssh. Заняв порт он не дает ssh/Апачу открыть его после перезапуска.

Ну к примеру на хостинге много обычных пользователей и нельзя чтобы они могли открыть порт вместо Апача или ssh.

Таким образом если номер порта меньше 1024 то ты знаешь что программа на нем запущена администратором сервера, а не обычным пользователем.

> Это что-то вроде идентификатора соединения в сетевой карте?


Нет, это на уровне ОС, у нее есть список какой порт какой программой открыт и соответственно кому надо передавать пришедшие на этот порт данные. Сетевая карта работает на более низком уровне и просто передает ОС пришедшие пакеты не особо в них разбираясь.

> Таким образом, при работе по ICMP протоколу получается программки даже не открывают соединение с узлом(я так понял, имеется ввиду сетевая карта), у серверочка (как его зовут?) только запрашивается служебная информация: есть ли возможность создать соединение (открыть порт), или нет.


Это при UDP/TCP так. Программа-сервер открывает порт для приема соединений либо программа-клиент просит ОС установить соединение с данными Ip/портом.

В ICMP портов нет и понять какой программе адресован пакет невозможно. Потому под линуксом программа ping использует права администратора, чтобы заставить ОС отдавать ей все пришедшие ICMP-пакеты (без прав админа это сделать нельзя разумеется). Если ты запустишь несколько ping одновременно, они не путаются, так как добавляют в пакеты какие-то свои номера, но это не порт.

Порт идентифицирует программу, не соединение. Соединение идентифицирует 4 числа: IP отправителя/получаетля, порт отправителя/получателя. Таким образом, один порт может использоваться для множества соединений. Например веб-сервер может принимать одновременно сотни соединений на один порт 80 при условии что они приходят от разных IP/портов.

То есть у веб-сервера который слушает порт 80, обычно есть много сокетов (сокет это что-то вроде идентификатора соединения на уровне ОС):

— «слушающий сокет» на порт 80, через который он получает от ОС новые сокеты при подсоединении клиентов к этому порту
— сокеты установленных соединений с клиентами

(это уже особенности того как работает ОС)

> приходят не обязательно в том порядке, что их отправили,


Да, потому что пакеты могут идти разными путями, а также маршрутизатор может по каким-то причинам пересылать их в другом порядке.

> UPD уже позволяет отправить какие-то данные на указанный порт указанного узла (сет.карты), где эти данные уже разбиваются на маленькие пакеты и скармливаются IP протоколу.


У сетевой карты нет портов, порт это просто число по которому ОС идентифицирует программу. У сетевого интерфейса есть только IP адрес и он отправляет/принимает все подряд.

> А когда соединение разрывается? Как происходит этот процесс?


В TCP соединение закрывать может передающая сторона, причем закрывает она этим канал только в одну сторону, на передачу. К примеру, клиент, послав запрос может сразу закрыть канал от клиента к серверу, но оставить открытым канал в обратную сторону (а каждое соединение, как ты помнишь двунаправленное).

Если закрыть канал в обе стороны, очевидно, соединение считается полностью закрытым.

Закрытие делается отправкой специального TCP-пакета с флагом FIN. Он значит «я закончил передавать данные». Получив такой пакет, другая сторона отправляет пакет с флагами FIN + ACK, то есть подтверждает закрытие одного из направлений передачи данных.

Также, есть сброс соединения. Он делается пакетом RST. Он обозначает либо отказ устанавливать соединение, либо если послан после установки, обозначает разрыв соединения. ОС шлет пакеты RST в случае если:

— пришел пакет с попыткой установить соединение на несуществующий порт, на котором никто не слушает (также можно настроить ОС чтобы она ничего не отправляла в ответ, для защиты от сканирования портов)
— программа, которая открыла порт, упала/завершилась. В этом слуае ОС закрывает все открытые ей соединения, посылая пакеты RST

Вот есть длинная, но с графиками, статья про виды пакетов TCP:

http://www.soslan.ru/tcp/tcp18.html
http://www.opennet.ru/docs/RUS/tcpip/#c4_tcp

Кстати, есть программы которые позволяют перрехватывать проходящие через сетевую карту пакеты. Например кроссплатформенный и бесплатный wireshark (с графическим интерфейсом). Можешь поставить его и попробовать, только закрой лишние программы а то будет трудно разобраться. В нем будут видны все свойства пакетов, флаги, порядок установки и разрыва соединения.

Также, команда netstat -abn покажет все открытые соединения и слушающие порты. попробуй ее запустить.
#74 #510650
>>510597

> Устанавливается TCP-соединение с example.com. Приходит полностью html или другой контент, который нам вернул php


Тот кто отправляет данные, закрывает канал на передачу. То есть клиент посылает запрос, закрывает передачу (и сервер это знает так как получил пакет FIN). Сервер посылает ответ, закрывает передачу и соединение считается завершенным так как закрыто в обе стороны.

Именно благодаря закрытию канала при отправке например POST запроса севрер знает когда собственно запрос закончился и можно начинать его обрабатывать. Ведь в HTTP по умоланию нет никакого признака конца данных.

Это по умолчанию, а с Keep-alive конечно канал сразу не закрывается.

> Так вот, если первый запрос завершился 200 OK, то соединение продолжает некоторое время висеть открытым, или как?


По умолчанию закрывается, но клиент и сервер могут договориться не закрывать его с помощью заговков Keep-Alive/Connection. Если будешь смотреть заголвоки на вкладке Network в отладчике, то обрати на них внимание.
#75 #510675
>>510597

> Это слишком сложно, и я не знаю тех языков, на которых подобное пишется (си, я подозреваю).


На PHP есть функции для работы с сокетами: http://php.net/manual/ru/sockets.examples.php

Также, можно открыть соединение через врапперы tcp и udp: http://php.net/manual/ru/function.stream-socket-client.php

Это действительно сложно на первый взгяд, но я думаю написать простые TCP -клиент и сервер пересылающие сообщения, не сложно.

мануалы действительно используют код на СИ. Но если ты понимаешь принцип ты легко перепишешь его на PHP:

http://masandilov.ru/network/guide_to_network_programming

Ну подумай, в общем, я думаю, если писать потихоньку то это не так сложно. Зато ты гораздо лучше будешь понимать что происходит при передаче данных в сети. К тому же в случае с TCP ты можешь установить netcat и она может использоваться как клиент/сервер для тестирования, так как умеет и принимать и устанавливать соединения.

nc -v -l -p 1000 — открыть порт 1000 на прием соединений
nc -v localhost 1000 — соединиться с портом 1000 на своем компьютере

Сделай это в 2 терминалах и получишь мини-чат.

> время установки соединения (ну или эмуляции этого соединения, мы же с портом не коннектимся),


Это время между отправкой и полуением пакета. в ICMP нет соединений, можно только слать пакеты, как в UDP.

> и какой-то ttl.


ttl это поле которое уменьшается на 1 при проходе пакета через маршрутизатор. при достижении нуля пакет уничтожается и отправителю отправляется ICMP-уведомление. Это сделано чтобы при неправильной маршрутизации пакет не ходил по сети вечно.

> ну пик1. Что мне с ним дальше делать?


Ну ты научился пользоваться пингом и узнал что пакеты проходят от тебя до сервера яндекса без проблем.

> Чего он мне гугл только с пятой попытки нашел?


Узлы сети соединены не напрямую, а через маршрутизаторы (которые тоже являются узлами и имеют IP адреса). Traceroute посылает пакеты с возрастающим ttl (которые умрут пройдя несклоько шагов), и выводит тебе пришедшие уведомления об их уничтожении. Таким образом ты видишь каким путем шел пакет к цели.

traceroute позвоялет видеть каким путем идет пакет и обнаруживать проблемы неправильной конфигурации сети.

Там где зведочки, ответа не пришло. Это значит администратор маршрутизатора отключил отправку ICMP уведомлений.

> Говорит 400 bad request


ты неправильно набрал запрос. Проверь пробелы, переводы строк, не перепутано ли что.
#75 #510675
>>510597

> Это слишком сложно, и я не знаю тех языков, на которых подобное пишется (си, я подозреваю).


На PHP есть функции для работы с сокетами: http://php.net/manual/ru/sockets.examples.php

Также, можно открыть соединение через врапперы tcp и udp: http://php.net/manual/ru/function.stream-socket-client.php

Это действительно сложно на первый взгяд, но я думаю написать простые TCP -клиент и сервер пересылающие сообщения, не сложно.

мануалы действительно используют код на СИ. Но если ты понимаешь принцип ты легко перепишешь его на PHP:

http://masandilov.ru/network/guide_to_network_programming

Ну подумай, в общем, я думаю, если писать потихоньку то это не так сложно. Зато ты гораздо лучше будешь понимать что происходит при передаче данных в сети. К тому же в случае с TCP ты можешь установить netcat и она может использоваться как клиент/сервер для тестирования, так как умеет и принимать и устанавливать соединения.

nc -v -l -p 1000 — открыть порт 1000 на прием соединений
nc -v localhost 1000 — соединиться с портом 1000 на своем компьютере

Сделай это в 2 терминалах и получишь мини-чат.

> время установки соединения (ну или эмуляции этого соединения, мы же с портом не коннектимся),


Это время между отправкой и полуением пакета. в ICMP нет соединений, можно только слать пакеты, как в UDP.

> и какой-то ttl.


ttl это поле которое уменьшается на 1 при проходе пакета через маршрутизатор. при достижении нуля пакет уничтожается и отправителю отправляется ICMP-уведомление. Это сделано чтобы при неправильной маршрутизации пакет не ходил по сети вечно.

> ну пик1. Что мне с ним дальше делать?


Ну ты научился пользоваться пингом и узнал что пакеты проходят от тебя до сервера яндекса без проблем.

> Чего он мне гугл только с пятой попытки нашел?


Узлы сети соединены не напрямую, а через маршрутизаторы (которые тоже являются узлами и имеют IP адреса). Traceroute посылает пакеты с возрастающим ttl (которые умрут пройдя несклоько шагов), и выводит тебе пришедшие уведомления об их уничтожении. Таким образом ты видишь каким путем шел пакет к цели.

traceroute позвоялет видеть каким путем идет пакет и обнаруживать проблемы неправильной конфигурации сети.

Там где зведочки, ответа не пришло. Это значит администратор маршрутизатора отключил отправку ICMP уведомлений.

> Говорит 400 bad request


ты неправильно набрал запрос. Проверь пробелы, переводы строк, не перепутано ли что.
#76 #510693
Оп, а есть какие-то рекомендации по количеству return'ов в функциях? Допустим, если какой-нибудь иф, то можно сделать при каждом условии свой вывод или лучше присваивать значение какой-то переменной, а в конце выводить?
#77 #510701
>>510640
Вся проблема в том, что такие полезные посты уходят в никуда. Запилил бы ты рубрику вопрос — ответ, я бы подписался на рсс. Аж обидно, что харкач не знает своих героев.
#78 #510708
>>510701
Это у тебя значит в одно ухо влетело, из другого вылетело.
А я все запоминаю, что он мне отвечает.
В никуда уходят, охуел штоле сука.

Тебе ничто не мешает сохранять его пасты, например.
И можешь тоже задавать вопросы в треде, видишь как он возбуждается от этого.
#79 #510710
>>510708

>Это у тебя значит в одно ухо влетело, из другого вылетело.


Сыранул и не вчитался. Я говорю, что знания должны накапливаться, а не убывать. Я вот написал пост и всё. Спустя 10 тредов мой ответ съест лангольер. Жаль время человека.
#80 #510721
Начал читать: https://medium.com/javascript-scene/how-to-fix-the-es6-class-keyword-2d42bb3f4caf

И дошел до картинки: https://d262ilb51hltx0.cloudfront.net/max/990/1*NZUhr1jZdBK5YLZogMZgow.png . Она наглядно показывает уровень современного фронтенд"специалиста". Начнем с того что сам бекбон, упоминаемый в посте, построен на классах, только более костыльно и неявно (там по моему есть функция extend или как-то так для наследования). Слово class просто позволяет сделать это наследование более прозрачным.

Ну и далее он пишет «DI ... which of course coupled all those modules to DI container». Это не DI, а service locator в таком случае. Фронтенд-"специалисты" не разобрались в паттернах, набыдлокодили код, а виновато слово class из ES6.Нет, виноваты вы, потому что не разбираетесь в программировании.

Ну и далее сам пост про то что сложно менять new на фабрику, напоминает какой-то бред. Если автор кода использует new, это значит что он хочет создать новый объект. Нет никакой причины заменять это на вызов фабрики (реальная причина, если мы посмотрим на код автора и продолжения поста, то, что ему почему-то нравится создавать объекты через Object.create, а не через new).

В общем, человек явно любитель делать не как все, придумывать какие-то свои велосипеды, и возмущается что ему мешают это делать.

>>510693

Лучше сразу return чтобы читать было проще

>>510701

Я схоронил пасту в текстовый файлик.
#81 #510767
А если у меня ввод с клавы тормозит, а когда я выключаю соединение с нетом - это прекращается, значит ли это что кто-то палит мой комп?
#82 #510791
>>510767
Фаерволл ставить не пробовал? Иногда такое чувство, что тут многие пека вреча только купили
#83 #510803
>>510791
что за фаербол?
#84 #510812
>>510035
почему на локалке все норм работает, а на хосте вылезает такое:
Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.
#85 #510823
>>510812

.htaccess неправильный или ошибка в конфиге Апача. Точную причину ищи в логе ошибок.
#86 #510830
>>510823
Вот интересно, пхп формат перестал на хосте работать.
#87 #510839
Установила XAMMP, а там опять MySQL не работает, что же делать, винду переустанавливать?
#88 #510840
>>510839
У ОПа есть мануал по ручной установке MySQL и Apache.
#89 #510842
Есть 3 условия и в каждом условии запросы к разным таблицам. Как мне объединить эти три запроса в один?

$sql_query = "SELECT user_id, user_search_pref, user_photo, user_birthday, user_country_city_name FROM `".PREFIX."_users` WHERE user_search_pref LIKE '%".$query."%' AND user_delet = '0' AND user_ban = '0' ORDER by `user_photo` DESC, `user_country_city_name` DESC LIMIT 0, ".$limit_sql;

$sql_query = "SELECT id, photo, title, add_date, owner_user_id FROM `".PREFIX."_videos` WHERE title LIKE '%".$query."%' AND privacy = 1 ORDER by `views` DESC LIMIT 0, ".$limit_sql;

$sql_query = "SELECT id, title, photo, traf, adres FROM `".PREFIX."_communities` WHERE title LIKE '%".$query."%' AND del = '0' AND ban = '0' ORDER by `traf` DESC, `photo` DESC LIMIT 0, ".$limit_sql;
#90 #510845
Оп, выскажи свое мнение по поводу верстки и натяжки шаблонов на cms. Как способ подзаработать на переезд в город миллионик, для последующего устройства джуном. Если искать заказы на зарубежных фриланс биржах.
#91 #510855
>>510840
так оно у меня уже все установлено переустановлено, я просто в душе не ебу, где этот майсокл лежит и как его удалить, в хампе в пакете он есть уже.
#92 #510856
>>510842
а не проще одну таблицу с вложенными ключами сделать?
#93 #510857
>>510856
Нет
#94 #510889
>>510855
Снеси хамп и поставь руками.
#95 #510907
>>510855
Через установку/удаление программ наверно можно.
661 Кб, 586x580
#96 #510922
что читать по SQL? С кучей практики желательно.
78 Кб, 542x700
#97 #510931
>>510922
Ирина Астахова, учебник по сикуэль или как-то так называется. 100 страниц подобностей и практических задач.
http://flibusta.net/a/23040
263 Кб, 399x559
#98 #510932
>>510336
Уже не надо, остановился на совете вот этого анона >>510336, хотя если есть что-то из разряда "мастхев", то напишите плиз.
#99 #510933
>>510931
спс, посмотрю.
#100 #510946
>>510933
Мразь ёбаная, никогда не отвечай «посмотрю». Ты только что сыранул на советчика.
#101 #510951
>>510946
А проблема в чем?
164 Кб, 768x1024
#102 #510961
Все какое то сомнительное говнецо(я могу ошибаться), про Астахову пишут, что она хуевый препод и примеры есть не корректные, Изучаем SQL - много картиночек, я пробывал читать из этой серии книгу про сss и могу сказать что мануал на htmlbook гораздо лучше. Придется ждать Оп'а.
#103 #510968
Пока регнусь на тостере, спрошу там.
#104 #511020
Почему во всех мануалах по AJAX используют всякие фреймворки и библиотеки? Неужели так сложно на чистом джсе делать AJAX запрос? Не хочется грузить страницу еще и фреймворками.
#105 #511023
>>511020

И на чистом JS встречал. Просто почти все используют jQuery, а там AJAX запрос сделать намного проще и быстрее, чем на JS.
#106 #511026
Кстати, вот на этом сайте много годноты и уроков по темам, которых нет в учебнике ОПа. Отсюда по cURL узнал, и работу с изображениями. Неплохие статьи на мой взгляд и главное понятным языком написаны.
http://myrusakov.ru/php-osnovy.html
#107 #511034
>>511026
http://srs.myrusakov.ru/freephp
Ну хуй знает, хуй знает...
Смутные сомнения терзают меня.
191 Кб, 1600x501
#108 #511052
почему, когда я ставлю yii2 через composer в нем нету папки vendor, в следствии чего получается ошибка.
делаю вроде как всё правильно, даже посмотрел на ютубе видосы как делают, точно так же. почему у них норм, а у меня нет?
#109 #511063
>>511052
Потому что у тебя прописаны юниксовые пути на винде. А еще установлен openserver. В него вшит вирус, вызывающий рак яичек.
#110 #511088
>>510675

>Ну подумай, в общем, я думаю, если писать потихоньку то это не так сложно.


Давай чуток попозже. Доделаю хоть файлообменник. Там мне осталась регистрация, древовидные комментарии (мне понравилось решение №4 из твоего урока, где создается колонка path вида '1.1.2.1.......', следовательно мы должны хитро вкладывать элементы и парсить dom).

Твою пасту по задачам на xml сохранил, это следующее на очереди. Авось напишу пару патчей для своего киндла, будет хоть чем похвастаться перед родней. А то они думают, что я в игрушки целыми днями играю (неправда, всего 3-4 часа).

Может потом и возьмусь за эту задачу, мне кажется она будет полезной в плане разруливания всяких сокетных соединений, надо бы хороший такой чат написать. Я уже писал, но там тупо гоняются json-строки, это не дело, надо через сокеты.

>Узлы сети соединены не напрямую, а через маршрутизаторы (которые тоже являются узлами и имеют IP адреса)


О, услышал знакомое слово. Про маршрутизацию я читал у Олифер, мало что понял, но хоть знаю красивые слова типа коммутатор и мультиплексор.
Думаю базового знакомства хватит, я же не сисадмин.

>telnet ya.ru 80


Получил заголовки и страницу. Погоди, а зачем ты мне сказал вбить 1.0 вместо 1.1? nginx все равно ответил по новому протоколу.

inside@HP255:~$ telnet ya.ru 80
Trying 213.180.204.3...
Connected to ya.ru.
Escape character is '^]'.
GET / HTTP/1.0
Host: ya.ru

HTTP/1.1 200 Ok
Server: nginx
Date: Wed, 08 Jul 2015 15:04:59 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 9664
Connection: close
Cache-Control: no-cache,no-store,max-age=0,must-revalidate
Expires: Wed, 08 Jul 2015 15:04:59 GMT
Last-Modified: Wed, 08 Jul 2015 15:04:59 GMT
P3P: policyref="/w3c/p3p.xml", CP="NON DSP ADM DEV PSD IVDo OUR IND STP PHY PRE NAV UNI"
Set-Cookie: yandex_gid=143; Expires=Fri, 07-Aug-2015 15:04:59 GMT; Domain=.ya.ru; Path=/
Set-Cookie: yp=; Expires=Sun, 10-Jul-2005 15:04:59 GMT; Path=/
Set-Cookie: yp=; Expires=Sun, 10-Jul-2005 15:04:59 GMT; Domain=.ya.ru; Path=/
Set-Cookie: yp=1438959899.ygu.1; Expires=Sat, 05-Jul-2025 15:04:59 GMT; Domain=.ya.ru; Path=/
Set-Cookie: S=; Expires=Sun, 10-Jul-2005 15:04:59 GMT; Path=/
Set-Cookie: yandexuid=4296845751436367899; Expires=Sat, 05-Jul-2025 15:04:59 GMT; Domain=.ya.ru; Path=/
X-Frame-Options: DENY

>>510640

>Также, команда netstat -abn


verbose наверное, опции b я не нашел.

Ага, порты закреплены за программами, то есть когда придет какой-то поток на тот или иной порт ОС будет знать, кому отдать эти данные на обработку, я понял.

Ладно, ты меня перегрузил. Давай я пока побалуюсь немного с курлом, а потом доделаю многострадальный файлообменник.

Придумай мне задачи на курл. Я тупой, я не могу зазубривать справочники, дай мне практическое задание.
Что можно сделать курлом? Кроме соединения гетом, хедом и постом, что еще интересного можно сделать? Как скачать сайт курлом, не wgetом? Как загрузить/скачать файлы по ftp на хостинг (если они это позволяют, конечно)?
Придумай еще задания, потому что я смутно понимаю, какие у него возможности, а тупо зазубривать команды, не понимая их смысла не охота.
#110 #511088
>>510675

>Ну подумай, в общем, я думаю, если писать потихоньку то это не так сложно.


Давай чуток попозже. Доделаю хоть файлообменник. Там мне осталась регистрация, древовидные комментарии (мне понравилось решение №4 из твоего урока, где создается колонка path вида '1.1.2.1.......', следовательно мы должны хитро вкладывать элементы и парсить dom).

Твою пасту по задачам на xml сохранил, это следующее на очереди. Авось напишу пару патчей для своего киндла, будет хоть чем похвастаться перед родней. А то они думают, что я в игрушки целыми днями играю (неправда, всего 3-4 часа).

Может потом и возьмусь за эту задачу, мне кажется она будет полезной в плане разруливания всяких сокетных соединений, надо бы хороший такой чат написать. Я уже писал, но там тупо гоняются json-строки, это не дело, надо через сокеты.

>Узлы сети соединены не напрямую, а через маршрутизаторы (которые тоже являются узлами и имеют IP адреса)


О, услышал знакомое слово. Про маршрутизацию я читал у Олифер, мало что понял, но хоть знаю красивые слова типа коммутатор и мультиплексор.
Думаю базового знакомства хватит, я же не сисадмин.

>telnet ya.ru 80


Получил заголовки и страницу. Погоди, а зачем ты мне сказал вбить 1.0 вместо 1.1? nginx все равно ответил по новому протоколу.

inside@HP255:~$ telnet ya.ru 80
Trying 213.180.204.3...
Connected to ya.ru.
Escape character is '^]'.
GET / HTTP/1.0
Host: ya.ru

HTTP/1.1 200 Ok
Server: nginx
Date: Wed, 08 Jul 2015 15:04:59 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 9664
Connection: close
Cache-Control: no-cache,no-store,max-age=0,must-revalidate
Expires: Wed, 08 Jul 2015 15:04:59 GMT
Last-Modified: Wed, 08 Jul 2015 15:04:59 GMT
P3P: policyref="/w3c/p3p.xml", CP="NON DSP ADM DEV PSD IVDo OUR IND STP PHY PRE NAV UNI"
Set-Cookie: yandex_gid=143; Expires=Fri, 07-Aug-2015 15:04:59 GMT; Domain=.ya.ru; Path=/
Set-Cookie: yp=; Expires=Sun, 10-Jul-2005 15:04:59 GMT; Path=/
Set-Cookie: yp=; Expires=Sun, 10-Jul-2005 15:04:59 GMT; Domain=.ya.ru; Path=/
Set-Cookie: yp=1438959899.ygu.1; Expires=Sat, 05-Jul-2025 15:04:59 GMT; Domain=.ya.ru; Path=/
Set-Cookie: S=; Expires=Sun, 10-Jul-2005 15:04:59 GMT; Path=/
Set-Cookie: yandexuid=4296845751436367899; Expires=Sat, 05-Jul-2025 15:04:59 GMT; Domain=.ya.ru; Path=/
X-Frame-Options: DENY

>>510640

>Также, команда netstat -abn


verbose наверное, опции b я не нашел.

Ага, порты закреплены за программами, то есть когда придет какой-то поток на тот или иной порт ОС будет знать, кому отдать эти данные на обработку, я понял.

Ладно, ты меня перегрузил. Давай я пока побалуюсь немного с курлом, а потом доделаю многострадальный файлообменник.

Придумай мне задачи на курл. Я тупой, я не могу зазубривать справочники, дай мне практическое задание.
Что можно сделать курлом? Кроме соединения гетом, хедом и постом, что еще интересного можно сделать? Как скачать сайт курлом, не wgetом? Как загрузить/скачать файлы по ftp на хостинг (если они это позволяют, конечно)?
Придумай еще задания, потому что я смутно понимаю, какие у него возможности, а тупо зазубривать команды, не понимая их смысла не охота.
#111 #511116
ОП, решил задачу по списку студентов:
https://github.com/soulsteel/studentProject
Заранее спасибо за конструктивную критику.
#112 #511153
Пэхэпач, поясни за __construct, попался мне этот зверь в codecademy, что-я не догоняю нифига, перевод вроде понимаю, а что сказать хотели, не очень.
#113 #511157
>>511153

Это функция, которая автоматически выполняется при создании экземпляра класса.
#114 #511273
http://www.php-fig.org/psr/psr-2/ru/

>Все PHP файлы НЕОБХОДИМО заканчивать одной пустой строкой.


Это зачем? Насчет отсутствия закрывающего тега ?> понятно, а зачем пустая строка в конце файла? Чем обусловлено это правило?
302 Кб, 769x1016
#115 #511347
Как мне проверить свою природную способность к логике и абстрактному мышлению?
Чтобы знать, могу ли я стать полноценным пхп-программистом или забить .
#116 #511352
>>511347
По-моему тебе уже можно ставить диагноз.

Ну серьезно, омеганчики, ну как можно быть такими чмошниками? Из-за вашей неуверенности в себе отрасль переполняется тупым быдлом.
Не далее как сегодня общался с одним, это просто пиздец. Эталонное рыгающее быдло, бухое, тупое, самодовольное. Заучило наизусть часть фреймворка, схоронило себе несколько готовых проектов, и копипастит. Я ему говорю, нахуя ты это тут написал? А он говорит "ну вот в том проекте так написано, значит так надо. тот сайт писал чувак покруче тебя, так что не выйобуйся мне тут".

Черт, я специально выбрал айти, чтобы общаться только с умными культурными людьми, а из-за вашей лузерской позиции скоро буду окружен рыгающими колхозниками.
С омеганом сегодня переписывался: "Ты ведь и сам прекрасно понимаешь и видишь ситуацию. Нужно сделать портфолио. А ты один такой? Посмотри любой фриланс сайт. Там таких сотни... И как с ними состязаться? Как бороться за работу?"
Сказал ему не быть ипохондриком, и что на фрилансе большая часть - некомпетентный сброд, обвинил меня в высокомерии. Блять, да идите вы нахуй, опущенцы.
#117 #511373
>>511352

Лучше уж рыгающее быдло, чем снобы.
#118 #511374
>>511352

>айти


>умными культурными людьми


Ты не особо блещешь умом, если на самом деле думал, что большинство "айтишников" - умные культурные люди.

>большая часть - некомпетентный сброд,


Всем похуй абсолютно. Большинство работодателей - обычное быдло, которое считает, что более опытный - значит сделает лучше менее опытного. Быдлом управляет страх.

>Эталонное рыгающее быдло, бухое, тупое, самодовольное.


Такое быдло будет собеседовать тебя при приёме на работу. Гарантирую.
#119 #511378
>>511352

>бороться за работу


Ты выбрал карьеру программистишки. Поздравляю. Ты будешь постоянно терпеть унижения ради того, чтобы в 35 лет сидеть в санном опенспейсе, делать сайты на пэхапэ и пить остывший растворимый кофе.
ПРИШЛО ВРЕМЯ УЧИТЬ НОВЫЙ ФРЕЙМВОРК
ФРЕЙМВОРК САМ НЕ ИЗУЧИТСЯ
ИЗУЧИ ЕГО, ИЗУЧИ ЕГО ЕЩЕ РАЗ
ЗАЧЕМ МНЕ НУЖЕН СВОЙ СТАРТАП, У МЕНЯ НЕТ ВРЕМЕНИ ЧТОБЫ ЕБАТЬСЯ С НИМ
ЛУЧШЕ ЕЩЕ РАЗ ВЫУЧИТЬ ФРЕЙМВОРК
Я ИЗУЧАЮ ФРЕЙМВОРК ПО 3 РАЗА В ДЕНЬ
КАЖДОЕ ИЗУЧЕНИЕ ЗАНИМАЕТ ПЯТЬДЕСЯТ МИНУТ
Я ЖИВУ АКТИВНОЙ И ПОЛНОЦЕННОЙ ЖИЗНЬЮ
Я УСПЕШЕН И ПОЭТОМУ ЦЕЛЫЙ ДЕНЬ ПРОГРАММИРУЮ
А ПОСЛЕ ЭТОГО ИЗУЧАЮ НОВЫЙ ФРЕЙМВОРК
ТУПОЕ БЫДЛО ОДЕРЖИМО ДЕНЬГАМИ А Я СВОБОДНЫЙ ОТ ЗАДРОТСТВА ЧЕЛОВЕК
СКАЧАТЬ КНИГУ ПО НОВОМУ ФРЕЙМВОРКУ БЕCПЛАТНО И БЕЗ РЕГИСТРАЦИИ
ЛУЧШЕ Я ИЗУЧУ ЕЩЕ РАЗ ФРЕЙМВОРК
СТАБИЛЬНОСТЬ НЕ НУЖНА Я НЕ ИЗУЧАЛ ФРЕЙМВОРК НЕДЕЛЮ ПОЙДУ ИЗУЧУ НОВЫЙ ФРЕЙМВОРК
ВСЕ ПРОСТО И ПОНЯТНО ОШИБКА TypeError: Object has no method
ЭТО ЖЕ ОЧЕВИДНО КАК ЕЕ РЕШИТЬ
ПРИШЛО ВРЕМЯ ИЗУЧАТЬ ФРЕЙМВОРК
ККОКОКОКОКОКОКО НОВЫЕ ТЕХНОЛОГИИ ФРЕЙМВОРК ПРОГРАММИРОВАНИЕ КОКОКОКОКОКОКО
#120 #511380
>>511352

> схоронило себе несколько готовых проектов


Пиздец, вот такое быдло мне и выдавало "кококо какое у вас портфолио скромное", скромное, зато мое сука, мне как-то совесть не позволяет затирать теги в чужих проекта и копипастить их пиздец.
#121 #511381
>>510907
Я уже удалил все майсоклы которые нашел, кроме хамовского. не работает (кстати наверное зря из Program files его удалил, один раз он работал лел). Хотя это может еще из-за того, что я в настройках и апаче хост для zend rameworka прописал, хуй пойми короче.
#122 #511382
>>511380

>быдло мне и выдавало


Я однажды кинул быдлу ссылочку на свой гитхаб. Быдло начало втирать мне, что это не я типа проекты писал, а спиздил их. Потому что я не подписываю коммиты своим именем по паспорту, а ПСЕВДОНИМОМ. Быдло тупое поколение вконтакте сука не понимает что такое псевдоним нахуй.
#123 #511383
>>510931
сервер в рашке забанен. лел хуяси.
86 Кб, 640x633
#124 #511384
>>511383
Последнее обвиняет ресурс в неправомерной публикации произведений известного американского писателя Рэя Брэдбери. На сайте, без согласования с правообладателями, были размещены романы «451 градус по Фаренгейту», «Вино из одуванчиков», «Марсианские хроники» и «Золотые яблоки солнца».
#125 #511388
>>511378

>ФРЕЙМВОРК САМ СЕБЯ НЕ ИЗУЧИТ


>ТУПОЕ БЫДЛО ОДЕРЖИМО ДЕНЬГАМИ А Я СВОБОДНЫЙ ОТ ЗАДРОТСТВО ЧЕЛОВЕК


Я тебя пофиксил немного, в соответствии с канонами.
#126 #511391
Помогите пожалуйста. Где найти материалы чтобы лучше разобраться с регулярными выражениями? Основы понял и простенькие регулярки пишу без проблем, но от попыток написать скрипт "Grammar Nazi" уже взрывается голова :(
#127 #511392
Пыханы (и ОП), что скажете по поводу этого текста?
http://www.linux.org.ru/forum/development/2792914#comment-2793120
Интересуют второй и третий абзацы.
https://github.com/V3N0m21/Uppu3 #128 #511396
>>510048
>>507767

Посмотрел твой код. Хорошо что ты освоил твиг и доктрину, это радует, но пока много замечаний.

> class FileResource


Странное название. Я встречал FileModel, File (по моему лучший вариант), но FileResource это что-то непривычное.

Ты используешь доктрину. Это хорошо, надеюсь ты уже успел убедиться как это удобно, когда не надо писать руками DataMapper, и тебе предоставляется готовый. Более того, если ты будешь использовать доктрину в сложных проектах (где много таблиц и связей между ними), ты увидишь что она способна сэкономить немало времени. Советую и дальше ее стараться использовать.

Но конечно стоит получше изучить ее особенности. Пока я вижу, что ты научился загружать/сохранять сущности в БД, но это лишь самое начало.

Доктрина это довольно сложная библиотека. Ей надо читать метаданные (аннотации в классе FileResource), ей надо парсить и преобразовывать DQL-запросы. Это все требует кеширования, иначе твой код при каждом вызове скрипта будет тратить на это время. В мануале к доктрине это явно написано: http://doctrine-orm.readthedocs.org/en/latest/reference/improving-performance.html#metadata-and-query-caches

> it is strongly discouraged to use Doctrine without a Metadata and Query cache (preferably with APC or Memcache as the cache driver).



Кеширование задается в настройках, и у тебя есть возможность задать какой именно хранилище используется. Для доктрины, мне кажется, хорошо подходит APC, так как это локальный кеш, который использует shared memory (шареную память? на жаргоне ее так называют) и потому работает быстро (но у него есть и недостатки: он недоступен из командной строки, так как память приналежит пользователю, под которым запущен Апач, он локальный по отношению к серверу, но в данном случае это нам и нужно).

Если кеш APC не доступен, можно использовать кеш на файлах. Он наименее эффективен, но для локалхоста, где у нас один пользователь, его возможностей хватит. Зато он не требует ничего устанавливать.

Memcache на мой взгляд для кеширования метаданных наименее выгоден. Он требует установки и доступ к нему идет не напрямую. а через сетевое соединение. Заметь, что он может быть хорош для других задач.

Если открыть исходники доктрины, мы увидим что при выключенном devMode и не указанном кеше, она сама пытается подобрать драйвер:

http://www.doctrine-project.org/api/orm/2.2/source-class-Doctrine.ORM.Tools.Setup.html#163

Мне это не нравится и кажется что это неправильный подход. Ну к примеру, то, что у тебя установлено расширение memcache еще не значит что на том же компьютере запущен сервер memcache.

Потому не полагайся на доктрину, а напиши свой код, который проверяет наличие кеша apc и задействует либо его либо файлы. И выучи команду очистки кеша, разумеется, доктрина не всегда может понять что он устарел при изменениях кода.

Также, доктрине нужна папка для прокси-классов. Прокси-классы это классы-наследники сущностей (вроде FileResource) которые доктрина использует при ленивой загрузке. В общем, та, что она берет по умолчанию, наверно подойдет, но тебе надо знать команду для ее очистки.

Настройки соединения с базой из bootstrap.php хорошо бы вынести в файл-конфиг вида

$dbname = ...;
$user = ....;

> https://github.com/V3N0m21/Uppu3/blob/master/app/Helper/Resize.php#L9


Обычно конструктор только инициализирует объект. Я думаю, лучше тут конструктор не делать, а для ресайза сделать метод resize.

> https://github.com/V3N0m21/Uppu3/blob/master/app/Helper/Resize.php#L26


> strtolower(strrchr($file, '.'));


Не стоит использовать strtolower так как она корежит нелатинские буквы в utf-8.

Определять тип картинки лучше не по расширению, а по типу который вернет например getimagesize().

Опции надо делать константами, а не строками. И в твоем случае список опций запутанный и я не понимаю, зачем их там много и чем они различаются. Мне кажется, это неудачный способ и лучше параметры ресайза задавать как-то по-другому. Ну например, задавать max-height и max-width. Или хотя бы сделать комментарии, как каждый режим работает.

Код определения размеров слишком большой, надо его как-то объединить, потому что там явно многое повторяется.

Зачем нужен exact, я не понимаю. По моему он приводит к нарушению пропорций изображения.

Маленькие картинки не должны увеличиваться. Размеры надо округлять, так как при делении может получиться нечелое число.

> if (imagetypes() & IMG_JPG) {


> imagejpeg($this->imageResized, $savePath, $imageQuality);


Тут при отстутсвии поддердки JPG ты просто молча выходишь из функции как ни в чем не бывало. Это неправильно, фактически картинка не создана а мы делаем вид что все в порядке.

Аналогично с default. Ошибки не должны умалчиваться.

Также, посмотри на свойства этого класса, некторые из них мне кажется можно заменить на обычные переменные и явно передавать между функциями.

> $invertScaleQuality = 9 - $scaleQuality;


Это странный код так как PNG это формат без потерь и его качество не зависит от этого значения. Это значение просто определяет время которое упаковщик потратит на поиск оптимального способа сжатия.

Для MediaInfo надо сделать нормальный методы сохранения/распаковки из JSON, а то ты возвращаешь из getMediaInfo просто массив без методов (так как StdClass это и есть фактически массив только без функций для работы с ним, и его не стоит вообще никогда использовать поэтому). При желании можно даже добавить новый тип в doctrine, чтобы она сама его запаковывала/распаковывала при загрузке и сохранеии, как опсиано тут:

http://doctrine-orm.readthedocs.org/en/latest/cookbook/custom-mapping-types.html
http://doctrine-orm.readthedocs.org/en/latest/cookbook/advanced-field-value-conversion-using-custom-mapping-types.html

Я думаю, стоит сделать тип который позволяет указать класс в который надо мапить данные:

@ORM\Column(type="json", class="MediaInfo")

Такой тип позволит в будущем сохранять в базу и объекты других классов. Также, ты можешь замапить MediaInfo на отдельную таблицу или добавить колонки в files, но это не так интересно.

Я впрочем, изучил код класса Type в доктрине, и у него нет доступа к аннотациям. Так что так сделать не получится, придется делать так:

@ORM\Column(type="mediaInfoType")

> https://github.com/V3N0m21/Uppu3/blob/master/public/index.php#L27


Эту простыню надо разбить на функции или методы.

> https://github.com/V3N0m21/Uppu3/blob/master/public/index.php#L27


> $file = $entityManager->find('Uppu3\Resource\FileResource', $id);


Что если такого файла нет в базе?

> echo $app->render


echo не нужен

>if (in_array($file->getExtension(), $pictures)){


> } elseif (in_array($file->getExtension(), $video)) {


По моему ты сделал неправиьно. Шаблон для просмотра файла должен быть один, а вот уже в нем стоит if/elseif для разных типов.

> header("Content-Disposition: attachment; filename=".$file->getName());


В заголовках можно использовать только латинницу (точнее ASCII), потому нельзя использовать filename для задания имени файла. Для задания имени файла надо делать URL, который на него заканчивается.

> $name = "upload/".$id."-".$file->getName()."-txt";


это (и все аналогичные места) нужно вынести в функцию

> } else {


> echo "Not found";


Неправильно. страница ошибки должна отдаваться с кодом 404 (коды состояния: https://ru.wikipedia.org/wiki/%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2_%D1%81%D0%BE%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%B8%D1%8F_HTTP#404 )

Более того, в СЛим уже встроена функция выдачи такой страницы: http://docs.slimframework.com/errors/404/

$entityManager лучше предоставлять как синглтон Слима (также, его удобно сокращать до em): http://docs.slimframework.com/di/overview/ через $app->em

> php_value max_execution_time 1000


Очень странная настройка.

> <meta charset="utf8" />


Слеш в одиночных тегах в HTML не нужен, это не XML

Выравниваение кода в шаблонах ужасное, надо делать отступы, иначе твой код тяжело читать.

> <img src="/upload/resize/resize-{{file.name}}">


Ссылка на картинку должна формироваться функцией или методом, а не быть вписана в нескольких местах кода.

> Размер файла:</strong> {{ file.size }} байт


Стоило бы сделать функцию (и прокинуть ее в twig как фильтр) для вывода размера в человекочитаемом виде.

> name="load"


Не стоит называть кнопку и поле с файлом одинаково.

Также, если требуется запускать какие-то команды, надо добавить файл README с описанием как установить проект.

Где дамп базы данных? Я даже установить наверно его не смогу без нее. Или у тебя он создается доктриной? По моему опыту, удобнее все же создавать таблицы и колонки самостоятельно, так как можно точнее указать тип, добавить комментарии итд.

При попытке отправить форму с невыбранным файлом надо выдавать ошибку.

> https://github.com/V3N0m21/Uppu3/blob/master/app/templates/layout.html#L6


Путь к CSS неправильный. Надо делать не относительный путь, а путь относительно корня сайта, в Слиме есть функция для его получения: http://docs.slimframework.com/request/paths/

Если чо-то непонятно, задавай вопросы.
https://github.com/V3N0m21/Uppu3 #128 #511396
>>510048
>>507767

Посмотрел твой код. Хорошо что ты освоил твиг и доктрину, это радует, но пока много замечаний.

> class FileResource


Странное название. Я встречал FileModel, File (по моему лучший вариант), но FileResource это что-то непривычное.

Ты используешь доктрину. Это хорошо, надеюсь ты уже успел убедиться как это удобно, когда не надо писать руками DataMapper, и тебе предоставляется готовый. Более того, если ты будешь использовать доктрину в сложных проектах (где много таблиц и связей между ними), ты увидишь что она способна сэкономить немало времени. Советую и дальше ее стараться использовать.

Но конечно стоит получше изучить ее особенности. Пока я вижу, что ты научился загружать/сохранять сущности в БД, но это лишь самое начало.

Доктрина это довольно сложная библиотека. Ей надо читать метаданные (аннотации в классе FileResource), ей надо парсить и преобразовывать DQL-запросы. Это все требует кеширования, иначе твой код при каждом вызове скрипта будет тратить на это время. В мануале к доктрине это явно написано: http://doctrine-orm.readthedocs.org/en/latest/reference/improving-performance.html#metadata-and-query-caches

> it is strongly discouraged to use Doctrine without a Metadata and Query cache (preferably with APC or Memcache as the cache driver).



Кеширование задается в настройках, и у тебя есть возможность задать какой именно хранилище используется. Для доктрины, мне кажется, хорошо подходит APC, так как это локальный кеш, который использует shared memory (шареную память? на жаргоне ее так называют) и потому работает быстро (но у него есть и недостатки: он недоступен из командной строки, так как память приналежит пользователю, под которым запущен Апач, он локальный по отношению к серверу, но в данном случае это нам и нужно).

Если кеш APC не доступен, можно использовать кеш на файлах. Он наименее эффективен, но для локалхоста, где у нас один пользователь, его возможностей хватит. Зато он не требует ничего устанавливать.

Memcache на мой взгляд для кеширования метаданных наименее выгоден. Он требует установки и доступ к нему идет не напрямую. а через сетевое соединение. Заметь, что он может быть хорош для других задач.

Если открыть исходники доктрины, мы увидим что при выключенном devMode и не указанном кеше, она сама пытается подобрать драйвер:

http://www.doctrine-project.org/api/orm/2.2/source-class-Doctrine.ORM.Tools.Setup.html#163

Мне это не нравится и кажется что это неправильный подход. Ну к примеру, то, что у тебя установлено расширение memcache еще не значит что на том же компьютере запущен сервер memcache.

Потому не полагайся на доктрину, а напиши свой код, который проверяет наличие кеша apc и задействует либо его либо файлы. И выучи команду очистки кеша, разумеется, доктрина не всегда может понять что он устарел при изменениях кода.

Также, доктрине нужна папка для прокси-классов. Прокси-классы это классы-наследники сущностей (вроде FileResource) которые доктрина использует при ленивой загрузке. В общем, та, что она берет по умолчанию, наверно подойдет, но тебе надо знать команду для ее очистки.

Настройки соединения с базой из bootstrap.php хорошо бы вынести в файл-конфиг вида

$dbname = ...;
$user = ....;

> https://github.com/V3N0m21/Uppu3/blob/master/app/Helper/Resize.php#L9


Обычно конструктор только инициализирует объект. Я думаю, лучше тут конструктор не делать, а для ресайза сделать метод resize.

> https://github.com/V3N0m21/Uppu3/blob/master/app/Helper/Resize.php#L26


> strtolower(strrchr($file, '.'));


Не стоит использовать strtolower так как она корежит нелатинские буквы в utf-8.

Определять тип картинки лучше не по расширению, а по типу который вернет например getimagesize().

Опции надо делать константами, а не строками. И в твоем случае список опций запутанный и я не понимаю, зачем их там много и чем они различаются. Мне кажется, это неудачный способ и лучше параметры ресайза задавать как-то по-другому. Ну например, задавать max-height и max-width. Или хотя бы сделать комментарии, как каждый режим работает.

Код определения размеров слишком большой, надо его как-то объединить, потому что там явно многое повторяется.

Зачем нужен exact, я не понимаю. По моему он приводит к нарушению пропорций изображения.

Маленькие картинки не должны увеличиваться. Размеры надо округлять, так как при делении может получиться нечелое число.

> if (imagetypes() & IMG_JPG) {


> imagejpeg($this->imageResized, $savePath, $imageQuality);


Тут при отстутсвии поддердки JPG ты просто молча выходишь из функции как ни в чем не бывало. Это неправильно, фактически картинка не создана а мы делаем вид что все в порядке.

Аналогично с default. Ошибки не должны умалчиваться.

Также, посмотри на свойства этого класса, некторые из них мне кажется можно заменить на обычные переменные и явно передавать между функциями.

> $invertScaleQuality = 9 - $scaleQuality;


Это странный код так как PNG это формат без потерь и его качество не зависит от этого значения. Это значение просто определяет время которое упаковщик потратит на поиск оптимального способа сжатия.

Для MediaInfo надо сделать нормальный методы сохранения/распаковки из JSON, а то ты возвращаешь из getMediaInfo просто массив без методов (так как StdClass это и есть фактически массив только без функций для работы с ним, и его не стоит вообще никогда использовать поэтому). При желании можно даже добавить новый тип в doctrine, чтобы она сама его запаковывала/распаковывала при загрузке и сохранеии, как опсиано тут:

http://doctrine-orm.readthedocs.org/en/latest/cookbook/custom-mapping-types.html
http://doctrine-orm.readthedocs.org/en/latest/cookbook/advanced-field-value-conversion-using-custom-mapping-types.html

Я думаю, стоит сделать тип который позволяет указать класс в который надо мапить данные:

@ORM\Column(type="json", class="MediaInfo")

Такой тип позволит в будущем сохранять в базу и объекты других классов. Также, ты можешь замапить MediaInfo на отдельную таблицу или добавить колонки в files, но это не так интересно.

Я впрочем, изучил код класса Type в доктрине, и у него нет доступа к аннотациям. Так что так сделать не получится, придется делать так:

@ORM\Column(type="mediaInfoType")

> https://github.com/V3N0m21/Uppu3/blob/master/public/index.php#L27


Эту простыню надо разбить на функции или методы.

> https://github.com/V3N0m21/Uppu3/blob/master/public/index.php#L27


> $file = $entityManager->find('Uppu3\Resource\FileResource', $id);


Что если такого файла нет в базе?

> echo $app->render


echo не нужен

>if (in_array($file->getExtension(), $pictures)){


> } elseif (in_array($file->getExtension(), $video)) {


По моему ты сделал неправиьно. Шаблон для просмотра файла должен быть один, а вот уже в нем стоит if/elseif для разных типов.

> header("Content-Disposition: attachment; filename=".$file->getName());


В заголовках можно использовать только латинницу (точнее ASCII), потому нельзя использовать filename для задания имени файла. Для задания имени файла надо делать URL, который на него заканчивается.

> $name = "upload/".$id."-".$file->getName()."-txt";


это (и все аналогичные места) нужно вынести в функцию

> } else {


> echo "Not found";


Неправильно. страница ошибки должна отдаваться с кодом 404 (коды состояния: https://ru.wikipedia.org/wiki/%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2_%D1%81%D0%BE%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%B8%D1%8F_HTTP#404 )

Более того, в СЛим уже встроена функция выдачи такой страницы: http://docs.slimframework.com/errors/404/

$entityManager лучше предоставлять как синглтон Слима (также, его удобно сокращать до em): http://docs.slimframework.com/di/overview/ через $app->em

> php_value max_execution_time 1000


Очень странная настройка.

> <meta charset="utf8" />


Слеш в одиночных тегах в HTML не нужен, это не XML

Выравниваение кода в шаблонах ужасное, надо делать отступы, иначе твой код тяжело читать.

> <img src="/upload/resize/resize-{{file.name}}">


Ссылка на картинку должна формироваться функцией или методом, а не быть вписана в нескольких местах кода.

> Размер файла:</strong> {{ file.size }} байт


Стоило бы сделать функцию (и прокинуть ее в twig как фильтр) для вывода размера в человекочитаемом виде.

> name="load"


Не стоит называть кнопку и поле с файлом одинаково.

Также, если требуется запускать какие-то команды, надо добавить файл README с описанием как установить проект.

Где дамп базы данных? Я даже установить наверно его не смогу без нее. Или у тебя он создается доктриной? По моему опыту, удобнее все же создавать таблицы и колонки самостоятельно, так как можно точнее указать тип, добавить комментарии итд.

При попытке отправить форму с невыбранным файлом надо выдавать ошибку.

> https://github.com/V3N0m21/Uppu3/blob/master/app/templates/layout.html#L6


Путь к CSS неправильный. Надо делать не относительный путь, а путь относительно корня сайта, в Слиме есть функция для его получения: http://docs.slimframework.com/request/paths/

Если чо-то непонятно, задавай вопросы.
#129 #511399
>>511396
Пиздец чувак, книги писать или статьи на хабр не пробовал? ебать ты графоман.
https://github.com/blackberryJam/abiturients #130 #511406
>>510048
>>508294

> https://github.com/blackberryJam/abiturients/blob/master/abiturients.sql


Убери из дампа CREATE DATABASE, USE так как у пользователя може быть другая база данных с другим именем.

local лучше сделать ENUM или TINYINT, либо преобразовывать в число при выборке.

> UNIQUE KEY `email_token` (`email`,`token`)


Это значит что один email может встречатья несколько раз если с ним идут разные токены. То точно это имел в виду?

> https://github.com/blackberryJam/abiturients/blob/master/app/autoloader.php#L3


А автозагрузчике надо проверять есть ли такой файл. Иначе код вроде

if (class_exists('sadadsa'))

упадет с ошибкой

> https://github.com/blackberryJam/abiturients/blob/master/app/classes/AbiturientService.php#L9


> $mapper = new AbiturientsMapper($GLOBALS['pdo']);


Не, так не годится. Во-первых ты не должен создавать маппер в сервисе (а должен передавать извне), во-вторых не должен использовать GLOBALS.

Лучше сделать так:

$service = new AbiturientService($abiturientMapper, $validator);

Это назвыается Dependency Injection через конструктор. Урок по теме: https://gist.github.com/codedokode/e1d31a31b37d5f635057

Заметь что для контроллеров обычно это не применяют. Обычно контроллер имеет доступ к DI контейнеру и может получить любой сервис из него. Так что, раз уж ты решил нагородить ООП, сделай-ка DI container. Это класс, который создает или (при повторном обращении) возвращает ранее созданные сервисы, он выглядит примерно так:

$mapper = $container->getAbiturientMapper();
$service = $container->getAbiturientService();

Сами сервисы и мапперы не должны ничего про него знать (иначе код будет запутанным и мы получим service locator), а вот контроллер вполне может иметь к нему доступ. Создавать сам контейнер удобно в bootstrap.php.

Как альтернатива, можно создать контейнер с публичными свойствами и в bootstrap прописать в них мапперы и сервисы, тогда к ним можно обращаться как $container->someMapper. Это работает когда сервисов немного.

В общем код вроде new AbiturientsMapper(...); должен быть только в одном месте. Любой сервис должен быть только в одном экземпляре и не должен создаваться по несколько раз (иначе будет путаница, один экземпляр проставил какое-то поле, а ты вызваешь другой экземпляр где у поля другое значение).

Также, тут в принципе можно было встроить валидатор в сервис. Но можно и отдельным классом, почему бы и нет.

> $string = $string . substr($chars, mt_rand(1, $numChars) - 1, 1);


Тут лучше использовать mb функции, хоть тут и латинница, но лучше привыкать использовать их.

> if ($mapper->isTokenReserved($string) == true) {


> return $this->generateToken($length);


Это потенциально бесконечный цикл. Сделай ограничение. например, можно поместить генерацию токена внутрь for с определенным числом попыток.

> setcookie('flashMessage', $id, time() + 600);


для куки надо указывать path, иначе она будет видна не на всех страницах. Почитай про path тут:

http://citforum.ru/internet/html/cookie.shtml (рус)
https://en.wikipedia.org/wiki/HTTP_cookie#Domain_and_Path (англ)

> switch ($id) {


> case '1':


Я бы сделал это число константой с понятным названием. Также, мне кажется функция readMessage должна сама брать его из кук. А то куки ставятся в сервисе, а читаются где-то в другом месте.

> https://github.com/blackberryJam/abiturients/blob/master/app/classes/AbiturientsMapper.php#L6


> public function __construct($pdo)


Нужен тайп-хинт, они полезны и улучшают код.

> foreach ($abiturient as $property => $value)


Мне кажется список полей лучше хранить в массиве, так как теоретически у класса могут добавитьяс поля которые не сохраняются в таблицу. И твой код при добавлении таких полей сломается, это плохо. Код не должен ломатья от добавления поля к классу.

> if ($result["COUNT(x)"] == 0) {


Используй алиас: SELECT COUNT() AS cnt

Если ты слабо знаешь SQL, в ОП-посте есть неплохие задачки на него, которые помогут изучить его лучше.

> https://github.com/blackberryJam/abiturients/blob/master/app/classes/FrontController.php


> switch ($_SERVER['REQUEST_URI']) {


Если в URL есть параметры, например /?x=1 то этот код не заработает. надо их отрезать из URL.

Также, что выведется если ни одно из условий не срабоатет? Белая страница? Не, сделай-ка страицу 404 с выдачей соответствущего кода HTTP/1.1 404 Not Found

> processTheRequest


Обычно это называют handle()

> https://github.com/blackberryJam/abiturients/blob/master/app/classes/MainPageController.php#L7


> if ($SERVER['REQUEST_METHOD'] == 'GET') {


А что если метод другой? Если это HEAD? Я думаю, этот if лучше вообще убрать.

> foreach ($abiturient as $property => $value) {


> if (isset($values[$property])) {


> $abiturient->$property = trim($values[$property]);


Это опасный код так как пользователь может прописать любые значения в любые поля объекта. В том числе те поля, которые он редактировать не должен иметь возможность. Я думаю, тут должен быть список допустимых полей.

> https://github.com/blackberryJam/abiturients/blob/master/app/classes/UserpageController.php#L4


> public function processTheRequest()


Эта функция слишком длинная. Вынеси отдельные действия в отдеьные методы, например: чтение данных из POST, редирект.

> if ($_SERVER['REQUEST_METHOD'] == 'GET') {


> if (array_key_exists('token', $_COOKIE)) {


> $abiturient = $mapper->getByToken($_COOKIE['token']);


Не понимаю почему это делается толбко при GET.

Алсо, проверку на HTTP метод лучше бы вынести в функцию/метод вроде $this->isPost()

> $_SERVER['DOCUMENT_ROOT']


Лучше бы это не использовать (оно не всегда правильно указывает), а путь определять например через _ _ DIR _ _ .

Также, твои контроллеры выглядят какими-то переусложненными. Может стоит сделать базовый контроллер и в него вынести какие-то общие вещи, не знаю.

> https://github.com/blackberryJam/abiturients/blob/master/app/classes/UserpageController.php#L51


Это используется? Если да то надо отрефакторить так как вывод сообщений должен быть в шаблоне, а не в контроллере.

> public function validateInput(Abiturient $abiturient)


Надо очищать список ошибок иначе функцию нельзя вызвать 2 раза подряд.

Имена и фамилии могут содержать дефис, пробел, апостроф: О'Генри.

> $birthyear < 1950) {


Я думаю это несправедливо по отношению к 65-летним

> if ($string != 'male' && $string != 'female') {


Это надо сделать константами в классе Абитуриент.

> strtolower(


Она ломает нелатинские символы и лучше ее вообще не использовать.

> (@){1}


Это то же самое что @

> (.){1,40}


Круглые скобки не требуются

> $regexp = '/(.){1,40}(@){1}(.){1,40}/i';


Эта регулярка не привязана к краям строки и пройдет значение 'лол w@w.com asdadad asd asd as'

Также, почему не используешь флаг u в регулярке? Проще всегда его использовать.

> $regexp = '/[0-9]{3}/';


Регулярка не привязана к краям строки

> <meta name="viewport" content="width=device-width, initial-scale=1">


Это зачем?

> https://github.com/blackberryJam/abiturients/blob/master/templates/basicTemplate.html.php#L12


Это надо вынести в отдельный CSS файл

Папки css и fonts лучше вынести из templates, например в папку static/bootstrap. Также, не стоит менять что-то в бустрапе и удалять файлы, так как потом не разберешься что именно поменялось. Бутстрап надо просто распаковать в папку, ничего не меняя. Аналогично стоит поступать со всеми сторонними библитеками.

> <input type="text" placeholder="Пол ('male', 'female')"


Это надо сделать радиокнопками: http://htmlbook.ru/samhtml5/formy

Изучи какие элементы и возможности есть в формах. Обрати внимание, что в HTML5 есть атрибуты для клиентской валидации, то есть браузер будет проверят форму по заданным тобой правилам. Добавь эти атрибуты. Помни также что клиентская валидация не отменяет серверную валидацию на стороне PHP, она лишь служит для удобства пользователя.
https://github.com/blackberryJam/abiturients #130 #511406
>>510048
>>508294

> https://github.com/blackberryJam/abiturients/blob/master/abiturients.sql


Убери из дампа CREATE DATABASE, USE так как у пользователя може быть другая база данных с другим именем.

local лучше сделать ENUM или TINYINT, либо преобразовывать в число при выборке.

> UNIQUE KEY `email_token` (`email`,`token`)


Это значит что один email может встречатья несколько раз если с ним идут разные токены. То точно это имел в виду?

> https://github.com/blackberryJam/abiturients/blob/master/app/autoloader.php#L3


А автозагрузчике надо проверять есть ли такой файл. Иначе код вроде

if (class_exists('sadadsa'))

упадет с ошибкой

> https://github.com/blackberryJam/abiturients/blob/master/app/classes/AbiturientService.php#L9


> $mapper = new AbiturientsMapper($GLOBALS['pdo']);


Не, так не годится. Во-первых ты не должен создавать маппер в сервисе (а должен передавать извне), во-вторых не должен использовать GLOBALS.

Лучше сделать так:

$service = new AbiturientService($abiturientMapper, $validator);

Это назвыается Dependency Injection через конструктор. Урок по теме: https://gist.github.com/codedokode/e1d31a31b37d5f635057

Заметь что для контроллеров обычно это не применяют. Обычно контроллер имеет доступ к DI контейнеру и может получить любой сервис из него. Так что, раз уж ты решил нагородить ООП, сделай-ка DI container. Это класс, который создает или (при повторном обращении) возвращает ранее созданные сервисы, он выглядит примерно так:

$mapper = $container->getAbiturientMapper();
$service = $container->getAbiturientService();

Сами сервисы и мапперы не должны ничего про него знать (иначе код будет запутанным и мы получим service locator), а вот контроллер вполне может иметь к нему доступ. Создавать сам контейнер удобно в bootstrap.php.

Как альтернатива, можно создать контейнер с публичными свойствами и в bootstrap прописать в них мапперы и сервисы, тогда к ним можно обращаться как $container->someMapper. Это работает когда сервисов немного.

В общем код вроде new AbiturientsMapper(...); должен быть только в одном месте. Любой сервис должен быть только в одном экземпляре и не должен создаваться по несколько раз (иначе будет путаница, один экземпляр проставил какое-то поле, а ты вызваешь другой экземпляр где у поля другое значение).

Также, тут в принципе можно было встроить валидатор в сервис. Но можно и отдельным классом, почему бы и нет.

> $string = $string . substr($chars, mt_rand(1, $numChars) - 1, 1);


Тут лучше использовать mb функции, хоть тут и латинница, но лучше привыкать использовать их.

> if ($mapper->isTokenReserved($string) == true) {


> return $this->generateToken($length);


Это потенциально бесконечный цикл. Сделай ограничение. например, можно поместить генерацию токена внутрь for с определенным числом попыток.

> setcookie('flashMessage', $id, time() + 600);


для куки надо указывать path, иначе она будет видна не на всех страницах. Почитай про path тут:

http://citforum.ru/internet/html/cookie.shtml (рус)
https://en.wikipedia.org/wiki/HTTP_cookie#Domain_and_Path (англ)

> switch ($id) {


> case '1':


Я бы сделал это число константой с понятным названием. Также, мне кажется функция readMessage должна сама брать его из кук. А то куки ставятся в сервисе, а читаются где-то в другом месте.

> https://github.com/blackberryJam/abiturients/blob/master/app/classes/AbiturientsMapper.php#L6


> public function __construct($pdo)


Нужен тайп-хинт, они полезны и улучшают код.

> foreach ($abiturient as $property => $value)


Мне кажется список полей лучше хранить в массиве, так как теоретически у класса могут добавитьяс поля которые не сохраняются в таблицу. И твой код при добавлении таких полей сломается, это плохо. Код не должен ломатья от добавления поля к классу.

> if ($result["COUNT(x)"] == 0) {


Используй алиас: SELECT COUNT() AS cnt

Если ты слабо знаешь SQL, в ОП-посте есть неплохие задачки на него, которые помогут изучить его лучше.

> https://github.com/blackberryJam/abiturients/blob/master/app/classes/FrontController.php


> switch ($_SERVER['REQUEST_URI']) {


Если в URL есть параметры, например /?x=1 то этот код не заработает. надо их отрезать из URL.

Также, что выведется если ни одно из условий не срабоатет? Белая страница? Не, сделай-ка страицу 404 с выдачей соответствущего кода HTTP/1.1 404 Not Found

> processTheRequest


Обычно это называют handle()

> https://github.com/blackberryJam/abiturients/blob/master/app/classes/MainPageController.php#L7


> if ($SERVER['REQUEST_METHOD'] == 'GET') {


А что если метод другой? Если это HEAD? Я думаю, этот if лучше вообще убрать.

> foreach ($abiturient as $property => $value) {


> if (isset($values[$property])) {


> $abiturient->$property = trim($values[$property]);


Это опасный код так как пользователь может прописать любые значения в любые поля объекта. В том числе те поля, которые он редактировать не должен иметь возможность. Я думаю, тут должен быть список допустимых полей.

> https://github.com/blackberryJam/abiturients/blob/master/app/classes/UserpageController.php#L4


> public function processTheRequest()


Эта функция слишком длинная. Вынеси отдельные действия в отдеьные методы, например: чтение данных из POST, редирект.

> if ($_SERVER['REQUEST_METHOD'] == 'GET') {


> if (array_key_exists('token', $_COOKIE)) {


> $abiturient = $mapper->getByToken($_COOKIE['token']);


Не понимаю почему это делается толбко при GET.

Алсо, проверку на HTTP метод лучше бы вынести в функцию/метод вроде $this->isPost()

> $_SERVER['DOCUMENT_ROOT']


Лучше бы это не использовать (оно не всегда правильно указывает), а путь определять например через _ _ DIR _ _ .

Также, твои контроллеры выглядят какими-то переусложненными. Может стоит сделать базовый контроллер и в него вынести какие-то общие вещи, не знаю.

> https://github.com/blackberryJam/abiturients/blob/master/app/classes/UserpageController.php#L51


Это используется? Если да то надо отрефакторить так как вывод сообщений должен быть в шаблоне, а не в контроллере.

> public function validateInput(Abiturient $abiturient)


Надо очищать список ошибок иначе функцию нельзя вызвать 2 раза подряд.

Имена и фамилии могут содержать дефис, пробел, апостроф: О'Генри.

> $birthyear < 1950) {


Я думаю это несправедливо по отношению к 65-летним

> if ($string != 'male' && $string != 'female') {


Это надо сделать константами в классе Абитуриент.

> strtolower(


Она ломает нелатинские символы и лучше ее вообще не использовать.

> (@){1}


Это то же самое что @

> (.){1,40}


Круглые скобки не требуются

> $regexp = '/(.){1,40}(@){1}(.){1,40}/i';


Эта регулярка не привязана к краям строки и пройдет значение 'лол w@w.com asdadad asd asd as'

Также, почему не используешь флаг u в регулярке? Проще всегда его использовать.

> $regexp = '/[0-9]{3}/';


Регулярка не привязана к краям строки

> <meta name="viewport" content="width=device-width, initial-scale=1">


Это зачем?

> https://github.com/blackberryJam/abiturients/blob/master/templates/basicTemplate.html.php#L12


Это надо вынести в отдельный CSS файл

Папки css и fonts лучше вынести из templates, например в папку static/bootstrap. Также, не стоит менять что-то в бустрапе и удалять файлы, так как потом не разберешься что именно поменялось. Бутстрап надо просто распаковать в папку, ничего не меняя. Аналогично стоит поступать со всеми сторонними библитеками.

> <input type="text" placeholder="Пол ('male', 'female')"


Это надо сделать радиокнопками: http://htmlbook.ru/samhtml5/formy

Изучи какие элементы и возможности есть в формах. Обрати внимание, что в HTML5 есть атрибуты для клиентской валидации, то есть браузер будет проверят форму по заданным тобой правилам. Добавь эти атрибуты. Помни также что клиентская валидация не отменяет серверную валидацию на стороне PHP, она лишь служит для удобства пользователя.
#131 #511409
>>511157
На похапенет иди, там все обстоятельно расписано. Вкратце - магический метод, который вызывается при инициализации объекта класса.
#132 #511411
>>511383
В луковицу не способен?
#133 #511415
>>511153

На кодеакадеми очень базовые знания. Про ООП можно почитать в учебнике из ОП поста, там про него отдельная глава и есть хорошие задания для закрепления.
61 Кб, 888x590
#134 #511451
>>511347
Нет никакой "природной способности" к логике. Ты можешь ее развить изучая науку Логику. Но ты должен подойти к этому ответственно, т.е. активно рассуждая и рефлексируя над прочитанным материалом, пытаясь уловить/достроить мысль автора. После, если тебе понравится, можно перейти к математической логике, это к слову, тоже интересно.
#135 #511452
>>511347
Если понимаешь, как работают циклы и условия и можешь решить задачу про рост школотронов из учебника ОПа, то все заебись. Потому что есть люди которые не могут понять даже этого. Хуй пойми как они вообще живут. Дальше вопрос наличия времени и усидчивости.
#136 #511456
>>510035
Поясните за фреймворки и энти MVC, насколько они полезны? Я пытался один ковырять, но там вообще какая-то хуета мало похожая на php.
#137 #511457
>>511406

>> https://github.com/blackberryJam/abiturients/blob/master/abiturients.sql


>Убери из дампа CREATE DATABASE, USE так как у пользователя може быть другая база данных с другим именем.


>


>local лучше сделать ENUM или TINYINT, либо преобразовывать в число при выборке.


>


>> UNIQUE KEY `email_token` (`email`,`token`)


>Это значит что один email может встречатья несколько раз если с ним идут разные токены. То точно это имел в виду?


Дамп был старый, уже поменял.

>> switch ($id) {


>> case '1':


>Я бы сделал это число константой с понятным названием. Также, мне кажется функция readMessage должна сама брать его из кук. А то куки ставятся в сервисе, а читаются где-то в другом месте.


Не совсем понял, как и зачем здесь использовать константы. Но теперь код выглядит как-то так:
public function readFlashMessage($cookie)
{
switch ($cookie) {
case 'success':
return 'Данные отправлены.';
break;
}

if (array_key_exists('flashMessage', $_COOKIE)) {
$service = new AbiturientService();
$flashMessage = $service->readFlashMessage($_COOKIE['flashMessage']);
$this->render($abiturient, $errors, $flashMessage);
$service->unsetFlashMessage();
} else {
$this->render($abiturient, $errors);
}

>> https://github.com/blackberryJam/abiturients/blob/master/app/classes/UserpageController.php#L51


>Это используется? Если да то надо отрефакторить так как вывод сообщений должен быть в шаблоне, а не в контроллере.


Да, функция вызывается тут: https://github.com/blackberryJam/abiturients/blob/master/templates/form.html.php#L4
Сначала там был этот самый код, который теперь выведен в отдельную функцию displayAlerts().

С остальными замечаниями буду разбираться, спасибо.
#137 #511457
>>511406

>> https://github.com/blackberryJam/abiturients/blob/master/abiturients.sql


>Убери из дампа CREATE DATABASE, USE так как у пользователя може быть другая база данных с другим именем.


>


>local лучше сделать ENUM или TINYINT, либо преобразовывать в число при выборке.


>


>> UNIQUE KEY `email_token` (`email`,`token`)


>Это значит что один email может встречатья несколько раз если с ним идут разные токены. То точно это имел в виду?


Дамп был старый, уже поменял.

>> switch ($id) {


>> case '1':


>Я бы сделал это число константой с понятным названием. Также, мне кажется функция readMessage должна сама брать его из кук. А то куки ставятся в сервисе, а читаются где-то в другом месте.


Не совсем понял, как и зачем здесь использовать константы. Но теперь код выглядит как-то так:
public function readFlashMessage($cookie)
{
switch ($cookie) {
case 'success':
return 'Данные отправлены.';
break;
}

if (array_key_exists('flashMessage', $_COOKIE)) {
$service = new AbiturientService();
$flashMessage = $service->readFlashMessage($_COOKIE['flashMessage']);
$this->render($abiturient, $errors, $flashMessage);
$service->unsetFlashMessage();
} else {
$this->render($abiturient, $errors);
}

>> https://github.com/blackberryJam/abiturients/blob/master/app/classes/UserpageController.php#L51


>Это используется? Если да то надо отрефакторить так как вывод сообщений должен быть в шаблоне, а не в контроллере.


Да, функция вызывается тут: https://github.com/blackberryJam/abiturients/blob/master/templates/form.html.php#L4
Сначала там был этот самый код, который теперь выведен в отдельную функцию displayAlerts().

С остальными замечаниями буду разбираться, спасибо.
#138 #511460
>>511396
Спасибо, буду разгребать
Дамп SQL не вложил потому что это пока еще совсем черновик, и я хотел уяснить основные моменты и чтоб ты указал мне на критические косяки в моей архитектуре проекта.
Сейчас пройдусь по твоим замечаниям и выложу с дампом
sage #139 #511477
ОП,ты няша
>>510035
спасибо что ты есть
#140 #511478
>>511477
случаенно приклеилась
54 Кб, 600x600
#141 #511489
>>511373
>>511374
>>511378
пуканчики разогреты, теперь атмосфера в треде веселее. я доволен.

>>511399
о, неофит в первый раз увидел пасту жирного опа.
#142 #511503
>>511415

>учебник из ОП-поста


Ты про тот, где одни задачи и почти нихуя пояснений, типа сам допрёшь, чо как маленький? Нет, спасибо, как-нибудь окольными путями.
#143 #511507
>>511503
Есть гипотеза, что лучше сразу же начинать читать чужой идиоматический код. Буквально нужно читать тысячи проектов. Так ты за год наберёшься опыта больше, чем некоторые за 50-80 лет. Составь список из веб-приложений на пхп. Прочитай их, паралельно пиши свои. 95% чтения кода, 2% написание своего кода, 3% чтение документации и блог постов. Уже через два месяца ты достигнишь уровня сениора, потому что человеческий мозг лучше всего учится на множественных примерах.
#144 #511514
>>511503
Потому что эти задачи учат мышлению, а не применению готовых решений.

>>511507
Так ты станешь макаком-копипастером, не более, если будешь бездумно копировать чужой код.

>Уже через два месяца ты достигнишь уровня сениора


>достигнишь


Школьник, вот давай ты сначала сам "достигнишь", а потом будешь феласофстовавать?
#145 #511521
>>511457
Немного поправил.
Наверное, даже лучше так:
public function readFlashMessage()
{
switch ($_COOKIE['flashMessage']) {
case 'success':
return 'Данные отправлены.';
break;
}
}

if (array_key_exists('flashMessage', $_COOKIE)) {
$service = new AbiturientService();
$flashMessage = $service->readFlashMessage();
$this->render($abiturient, $errors, $flashMessage);
$service->unsetFlashMessage();
} else {
$this->render($abiturient, $errors);
}
sage #146 #511526
>>510839
Вся суть рузских PHP-вованов.

> 2015


> XAMMP


> MySQL


> винда

588 Кб, 550x2396
#147 #511527
Програны, помогите решить задачу или ткните носом где можно почитать о таком. В гугле только счетчики кликов и скачиваний.
Нaпишитe счeтчик количeства мaшин проeзжающих чeрез АЗC, eсли дaны тaкие услoвия(чтобы в любой момeнт времeни он отобрaжал прaвильное количество машин):
с 8:00 - 17:00 - 2800 авто/9 часов (540 минут) = 5 мaшин в минуту
с 17:00 - 22:00 - 2000 авто/4часа (240 мин) = 9 мaшин в минуту
с 22:00 - 01:00 - 200 авто/ 3 часа (180 минут) = 2 мaшины в минуту
с 01:00 - 8:00 - 560 авто/ 8 часов (480 минут) = 1 мaшин в минуту
#148 #511533
>>511526
ТОЛЬКА ЛИНУКС ТОЛЬКА ПЛАТНЫЙ ХОСТИНГ ТОЛЬКА ХАРДКОР
#149 #511537
>>511527
А тебе зачем?
#150 #511538
>>511533
Через пять минут:

посоны, почему у миня не работает?((( я скопипастил все как в видеоуроке от вована
c:\denwer\../composer/autoload.php
#151 #511540
>>511538

>c:\denwer


Там опинсурвир, ващет.
Тоже игранул.
#152 #511544

>Вы когда-нибудь слышали про теорему о бесконечных обезьянах? В ней утверждается, что если обезьяна будет беспорядочно нажимать на клавиши клавиатуры бесконечное количество времени, то рано или поздно напечатает заданный текст



О, вот откуда пошел этот мемс про пхп-макак.
#153 #511546
>>511514

> эти задачи учат мышлению


А что делать, если тебя жутко бесит, так, что хочется уебать автору, необходимость разгребать говно, вроде "есть два стула..." языком PHP? Может есть какая-то альтернатива? Лично меня, эти задачи только раздражают, а это не очень способствует обучению.
#154 #511547
>>511373

>в нос ударил запах блевотины

#155 #511548
>>511526
Ты что сказать-то хотел, залетный?
#156 #511550
>>510839
Форматируй диск С:\, чтобы избавится от вируса.
#157 #511558
>>511537
устраиваюсь фронтэндщиком, зачем-то в тесте дали задание на знание пхп
#158 #511565
>>511546
Есть альтернатива, она называется cms. В вордпрессе нет ничего плохого.

Поймите, быдланчики, что мы (снобы), не из высокомерия или какого-то самоутверждения заставляем вас учить "всю эту хуйню". (Впрочем, есть и такие)
Просто программирование не самая легкая профессия, и малейшая неточность приводит к тому, что код становится непригодным, или крайне неудобным, его приходится чуть ли не с нуля переписывать. Можно плохо класть асфальт, можно плохо чистить канализацию, но в программировании недопустимо кое-как выполнять свою работу. Или отлично, или никак.

Вы лезете сюда, потому что услышали, "шо тут много бабла нахуй". Но эти деньги платятся именно за безукоризненную работу.
За плохие знания никто много не заплатит. В лучшем случае эти деньги можно выбить трудолюбием, выполняя примитивные задания много раз на каком-нибудь фрилансе (что большинство и делает).
#159 #511567
>>511565

>можно плохо класть асфальт, можно плохо чистить канализацию


Низзя.

>в программировании недопустимо кое-как выполнять свою работу


Допустимо, если потребителя всё устраивает.
#160 #511569
>>511558
>>511527
Каким образом получать время и дату начала отсчёта?
Другими словами, с какой точки времени ведётся отсчёт?
#161 #511573
>>511527
Странно, тогда в самой вакансии наверное было указано, что нужно знать php?
Если ты его не знаешь, зачем пытаешься туда устроиться?
Работодатель же не из прихоти пишет требования.
Если мы решим тебе эту задачу, завтра перед тобой встанет новая. Изучи основы php, и смело устраивайся в это место.

Задача решается точно так же как и в js ветками условий и преобразованием даты.
Условные конструкции в php
http://php.net/manual/ru/control-structures.if.php
Работа с датой и временем
http://php.net/manual/ru/ref.datetime.php
#162 #511578
>>511569
Какого отсчета? По-моему в задаче нужно написать функцию, которая возвращает либо среднее число автомобилей, проезжающих по статистике через АЗС в тот временной промежуток, к которому эта временная метка относится, либо возвращать количество автомобилей за отрезок времени, если на вход функции подается начало и конец промежутка.
#163 #511581
>>511569
я так понимаю время получается из формы
дата не важна
отсчет времени от 8 утра
т.е. если пользователь введет
17:02 ему должно выдать 2818 машин
#164 #511589
>>511578
>>511581
Я думал, что это для вещи вроде "У нас уже заправилось 90000 автомобилей". Для этого надо знать дату и время начала работы АЗС.
#165 #511590
>>511567

>Допустимо, если потребителя всё устраивает.


Поэтому я и упомянул о cms. Там применяются готовые типовые решения (пусть и далеко не идеально реализованные). Никто не будет грузить нестандартными вещами, заставлять решать "головоломки". (Правда головной болью будет, если понадобится что-то обновить, написать плагин, а все перекосится и рухнет)
Все готовенькое, надо только зазубрить, куда тыкать, и где какую последовательность букв прописать в коде, чтобы изменить конфигурацию.

А вот в работе программиста подобные "головоломки" встречаются достаточно часто, и таки придется решать нестандартные задания, но не абстрактные, а вполне себе практичные.
#166 #511597
>>511567

>если потребителя всё устраивает


Погоди, а что значит "пользователя все устраивает"?
Может он не знает, что ты ему впариваешь некачественную работу, и думает что все будет работать долго и надежно.
А оно у него через месяц начнет сыпать ошибками. Ну напишет он в сердцах злобный отзыв о таком "фрелансыре", со вздохом пойдет к следующему вовану, авось хоть здесь повезет.

Лично я буду вполне доволен, если зарплаты программистов рухнут до среднестатистических по стране, тогда в отрасли останутся только люди, которые любят свое дело. Мне не нужны деньги, я хочу гордиться творением своих рук, хочу общаться с людьми, такими же увлеченными и добросовестными.
#167 #511600
>>511597

Ну так и иди работать к единомышленникам, какое тебе дело до остальных людей, которые просто зарабатывают деньги и не такие идейные, как ты? Что за снобизм?
#168 #511603
>>511600
Ну так я здесь и нахожусь, в /pr, а не в /web, /biz, /b или /po.
Эти разделы целиком в вашем распоряжении, уважаемые.
#169 #511606
>>511565
Госпади мне даже твою пасту читать лень, я бы это время лучше потратил на создание формы на пхп для своего блога.
#170 #511608
>>511606

>6 строк


>паста


Тычо, из бе?
#171 #511609
>>511538
но извини, я собираюсь еще и хостинг покупать, чтобы свои говноподелия тестировать, когда я еще ни копейки даже этим не заработал. у меня такой принцип - пока я чем-то не заработал, я в это не вкладываюсь.
#172 #511612
>>511597
Ну да. Человек обращается к индусам, чтоб работало долго и надёжно, а не из желания сэкономить.
#173 #511613
>>510102
>>510105
>>510112
>>510129

Как обычно PHP дауны кроме PHP ничего не знают, отсюда и рождают такие ебанутые костыли...
Я хоть и сам щас на PHP программирую, но начинал далеко не с него, и опыт большой в разных языках...
Так вот запускать php скрипт (в cli) каждые 13 секунд, лучше всего так, это самый простой и не костыльный способ:
watch -n 13 'php -f time13.php'
#174 #511615
>>511558

>фронтэндщиком


иди плагины к вордерпсс поприкручивай лучше, фронтендщик нашелся мне.
#175 #511617
>>511603

Ну и что ты забыл в треде, посвященному языку с самым низким порогом вхождения и следовательно так привлекательного для ненавистных тобою не идейных быдлокодеров? Иди в тред какого-нибудь Haskell или Lisp, там ты точно нас не увидишь.
#176 #511620
>>511617
Скорее что ты забыл в треде, где учат язык, если ты не желаешь его учить?
#177 #511621
>>511615
пфф я решу эту задачу на ангуляре с закрытыми глазами
а hr и дауны вроде тебя считают что без пыхи не обойтись
#178 #511625
>>511617
Вполне себе полноценный язык, со своими недостатками конечно же. Бессмысленно восторгаться одним языком и говорить о несостоятельности другого может только школьник, который не разбирается ни в одном из них.

>Иди


Опять быдлота пытается куда-то меня послать. Надо же.
Но это действует только на слабых и нерешительных людей.

Я еще раз повторяю омежкам: вы видите, какой скам лезет в нашу родную "ботанскую" зону? Будьте решительнее, и увереннее в себе. У вас все получится.
Как вы любите говорить, добра :з, и все такое.
#179 #511627
Есть блог на вордпресс, на него поставлен шаблон и несколько плагинов (облако тегов, последние записи и т.д.). Хочу сделать вверху небольшое меню, даже точнее вывод ссылок, то есть создать страницы, на которых будет выводится определённая рубрика, как это сделать? Как вывести в водпресс на отдельной странице записи определённой рубрики? Обязательно лезть в ПХП код или можно так?
#180 #511629
>>511627
иди сразу нахуй
#181 #511632
>>511620

Дык я его и учу. Просто ты должен знать, какая репутация у пхп, так что приходить сюда и удивляться тому, что тред полон тех, кто пришел в программирование за легкими деньгами это как минимум странно.

>>511625

Дело не в том, полноценен он или нет, а в ЦА этого языка.
#182 #511633
>>511617

>PHP - язык с самым низким порогом вхождения


Это неправда, мне кажется. Правильно писать на PHP довольно сложно. Сложнее, чем на каком-нибудь питоне.
#183 #511636
>>511613

>cli


чо? какая еще командная строка?
#184 #511639
>>511633

Порог вхождение и сложность "правильного" написания это разные вещи.
#185 #511643
Мудрый оп, теперь я понимаю, почему ты так долго держишь тред в бамплимите: чтобы скрыть его от мимотралей и даунов, не умеющих в закладки.
Самое то между 500 и 800 постом, когда пишут только вопросы по делу и твои полезные ответы.
Вопрос сейчас в том, форсировать уход в бамплимит поддержанием флуда, или оставить все как есть и не обращать внимания?
#186 #511650
>>511632
ну да двачую, пхп чисто денег срубить, а для души и красоты на С кодят.
#187 #511662
>>511636
Задача была запускать с скрипт в консоле каждые 13 секунд
#188 #511669
>>511662

>доступ в ssh есть


аа, так это консоль была...
53 Кб, 1171x850
#189 #511674
>>510035
Как вам ТЗ?
#190 #511676
Господа есть желающие подзаработать?

Задание:

[code]Создание личного кабинета для присвоения статуса и номера принято/в работе/выполненно заявкам созданным с помощью компонента Joomla RS Form. Создание странички с отслеживанием статуса заявки по номеру.[/code]

жду ваши на своём фейкомыльце: koinou@mail.ru
#191 #511697
Я тут столкнулся с одной уязвимостью, вроде как XSRF, только мне нужно защитить не пользователя от XSRF атаки, а базу данных от пользователя. Дело в том, что есть одно Джаваскрипт приложение. Оно отсылает пост запрос на страничку с пхп скриптом и в network видно что это за страница и что за параметры, соответственно пользователь может их подделать. Генерировать токен не вариант, ведь он виден пользователю тоже. Вот что нашел в гугле:

\tRewriteCond %{REQUEST_METHOD} POST
\tRewriteCond %{REQUEST_URI} !/contact.php [NC]
\tRewriteCond %{REMOTE_ADDR} !127.0.0.1
\tRewriteRule .* - [F,L]

Так вот если я сделаю подобный .htaccess файл с именем скрипта в rewriterule и именем жс приложения в rewritecond, даст ли это 100% ную защиту от подделки пост запросов или есть способ её обойти?
#192 #511763
Как написать СЕО-скрипт, напримре тот который покажет количество страниц в гугле определённого сайта. Это надо делать при помощи специального API гугла, где можно посмотреть это API. Или просто вбить в гугле при помощи скрипта site:имя_сайта.com и считать результаты?
#193 #511790
>>511763
Зачем тебе это?
#194 #511811
>>511451
да, но есть начальный уровень, и склад ума
#195 #511825
>>511811
Чушь. Начальный уровень быстро прокачивается.
Что касается склада ума, то я уже три раза говорил, что из-за вашей неуверенности в себе ваши места занимают всякие коляны и кабаны. Вот они почему-то ни разу не сомневаются в своих способностях, хотя тупее тебя в два раза. Забавно, да?

ОП, замути им какой-нибудь психологический тренинг, с котиками, смайликами и петушками. Я пытаюсь их подбодрить, а они не понимают и на меня еще агрятся.
#196 #511829
>>511825

А схуяли омежка = умный? Что за бред? Если он портит себе жизнь парясь изо всякой хуйни, то он явно интеллектом не блещет.
#197 #511869
>>511790
прост)
#198 #511871
>>511674
Простенькое.
22 Кб, 379x318
#199 #511961
>>511406
Такой контейнер нормален?
#200 #511993
>>511961
Ой, он же не может собрать объект, получив параметры.
#202 #512082
>>511790
Интересно, я ещё думаю как пишут скрипты для проверки уникальности текста. Моё представление этого выглядит следующим образом, проверяемый текст разбивается в группы по три слова, причём делается это подобно очереди, то есть одни уходит в группе из трёх слов другой на его место подходит. Потом каждая из этих групп, собранная например в массив делает вызов гугла и проверяет есть ли совпадение например в первых 10 записях (вот тут не знаю как скрипт может проверить выбил ли гугл прямы совпадение, просканировать весь ответ первой десятки и если найти совпадение с текущей группой слов, посчитать что совпадение есть, так? Или есть какие-то АПИ гугла?) и так уже дальше всё выразить в процентах. Или я не так думаю?
#203 #512150
>>511871
Если простенькое, то что такое быстрая смена номера на сайта? еще и на шроах
#204 #512156
>>512150
Шорткоды https://codex.wordpress.org/ru:Shortcode_API
Что подразумевает заказчик под "номерами", нужно узнать у заказчика. Это часть твоей работы, гордись.
Не нужно решать "ебанутые задачки опа", тут живое общение с людьми. Что Галина Федоровна имела ввиду под "номерами"? Ну вот те цифры на сайте. Молодой человек, вы программист, или нет? За что я вам деньги плачу?

Но в целом задание вполне легкое и адекватное. Чаще тебе придется сталкиваться с переписыванием кривых плагинов, распидорашеными виджетами и т.д.
Внесешь изменение в одну функцию - потянет за собой еще десять, и все перекосится.
А если ты не используешь гит и не знаешь как откатить правку... Энджой йо сиэмэс.
#205 #512160
>>512156
я использую гит. но вообще я уже удалил это письмо, ибо никогда не работал с вордпрессом и в душе не ебу как сверстать кучку сереньких блоков, чтобы потом прикрутить их к вордпрессу. зато на фл.ру как-то удачно и внезапно предложили написать простенькие пхп-функции для тырнет-магазина за норм цену - наконец-то.
#206 #512162
удалил майсокл из панели задачи ХАМПа и он заработал, ну нада жи.
#207 #512163
>>512162
идивительные приключения виндузатника
#208 #512226
Какой-то пхп тред нынче не уютный, куча тролей, а я думал позадавать вопросики, по SQL'ю так ничего и не посоветовали.
#209 #512228
>>511674
у меня от него WEB-мастер. Проблевался.
#210 #512254
>>511396
https://github.com/V3N0m21/Uppu3
Подправил по замечаниям, но есть парочка вопросов

>При желании можно даже добавить новый тип в doctrine, чтобы она сама его запаковывала/распаковывала при загрузке и сохранеии



Как вот это должно по идее работать? Я должен замапить класс МедиаИнфо как колонку таблицы files?

>В заголовках можно использовать только латинницу (точнее ASCII), потому нельзя использовать filename для задания имени файла.



Но у меня оно почему-то нормально работает с кирилицей. Но если это неправильно, то можешь подсказать что почитать чтоб сделать правильно?

>Для задания имени файла надо делать URL, который на него заканчивается.


Потому что я не совсем понял что это значит

>Путь к CSS неправильный. Надо делать не относительный путь, а путь относительно корня сайта, в Слиме есть функция для его получения: http://docs.slimframework.com/request/paths/



Что-то мне эта слимовская функция не помогла, она возвращает совсем не то что мне нужно
#211 #512270
Тихо-то как.
#212 #512272
http://hh.ru/vacancy/13908085
А вы бы откликнулись на эту вакансию, если бы подходили по требованиям?
#213 #512273
>>512156

> Не нужно решать "ебанутые задачки опа"


Что ты бугуртишь? Они действительно ебанутые и не нужны.
#214 #512284
>>512272
Судя по тому, сколько лет она болтается в сети, «мы» не откликаются, причём массово.
#215 #512288
>>512284
Что, правда не один год уже мозолит глаза?

>«мы» не откликаются, причём массово


А чего так?
262 Кб, 564x354
#216 #512294
>>512288
1. «Ведущая студия» без пруфов,
2. Слова «ищем целеустремленных веб-разработчиков для работы над серьезными веб-проектами в сильной команде» — это значит, условия как в макДональдс, работа под огнём придирок и обвинений (сей жызненный факт просто надо знать, дизайн-студии давно в таком состоянии, года с 2004 точно)
3. «Разработка и развитие сложных, интересных и известных веб-проектов» — запоминайте. Сложные, высоконагрюзенные ИНТЕРЕСНЫЕ ПРОЕКТЫ, попил, откат, попил, откат, попил, откат, попил, откат, попил, откат, попил, откат...
4. «Знание PHP / HTML / CSS / JS / Jquery» и сразу же «от 40 000» — это за два языка сразу и вёрстку на дивах? До вычета налогов или после? Справа объявление: «Слесарь службы вентиляции и сантехники от 33 000 до 37 000 руб».
5. «Самостоятельность, самокритичность, умение видеть в программировании конечный продукт, а не только процесс написания крутого кода» — самокритичность? Чёбля? Не только работа под огнём придирок и обвинений, но и готовность обвинять себя самого?!! См. хотя бы книги Брайана Трейси, там подробно расписано, а тж. полезно гуглить всё про самооценку, хотя именно этих обезьянок изучает не психология, тут другие науки нужны, счас расскажу какие.
6. «Достойный оклад, квартальные премии по результатам проектов, большие перспективы роста» — ст. 165 УК РФ, «Злоупотребление доверием при отсутствии явных признаков хищения».
7. «Свободный график: 45 часов в неделю (с учетом перерывов на обед и досуг) в любом интервале времени, возможность удаленной работы» — чому не 40 часов в неделю? А случайно не ст. ли это 163 УК РФ «Вымогательство», от 4-х лет сидеть.
8. «Обратите внимание, что на собеседовании мы попросим вас пройти тест на знание PHP. Пожалуйста, не откликайтесь на вакансию, если вы не готовы его пройти по каким-либо причинам» — ст. 330 УК РФ, «Самоуправство», да ещё и нарушение Конституции скорее всего, хотя на неё людишки срать хотели в этой стране. До 7-8 лет в общем.

Если я буду когда-нибудь подбирать название для проекта, я десять раз подумаю. «Кодиксь, Битриксь, Лыбаксь, Пюппиксь» — нет, это не для нас. Наигрались «мы» в эти игры. Хватит уже.
262 Кб, 564x354
#216 #512294
>>512288
1. «Ведущая студия» без пруфов,
2. Слова «ищем целеустремленных веб-разработчиков для работы над серьезными веб-проектами в сильной команде» — это значит, условия как в макДональдс, работа под огнём придирок и обвинений (сей жызненный факт просто надо знать, дизайн-студии давно в таком состоянии, года с 2004 точно)
3. «Разработка и развитие сложных, интересных и известных веб-проектов» — запоминайте. Сложные, высоконагрюзенные ИНТЕРЕСНЫЕ ПРОЕКТЫ, попил, откат, попил, откат, попил, откат, попил, откат, попил, откат, попил, откат...
4. «Знание PHP / HTML / CSS / JS / Jquery» и сразу же «от 40 000» — это за два языка сразу и вёрстку на дивах? До вычета налогов или после? Справа объявление: «Слесарь службы вентиляции и сантехники от 33 000 до 37 000 руб».
5. «Самостоятельность, самокритичность, умение видеть в программировании конечный продукт, а не только процесс написания крутого кода» — самокритичность? Чёбля? Не только работа под огнём придирок и обвинений, но и готовность обвинять себя самого?!! См. хотя бы книги Брайана Трейси, там подробно расписано, а тж. полезно гуглить всё про самооценку, хотя именно этих обезьянок изучает не психология, тут другие науки нужны, счас расскажу какие.
6. «Достойный оклад, квартальные премии по результатам проектов, большие перспективы роста» — ст. 165 УК РФ, «Злоупотребление доверием при отсутствии явных признаков хищения».
7. «Свободный график: 45 часов в неделю (с учетом перерывов на обед и досуг) в любом интервале времени, возможность удаленной работы» — чому не 40 часов в неделю? А случайно не ст. ли это 163 УК РФ «Вымогательство», от 4-х лет сидеть.
8. «Обратите внимание, что на собеседовании мы попросим вас пройти тест на знание PHP. Пожалуйста, не откликайтесь на вакансию, если вы не готовы его пройти по каким-либо причинам» — ст. 330 УК РФ, «Самоуправство», да ещё и нарушение Конституции скорее всего, хотя на неё людишки срать хотели в этой стране. До 7-8 лет в общем.

Если я буду когда-нибудь подбирать название для проекта, я десять раз подумаю. «Кодиксь, Битриксь, Лыбаксь, Пюппиксь» — нет, это не для нас. Наигрались «мы» в эти игры. Хватит уже.
#217 #512299
>>512272

>Полная занятость, полный день


нет, я же не из ДС.
#218 #512301
>>512294

>это за два языка сразу и вёрстку на дивах?


там наверное знание как у меня - на уровне сделать форму обратной связи и прикрутить готовый плагин.
22 Кб, 771x230
#219 #512311
Я хороший PHP-программист. Ура!
http://corp.wamba.com/ru/test/test/
10 Кб, 480x360
#220 #512348
>>510035
эх, еще надо бы задачку опа написать, а потом сделать два прожекта на зенд фреймворке и пожалуй джумоле. как же заебало уже учиться и создаваться сайты в пустоту tbh.
#221 #512353
>>512311
Замечательный тест. На половину вопросов я не особо и знал ответ, так что-то слышал, где-то видел, но наверняка утверждать не берусь и при этом 202 балла. Лол. Хороший программист. Да уж.
#222 #512355
>>512353
Там ещё уровни "отличный программист" и "гуру пхп".
#223 #512357
>>512311
Я ебал такие тесты. С лицом летчика натыкал 155 баллов. Был уверен только в одном вопросе. Хороший программист че.
23 Кб, 487x268
#224 #512378
Почему оба инклюда работают (закоменченный и обычный)? В блоке if.
PHP такой умны и всё равно понимает, что я хотел сказать?
#225 #512432
>>512311

меньше половины же набрал. Там есть результат действительно хороший то приглашают резюме отправить по моему.
#226 #512433
>>512378

Закомментиированный код не работает, с чего ты взял? Можешь удалить и проверить.
#227 #512436
>>512433
А я проверил. Работает.
#228 #512439
>>512436
потмоу что $file
#229 #512442
>>512439
Что $file?
Если include $file закомментировать, а другой -- раскомментировать, всё работает.
#230 #512444
http://pastebin.com/G1BpwtEA
Почему после первой строчки у меня работает setcookie(), а если её поменять на вторую, то нет?
#231 #512448
>>512442

Почитай в мануале список каталогов где ищется файл при include. Лучше исплоьзовать абсолбтный путь от корня диска чтоюы не было противоречий:

$file = _ _ DIR _ _ . ....
#232 #512450
>>512444
Потому что кукис отправляются в виде заголовков ответа сервера, им не должен предшествовать вывод, то есть echo или html-теги.
Тебе нужно сначала изучить, что такое куки, и как они реализованы. Изучить http-протокол, чтобы знать, что такое заголовки, и как вообще обменивается данными клиент с сервером.
#233 #512452
>>512450
Это мне известно.
Вопрос в том, почему тогда с первой строчкой всё работает? В обоих случаях кука ставится после вывода хтмл.
#234 #512453
>>512448
Ну я так и хочу сделать, просто заметил такую странность.
#235 #512457
>>512452
тег ?> удали
#236 #512458
>>512452
Не может такого быть. Скинь полностью весь файл, а не эти два инпута, непонятно где ты там что ставишь.
#237 #512460
>>512444

Что значит «не работает»? В чем это проявляется? Как выглядит заголовок Set-Cookie в вкладке Network в отладчике в браузере?
#238 #512465
>>512460
Вот такая ошибка:
[Fri Jul 10 18:08:50.175907 2015] [:error] [pid 1223] [client 127.0.0.1:51109] PHP Warning: Cannot modify header information - headers already sent by (output started at /var/www/site.local/templates/form.html.php:28) in /var/www/site.local/app/classes/AbiturientService.php on line 35, referer: http://site.local/userpage

Причина её ясна -- кука устанавливается после вывода HTML. Мне просто интересно, почему в первом случае это игнорируется.
#240 #512469
>>512465

Ты уверен что ты просто не ошибся? Надо не гадать на кофейной гуще, а сделать повторяемый эксперимент и проверить:

<?php

ini_set('display_errors', 1);
for ($i = 0; $i < 2000; $i++) {
echo $i % 10;
setcookie(...);
}
echo "END";

Выполни этот скрипт и выясни при каком числе символов начинаются ошибки. А я тогда предложу варианты объяснений.
15 Кб, 374x240
#241 #512474
>>512469
Работает без ошибок. Куку ставил аналогичную.
#242 #512477
>>512474

Попробуй поднять число до 10000.
#243 #512485
>>512474

Вот, держи улучшенный скрипт: http://ideone.com/pybybS

Конечно такой скрипт ты должен был написать сам. Инженер должен уметь ставить такие эксперименты.
#244 #512489
>>512477
$i < 3491
Всё работает.

$i < 3492
В браузере:
Веб-страница недоступна
ERR_RESPONSE_HEADERS_TOO_BIG

$i < 10000
В лог приходит аналогичная ошибка. 5903 штуки.

>[Fri Jul 10 18:45:11.131622 2015] [:error] [pid 18621] [client 127.0.0.1:51214] PHP Warning: Cannot modify header information - headers already sent by (output started at /var/www/site.local/test.php:5) in /var/www/site.local/test.php on line 6


И ещё в браузере:
Веб-страница недоступна
ERR_RESPONSE_HEADERS_TOO_BIG
#245 #512490
>>512489

Попробуй браузер получше. У меня хром под Windows перевариает гораздо больше кук.

Также ты можешь заменить установку куки на заголовок поменьше например

header("X:1"); // всего 3 байта :)
#246 #512492
>>512485
Лог:
[Fri Jul 10 18:51:43.915408 2015] [:error] [pid 1222] [client 127.0.0.1:51258] PHP Fatal error: Uncaught exception 'ErrorException' with message 'Cannot modify header information - headers already sent by (output started at /var/www/site.local/test.php:16)' in /var/www/site.local/test.php:17\nStack trace:\n#0 [internal function]: {closure}(2, 'Cannot modify h...', '/var/www/site.l...', 17, Array)\n#1 /var/www/site.local/test.php(17): setcookie('test', '12345', 1436543502)\n#2 {main}\n thrown in /var/www/site.local/test.php on line 17

А в браузере опять "слишком большие заголовки".
#247 #512493
>>512489

Также если ты под линуксом, ты можешь отправится запрос из консоли:

telnet localhost 80 (ENter)
GET /script.php HTTP/1.1 (ENter)
Host: site.local (ENter)
(ENter)
(ENter)

Заодно увидишь страницу глазами браузера.
#248 #512494
>>512490
У меня хром под убунтой. Не экзотика вроде.
#249 #512495
>>512493
Ок, сейчас попробую.
#250 #512496
>>512492

Добавь значение counter в текст ErrrorExceotion:

new ErrorException("Stop, counter = $counter");

Кстати, интересно, я первый раз слушу про ошибку с слишком большими заголовками. Век живи, век учись.
#251 #512497
>>512492

Кстати раз ты под линуксом, ты знаешь про команду

tail -f log

которая следит за логом и постоянно выводит его в консоли? Удобно.

Также есть less +F log которая позвояет переключаться между отслеживанием лога и обычным просмотром.
#252 #512502
>>512493
Вот, что получилось. Как это читать?

anon@anon-desktop:~$ telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET /var/www/site.local/test.php HTTP/1.1
Host: site.local

HTTP/1.1 200 OK
Date: Fri, 10 Jul 2015 15:58:06 GMT
Server: Apache/2.4.7 (Ubuntu)
X-Powered-By: PHP/5.5.9-1ubuntu4.11
Content-Length: 0
Content-Type: text/html

Connection closed by foreign host.
anon@anon-desktop:~$
#253 #512506
>>512502

> GET /var/www/site.local/test.php HTTP/1.1


Надо писат тут не путь к файлу, а путь из URL который у тебя в браузере. То есть просто /test.php

Ну сам подумай, откуда браузер знает где ледит файл на сервере? он не знает, потому передает тот путь что в URL, а уже Апач определяет где этот файл на самом деле.

Странно что Апач ответил кодом 200, мне кажется тут должно было быть 404 Not Found, у тебя наверно mod_rewrite используется там в htaccess.
#254 #512509
>>512497
Нет, я только начинаю осваивать. Консоль использую только при работе с git, рестарте апача, некоторых манипуляциях с файлами.
Ну и ещё пара утилит только с консольным интерфейсом.
#255 #512510
>>512502

Сервер отдал тебе в ответ пустую страницу, судя по заголовку Powered-By, это просто запустился PHP скрипт который ничего не вывел (Content-Length: 0). Иначе ты бы увидл то, что он вывел, в низу под заголовками.
#256 #512514
>>512506

>у тебя наверно mod_rewrite используется там в htaccess


Ага.

>>512510
Уже понял. Вот что вывело в итоге:

....тут_много_цифр....0123456789012345 <-----закончилось на 5

Counter=4095
<br />
<b>Fatal error</b>: Uncaught exception 'ErrorException' with message 'Cannot modify header information - headers already sent by (output started at /var/www/site.local/test.php:16)' in /var/www/site.local/test.php:17
Stack trace:
#0 [internal function]: {closure}(2, 'Cannot modify h...', '/var/www/site.l...', 17, Array)
#1 /var/www/site.local/test.php(17): setcookie('test', '12345', 1436544765)
#2 {main}
thrown in <b>/var/www/site.local/test.php</b> on line <b>17</b><br />
Connection closed by foreign host.
#257 #512523
>>512514

Таким образом, получается что если выведено менбше 4096 (включая символ с номером 0) симвлов, то заголвоки посылать можно, а если больше то нельзя? Как это понять?

Для этого надо вспомнить про такую фичу как output buffering. PHP умеет перехватывать данные выводимые через echo и аналогичные команды и складывать их в буфер. А только при заполнении буфера отдавать Апачу (и в браузер соответтвенно). Очевидно пока данные в буфере, и не переданы Апачу, мы все еще можем слать заголовки.

Это делается для оптимизации при выводе данных маленькими кусками (а любой шаблон это и есть вывод данных маленькими кусками), так как послать блок размером 4096 байт быстрее чем послать 4096 блоков по 1 байту.

Буферизацию ты можешь включать и сам, для каких-то своих целей.

http://habrahabr.ru/company/mailru/blog/248573/
http://php.net/manual/ru/outcontrol.examples.basic.php

Осталось только подтвердить или опровергнуть эту версию. Буферизация управляется такими настройками:

http://php.net/manual/ru/outcontrol.configuration.php

Сделай phpinfo() и посмотри чему они равны у тебя.

Разумеется в коде ты не должен полагаться на буферизацию и должен слать заголовки строго до вывода любых данных.
#258 #512526
>>512514
Я кое-что пропустил. Там выше вот что было:
Set-Cookie: test=12345; expires=Fri, 10-Jul-2015 16:12:45 GMT; Max-Age=-1
Set-Cookie: test=12345; expires=Fri, 10-Jul-2015 16:12:45 GMT; Max-Age=-1
Set-Cookie: test=12345; expires=Fri, 10-Jul-2015 16:12:45 GMT; Max-Age=-1
Set-Cookie: test=12345; expires=Fri, 10-Jul-2015 16:12:45 GMT; Max-Age=-1
Set-Cookie: test=12345; expires=Fri, 10-Jul-2015 16:12:45 GMT; Max-Age=-1
Set-Cookie: test=12345; expires=Fri, 10-Jul-2015 16:12:45 GMT; Max-Age=-1
Set-Cookie: test=12345; expires=Fri, 10-Jul-2015 16:12:45 GMT; Max-Age=-1
Set-Cookie: test=12345; expires=Fri, 10-Jul-2015 16:12:45 GMT; Max-Age=-1
Vary: Accept-Encoding
Content-Length: 4600
Content-Type: text/plain; charset=utf-8

Кук поставилось гораздо больше. Собственно, выше одно задание кук, которые вытолкнули мои предыдущие команды.
#259 #512531
>>512526

Ну вот то, что ты видишь это протокол HTTP. Браузер с его помощью запрашивает и получает страницы и файлы с сервера. И как ты видишь, команда cookie всего лишь отправляет заголовок set-Cookie (который потом читает и разбирает браузер).
7 Кб, 268x45
#260 #512534
>>512523
Круто.
Наверное, надо больше времени уделять изучению конфигурации PHP.
#261 #512539
>>512531
Спасибо большое тебе.
Очень досаждает подобные неочевидные вещи. Можно было, в принципе и забить, но появляется ДИСКОМФОРТ от не полного понимания того с чем имеешь дело и мыслей вроде "а не поведёт ли оно себя так же в следующий раз".
#262 #512562
>>512523
Хм, интересно, я тоже не знал.

Когда сидел под виндой на сборачке, была железная ошибка при попытке выставить куки после вывода, потому что в вампе видимо output_buffering обнулен.
А на линуксе даже не знал, что по-дефолту php ставится с 4кб буффера.
Только что проверил, у меня тоже 4кб. Я как поставил апт-гетом, так ничего и не менял в конфиге.

>>512534
Могу поделиться кусочком знания, если ты это уже знаешь, то может другим пригодится. Я о такой штуке как BOM.
Сохраняя документ в юникоде, твой редактор добавляет в его начало несколько символов, так называемый byte order mark https://ru.wikipedia.org/wiki/Маркер_последовательности_байтов
Таким образом, если у тебя документ сохранен в юникоде, а output_buffering на нуле, ты будешь удивляться, когда ошибка "cookie already sent" будет появляться даже вот в таком абсолютно корректном коде:
<?php
setcookie('Hello', 'world', time()+3600);
echo 'Where is the error?';

Поэтому специально ради php во многих редакторах вшита возможность сохранять в utf8 БЕЗ BOM. То есть этот необязательный символ удаляется. Всегда сохраняй в utf8 без bom. Если увидишь ошибку "cookie already sent", есть смысл проверить, правильно ли сохранен документ.
#263 #512572
>>512562
Этот BOM выводится в HTML, так как ставится перед <?php, да?
#264 #512610
Поясните кто то по поводу скрипта проверки текста на уникальность, эти соображения >>512082 верны или нет?
#265 #512631
>>512562

Она не ради PHP. Символ BOM придуман, чтобы различат кодировки UTF16-BE и UTF-16LE (точнее, это не разные кодировки, а разные представления юникода). В этих кодировках каждый символ состоит из 2 байт, но порядок разный (да, выбрать единственный порядок разработчики не смогли). В utf-8 такой проблемы нет и BOM не требуется. Но тот же блокнот его вставляет.

В принципе BOM не так и плох, в том плане что помогает определить кодировку, но у него есть и недостатки:

— не все программы его понимают и игнорируют
— при склейке нескоьких файлов c BOM мы полуаем символы BOM в середине, если только программа склеивания не умеет их вырезать

BOM в текстовом редакторе или браузере не проблема, так как это невидимый символ, но программы которые что-то делают на уровне байт, он может сломать.

В общем, тут есть и плюсы и минусы.

>>512572

Да, PHP видит что в начале есть контент и отсылает его в браузер. А так как в HTTP ответе заголовки идут до тела ответа, после этого заголовки уже слать нельзя.

>>512610

Поверяют текст отправляя куски в поисковые системы. Поисковые системы такого использования за бесплатно не любят и блокируют подобные запросы. Советую тебе в это не лезть.
#266 #512637
>>512631

>Советую тебе в это не лезть.


Почему?

не тот анон
#267 #512655
>>512631

>Поверяют текст отправляя куски в поисковые системы. Поисковые системы такого использования за бесплатно не любят и блокируют подобные запросы. Советую тебе в это не лезть.


Ясно, я лезть не буду, хочется знать технологию, как это делать. Вернее как определить есть совпадение того или иного куска текста в индексе или нет. Просто скопировать текст полученного ответа, то есть всей страницы с выдачей и искать в ней текущие куски текста? Или же есть более лаконичное решение, какие-нибудь специальные функции от гугла?
#268 #512657
Поясните по поводу доменов и хостингов, вот например купил я один хостинг, а на нём можно размещать сайты только под именем имя_сайта.имя_хостинга.сom то есть домены третьего уровня, я иду и покупаю домен второго уровня и на него переношу свой сайт. Я хочу сделать ещё один сайт (по правилам хостинга я могу разместить два сайта) мне надо покупать ещё один домен?
#269 #512677
>>512655

Если текст есть в гугле очевидно что он не уникален. Попробуй например взять кусок любого текста в кавычках и поискать.

>>512637

Потому что работать стабильно твой скрипт не будет, придется постоянно возиться с проксями, разгадывателями капч и тд.

>>512657

Зависит от хостинга и тарифного плана. Если по правилам можно то наверно все заработает.
#270 #512682
Какие паттерны для проектов лучше всего использовать, чтобы не плодить неподдерживаемый макаронный код?
MVC? Какие ещё есть? Какие вы используете?
Я что-то почитал про MVC, так его и не понял, как-то слишком сложно. Неужели это удобно?
#271 #512688
>>512682

Чтобы не плодить макаронный код, надо не плодить макаронный код. А именно, выносить дублирующийся/похожий код в отдельные функции, использовать ООП там где уместно, разбивать код на слои, разбивать длинные функции на действия, давать хорошие понятные имена функциям и переменным. Я не могу предложить какой-то мануал на эту тему, но могу предложить изучить фреймворки вроде Yii2 и посмотреть как код написан там.

Также, ты можешь пройти задание про студентов и файлообменник (если знаешь ООП, если нет то сначала задачу на ООП) — они помогут тебе писать более правильный код и освоить MVC.
#272 #512690
>>512682

> Я что-то почитал про MVC, так его и не понял, как-то слишком сложно.


Ты либо читал плохую статью, либо что-то не то. MVC прост и логичен, вся его суть в том что мы разбиваем код, обрабатывающий запрос, на 3 незвисимых части, каждая их котрых занимается своим делом.
#273 #512702
Выполняю задачу про студентов, нарисовался такой вопрос: Какой вообще профит использовать ООП для этой задачи? Например, класс студент - нет профита, т.к. всё равно мы реализуем массив $values с введёнными значениями, потом спокойно можем записать значения этого массива в БД, а больше ситуаций где может понадобится объект класса студент я не вижу.
#274 #512712
>>512702

Хорошо, что ты задаешь такой вопрос и хочешь понять почему так, а не иначе.

> Какой вообще профит использовать ООП для этой задачи?


Чтобы научиться использовать ООП в MVC приложениях, сделать код читаемее и понятнее. Вот сравни 2 функции:

function doSmth(array $student)
{
...

function doSmth(Student $student)
{
...

Во второй сразу мы знаем какие есть поля и методы у Student. В первой мы ничего не знаем, кроме того что это какой-то массив с какими-то полями, а чтобы понять с какими именно, надо изучать все места где вызывается функция.

Таким образом злоупотребление массивами ведет к получению трудноподдерживаемого кода, и как следствие увелчиению числа ошибок.

Да, в этом приложении кода немного и подход с массивом в принципе может сработать. Но во-первых, в будущем ты будешь писать большие, а не маленькие приложения. Во-вторых, использование объекта вместо массива почти не увеличит код, зато сделает его гораздо качественнее.

Я тебе советую крепко задуматься прежде чем использовать где-то массив. Избавляйся от массивоориентированного мышления.

Такие приложения, как Drupal и Wordpress страдают этим — и в их коде тяжело ориентироваться.

> т.к. всё равно мы реализуем массив $values с введёнными значениями


Не реализуй массив, пиши значения сразу в объект. Зачем там массив?

> а больше ситуаций где может понадобится объект класса студент я не вижу.


В шаблон передать для вывода, в функцию проверки правильности заполнения формы.
#274 #512712
>>512702

Хорошо, что ты задаешь такой вопрос и хочешь понять почему так, а не иначе.

> Какой вообще профит использовать ООП для этой задачи?


Чтобы научиться использовать ООП в MVC приложениях, сделать код читаемее и понятнее. Вот сравни 2 функции:

function doSmth(array $student)
{
...

function doSmth(Student $student)
{
...

Во второй сразу мы знаем какие есть поля и методы у Student. В первой мы ничего не знаем, кроме того что это какой-то массив с какими-то полями, а чтобы понять с какими именно, надо изучать все места где вызывается функция.

Таким образом злоупотребление массивами ведет к получению трудноподдерживаемого кода, и как следствие увелчиению числа ошибок.

Да, в этом приложении кода немного и подход с массивом в принципе может сработать. Но во-первых, в будущем ты будешь писать большие, а не маленькие приложения. Во-вторых, использование объекта вместо массива почти не увеличит код, зато сделает его гораздо качественнее.

Я тебе советую крепко задуматься прежде чем использовать где-то массив. Избавляйся от массивоориентированного мышления.

Такие приложения, как Drupal и Wordpress страдают этим — и в их коде тяжело ориентироваться.

> т.к. всё равно мы реализуем массив $values с введёнными значениями


Не реализуй массив, пиши значения сразу в объект. Зачем там массив?

> а больше ситуаций где может понадобится объект класса студент я не вижу.


В шаблон передать для вывода, в функцию проверки правильности заполнения формы.
#275 #512713
>>512702

Ну и студент тут по моему центральная часть, вокруг которой строится все приложение. Как-то странно было бы не сделать для него класс. Ведь в любую функцию, делаюшую что-либо с ним, мы должны передать модель студента.
#276 #512717
>>512712
Cпасибо за развёрнутый ответ.
$values использовал для записи данных из инпутов по той причине, что код получается гораздо короче, чем если поочерёдно задавать каждое свойство. Но сейчас понял, что можно просто в конструкторе сделать так, чтобы значения брались из инпутов, наверное, сейчас так и сделаю.

Ещё вопрос по поводу ООП, на сколько сильная должна быть абстракция? Где стоит применять ООП, а где можно и обойтись без этого?
#277 #512721
>>512717

> что можно просто в конструкторе сделать так, чтобы значения брались из инпутов,


Это неправильно. Модель не должна ничего знать про форму и массивы вроде GET. Ты размазываешь функционал по всему коду вместо того чтобы каждый занимался своим делом.

Также неудобно когда конструктор принимает на вход массив, так как иногда имы хотим просто создать объект и заполнять его свойства.

Если ты хочешь, ты можешь добавить в студента метод вроде setAttributes, принимающий массив, но не забудь сделать в нем список допустимых для изменения полей.

> по поводу ООП, на сколько сильная должна быть абстракция? Где стоит применять ООП, а где можно и обойтись без этого?


Нужен класс Студент, класс для работы с таблицей студентов (у меня был урок про DataMapper), ну и наверно класс для валидации студента (хотя это можно поместить и в класс работы с БД).

также могут понадобиться какие-то отделные функции которые ни к одному классу не относятся.
#278 #512723
>>512721
Спасибо! Да, про MVC совсем забыл. Обязательно переделаю: понравилось решение с setAttributes
#279 #512725
Php отличается от цмс типа джумла или вордпресс и т.д.. Чем? Или рhp это не цмс. Каковы преимущества одного над другим?
#280 #512739
>>512725

Тем что PHP это язык программирования, а Joomla и Wordpress написанные на нем программы.
#281 #512740
>>512739
бля, как же меня бесят эти жумала и вордпрессы, пиздец и прочие фреймворки-библиотеки. Знаний программирования и применение пхп кода там никахуя, зато пафоса и ебли со стрелочками фтп клиентами, прикручиванием говна - дохуя.
#282 #512753
>>512740
если знаю пхп с этой поеботой разбирусь ?
#283 #512758
Посоветуйте php скрипт, который в админке позволяет создавать новые поля для ввода. А то я ТЗ невнимательно прочитал, думал нужно самому просто поля прикрутить к простой форме.
#284 #512815
>>512753
я не знаю, я еще сам в это говно не вникал, но от вордпресса я в ахуе. (в смысле, что его невозможно вообще подкорректировать).
#285 #512816
Анон, что не так с кодом? ПОчему не дешифруется?

[code]<?php

error_reporting(-1);

/ Коды для замены букв /
$code = array(
'а'\t=>\t'@',
'ч'\t=>\t'+',
'в'\t=>\t'=',
'у'\t=>\t'&',
'д'\t=>\t'',
'е'\t=>\t'%',
'м'\t=>\t'$',
'р'\t=>\t'-',
'c'\t=>\t'!',
'о'\t=>\t'^',
'и'\t=>\t'#',
'ж' => '('
);

$text = "
=@+ &$%-, с^с@+ (#=";
$cipher = strtr($code, $text);

$decode = array_flip ($code);
$code = strtr ($str, $code);

echo "Оригинал: {$text}\nШифровка: {$cipher}\n";
[/code]
#285 #512816
Анон, что не так с кодом? ПОчему не дешифруется?

[code]<?php

error_reporting(-1);

/ Коды для замены букв /
$code = array(
'а'\t=>\t'@',
'ч'\t=>\t'+',
'в'\t=>\t'=',
'у'\t=>\t'&',
'д'\t=>\t'',
'е'\t=>\t'%',
'м'\t=>\t'$',
'р'\t=>\t'-',
'c'\t=>\t'!',
'о'\t=>\t'^',
'и'\t=>\t'#',
'ж' => '('
);

$text = "
=@+ &$%-, с^с@+ (#=";
$cipher = strtr($code, $text);

$decode = array_flip ($code);
$code = strtr ($str, $code);

echo "Оригинал: {$text}\nШифровка: {$cipher}\n";
[/code]
#286 #512817
>>512816
Блять.
#287 #512836
Красиво в моем файлообменнике получилось, что пользователь может скачать файл под его оригинальным названием.
На большинстве сайтов почему-то скачивается с непонятным именем, или хеш, или какая-то последовательность цифр.
Почему там так сделано? Может есть какой-то подвох? Например mod_rewrite не на всех серверах работает (на nginx я смотрел, есть ngx_http_rewrite_module), или еще что-то в этом роде? (Подозреваю, что те сайты на cms, и там это удобство тупо не предусмотрели, а не отказались из-за каких-то заумных соображений)
Можно ли и стоит ли писать "кросс-серверный код", чтобы можно было затем перенести с апача на nginx?

Такой еще вопрос: как сделать скачивание архивом нескольких файлов (или даже одного)?
Ссылки типа "скачать .zip", "скачать .rar", "скачать .tar.gz" и т.д.
Подскажите, куда копать в плане работы с архиваторами в php. (Вернее, подскажи, все равно тут кроме опа никто почти по делу не отвечает)
#288 #512846
>>512816
шифровальщик мамкин
Почитай что такое кодировка например cp1251 и utf-8.
Чем однобитовая кодировка отличаеться от двух битной.
Юзай Multibyte String functions

Хотя и проблема в твоем коде в другом если коротко то это пиздец, но для подобных задачь нужно знать что обозначают перечисленные мной выше вещи.
А вообще для шифрования / дешифрования в PHP все есть и городить свои велосипеды не имеет смысла
#289 #512855
>>512816
Аргументы strtr ты передаешь не в том порядке.
А в массиве пары "ключ-значение" в функции strtr определяют "что заменить" (ключ) "на что заменить" (значение).
http://php.net/manual/ru/function.strtr.php
#290 #512881
Объясните доступным языком, что такое трейты и где применяются.
На php.net нечитабельная галиматья
http://php.net/manual/ru/language.oop5.traits.php
#291 #512884
>>512881
Кажется, это набор свойств и методов, которые мы можем затем импортировать в свои классы? (Если да, то почему эти поехавшие так не написали, а зашифровали это простое определение в непонятное?)
#292 #512891
>>512881
Интерфейсы с готовой реализацией некоторых методов.
#293 #512892
>>512891
Респект, максимально кратко и ясно.
#294 #512895
Так короче я понял, как можно сделать, чтобы в админке юзер создавал новые поля ввода и они выводились на страницу. Теперь вопрос, как из input name принять перменные методом _POST если они мне не известны, как их динамических из таблицы выводить? Или тут нужно таблицу с внешними ключами делать??
#295 #512896
Привет PHP-аноны!Вообщем, хотел спросить может тут найдутся адекваты ,вот пол года назад, тут в /pr и в верстка треде, все говорили что новичку следует начать с хтмлцсс( пройти курсы в академи) теперь говорят учи с++ или жаву, некоторые начни с питона или пхп, это такой тролинг что-ли?Понятно что все советуют то-чему они сами обучены, но может кто-то даст более адекватный ответ с чего начать? Что я буду учить потом пхп питон или руби разберусь сам, а вот что нужно знать точно для зарабатывания бабла... я так понял обязательно яву и хтмлцсс?
#296 #512906
>>512896

>Понятно что все советуют то-чему они сами обучены


Да.

>более адекватный ответ с чего начать?


Зависит от того, в какой сфере ты собираешься работать.

В веб-разработке, то есть в ремесле создания сайтов, естественно ты должен знать html, css и js (на худой конец jquery). Кроме того, нужно знать язык запросов к базам данных, это sql.
Что касается серверных технологий, то самым популярным на постсоветском пространстве языком по статистике является php. Он не лучше, не хуже других языков, у каждого языка свои преимущества и недостатки.
Кроме php, пишут еще на руби (как по мне он сложнее) и на питоне (менее востребован, чем php, но если ты из Москвы или других крупных городов, то найти работу можно).
На c++ разумеется никто сайты не пишет.
Яву ты похоже путаешь с джаваскриптом. Это совершенно разные языки. Да, джаваскрипт знать нужно.

С чего начать, выбирай сам. Если ты хочешь заниматься веб-разработкой, то php/ruby/python. Геймдев c++. О других языках я не в курсе.

>что нужно знать точно для зарабатывания бабла...


Cms типа wordpress, drupal, bitrix, joomla, opencart и т.д.
Много зарабатывать, работая программистом ты сможешь только если любишь это дело. Потому что знания нужны колоссальные. Если работа не совпадает с твоим хобби, то вряд ли ты дорастешь до этого уровня.
#297 #512914
>>512906
Вот спасибо братишка
#298 #512922
Ну ответьте же на этот вопрос, как это сделать ;_;

4. К простой форме оформления заказа, которая есть на сайте, добавить расширенную (email, индекс, ФИО, адрес, предпочтительный способ доставки, предпочтительный способ связи с примечанием, что звонки в регионы платные, пожелания и т д), т е необходимые поля добавляет/редактирует/удаляет админ.
5. При заполнении товаров в админке сделать расширенную текстовую форму для возможности, например, писать в столбик, менять цвета, ставить ссылки и т д.
#299 #512924
ОП, хуевый у тебя мануал, который якобы для чайников, без обид. Даешь теорию, говоришь решать задачи, а пример решенных задач не даешь. Как я ее решать-то должен? Я не скрываю, что я имбецил, но я видел в интернетах более разжеванные гайды по изучению, правда они немного скучнее, чем твои.
#300 #512927
>>512914
Анус тебе брат, хуй ты тупоголовый.
#301 #512928
Ну нихуя себе я еще и цмску должен на коленке написать, чтобы поля добавлялись, удалялись и редактировались, а писали, что парочку простых функций! И все это всего за 5 дней.
#302 #512949
Гайз, подскажите в чём трабла, не записываются данные в SQL. Листинг тут: http://pastebin.com/EwiqaScb
7 Кб, 250x188
#303 #512950
>>512927
Ну что ты все про хуи да анусы... Сосешь небось? Лижешь?
#304 #512951
>>512949
Все ПХП-шники такие дауны? Тебе же написано, что в синтаксисе ошибка. Вангую, что это из-за доллара перед названием таблицы students.
Мимо-джава-господин
#305 #512952
>>512951
До этого доллара не было, дописал - думал поможет и забыл убрать. Я вижу, что ошибка в синтаксисе поэтому и спрашиваю, ибо делаю по мануалу.
#306 #512956
>>512952
Попробуй поставить & вместо $, может поможет.
#307 #512960
>>512956
Нет :(
#308 #512965
>>512960
Нет, я неправильно сказал, надо %
#309 #512974
>>512949
иди проспись
#310 #513002
#311 #513005
>>512924

Если решил то запости ссылку на ideone для проверки, если не можешь решить то запости ссылку на код и напиши на чем завис. Тут много людей которые уже решили эти задачи и они тебе наверняка подскажут.
#312 #513007
>>512949

Чему у тебя равно $students? Почему ты переменную прямо в запрос подставляешь? Там вообще-то имя таблицы должно быть.

> You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '(name, secname, sex, group, email, mark, year, city)



Это значит в запросе ошибка перед (name ...
2046 Кб, 360x287
#313 #513012
>>513007
Ты там заработался, или захворал опять? Пей чай с малиной и погоняй нубов, нубы сами без тебя далеко не уедут.

>>512836
У меня вопросы накапливаются слишком быстро. Бампну старые и дополню еще одним:
как на файлообменнике сделать проверку хеш-суммы (или как эта шняга называется)?
Чтобы пользователи не могли загрузить одно и то же изображение. (На файлообменнике это пожалуй ни к чему, а вот если делать имиджборду, то по-моему это прекрасное средство от рака. Даунам будет лень постоянно держать под рукой паки)
#314 #513014
>>513012

Смотри функции md5 и md5_file.
#315 #513015
>>513012

В таблице с инфой о файлах добавь поле, в которое будешь добавлять хеш загружаемых файлов, который можно получить с помощью функции md5_file. Ну и соответственно при загрузке файла проверяешь хеш загружаемого файла и ищешь файлы с таким хешем в базе.
#316 #513028
>>513015
О, не знал что хеш можно получить не только из строки, но и из файла. Думал хеш-сумма это какая-то неведомая штука, а оказывается обычный md5.
Ясно, спс. Тупой вопрос получился, но уж извините.

По архиваторам додумался зайти на php.net (прогресс), теперь надо только осилить прочитать. Так что снимаю вопрос.
http://php.net/manual/ru/refs.compression.php
#317 #513043
>>513028

С архиватором не все так просто. Создание архива требует времени. Если архив маленький, то можно создать его прямо в скрипте и отдать пользователю. Но если он большой, то нежелательно склеивать файлы в скрипте. Надо использовать очередь задач (вроде gearman), добавлять задачу, показывать пользователю страницу прогресса и периодиески проверять ее статус.

Также нужен крон-скрипт или что-то аналогичное для удаления старых архивов.
#318 #513046
>>513002

>то причина в том, что они очень старые и написаны в то время (лет 40 назад) когда utf-8 и многобайтных кодировок еще не было.


> (лет 40 назад)


> PHP


> 40 лет



Что за еба мануал блять...
Хочеш работать с мульти байтовыми кодировками, юзай mb_ функции
#319 #513051
>>513046
Для тупых школьников капсболдом, как вы любите:
STRTR ПОДДЕРЖИВАЕТ UTF-8, то есть "мульти байтовые" (значение знаешь?) кодировки.
Да, mb_ функции необходимо использовать для замены устаревших аналогов, не работающих с юникодом, например strlen.
Однако функция strtr с юникодом работает, она поддерживает юникод.
#320 #513066
>>513046

> PHP


> 40 лет


> азазаза


Php написан на С (си, есть такой язык, разработанный в начале 70-х), многое от него унаследовал, в частности функции типа strlen.
#321 #513070
>>513007
Подставлял прямо в запрос потому что такой пример есть на хабре (http://habrahabr.ru/post/137664/) - долистать до именных плейсхолдеров. students это название таблица (там по ошибке стоит $),а $student это объект класса Student, имеет 8 полей, всё как обычно.Если кто-то всё таки скажет в чём была трабла, будет круто - надо разобраться, но конкретной необходимости нет, я переделал запрос к базе через mysqli
67 Кб, 709x765
#322 #513081
Ананасы, помогите с задачкой про айфон школьника. Себе придумал такое решение, но наверняка оно неправильное...чот полдня посидел, ничего лучше не придумал:

<?php

error_reporting(-1);

$creditBalance = 40000; / Долг анона перед банком /
$percent = 1.03; / Банк начисляет 3% в месяц от суммы /
$servicePayment = 1000; / А также 1000 рублей в месяц комиссии за обслуживание счета /
$monthlyPayment = 5000; / Анон платит 5000 р в месяц, это все, что ему дает мама на завтраки /
$paymentTotal = 0; / Сколько всего отдал банку анон /

/ Посчитаем расходы 20 раз на 20 месяцев вперед /
for ($month = 1; $month <= 20; $month ++) {

\t$creditBalance = ( $creditBalance * $percent ) + $servicePayment - $monthlyPayment;
\t$paymentTotal = $paymentTotal + $monthlyPayment;
\techo "{$month} месяц спустя: долг = {$creditBalance} руб, выплачено всего {$paymentTotal} руб. \n";

if ($creditBalance < $monthlyPayment) {
$paymentTotal = $paymentTotal+$creditBalance;
echo "{$month} месяц спустя: долг = 0 руб, выплачено всего {$paymentTotal} руб. \n";
break;
}
};

1 месяц спустя: долг = 37200 руб, выплачено всего 5000 руб.
2 месяц спустя: долг = 34316 руб, выплачено всего 10000 руб.
3 месяц спустя: долг = 31345.48 руб, выплачено всего 15000 руб.
4 месяц спустя: долг = 28285.8444 руб, выплачено всего 20000 руб.
5 месяц спустя: долг = 25134.419732 руб, выплачено всего 25000 руб.
6 месяц спустя: долг = 21888.45232396 руб, выплачено всего 30000 руб.
7 месяц спустя: долг = 18545.105893679 руб, выплачено всего 35000 руб.
8 месяц спустя: долг = 15101.459070489 руб, выплачено всего 40000 руб.
9 месяц спустя: долг = 11554.502842604 руб, выплачено всего 45000 руб.
10 месяц спустя: долг = 7901.137927882 руб, выплачено всего 50000 руб.
11 месяц спустя: долг = 4138.1720657184 руб, выплачено всего 55000 руб.
12 месяц спустя: долг = 0 руб, выплачено всего 59138.172065718 руб.
С меня хватит!
67 Кб, 709x765
#322 #513081
Ананасы, помогите с задачкой про айфон школьника. Себе придумал такое решение, но наверняка оно неправильное...чот полдня посидел, ничего лучше не придумал:

<?php

error_reporting(-1);

$creditBalance = 40000; / Долг анона перед банком /
$percent = 1.03; / Банк начисляет 3% в месяц от суммы /
$servicePayment = 1000; / А также 1000 рублей в месяц комиссии за обслуживание счета /
$monthlyPayment = 5000; / Анон платит 5000 р в месяц, это все, что ему дает мама на завтраки /
$paymentTotal = 0; / Сколько всего отдал банку анон /

/ Посчитаем расходы 20 раз на 20 месяцев вперед /
for ($month = 1; $month <= 20; $month ++) {

\t$creditBalance = ( $creditBalance * $percent ) + $servicePayment - $monthlyPayment;
\t$paymentTotal = $paymentTotal + $monthlyPayment;
\techo "{$month} месяц спустя: долг = {$creditBalance} руб, выплачено всего {$paymentTotal} руб. \n";

if ($creditBalance < $monthlyPayment) {
$paymentTotal = $paymentTotal+$creditBalance;
echo "{$month} месяц спустя: долг = 0 руб, выплачено всего {$paymentTotal} руб. \n";
break;
}
};

1 месяц спустя: долг = 37200 руб, выплачено всего 5000 руб.
2 месяц спустя: долг = 34316 руб, выплачено всего 10000 руб.
3 месяц спустя: долг = 31345.48 руб, выплачено всего 15000 руб.
4 месяц спустя: долг = 28285.8444 руб, выплачено всего 20000 руб.
5 месяц спустя: долг = 25134.419732 руб, выплачено всего 25000 руб.
6 месяц спустя: долг = 21888.45232396 руб, выплачено всего 30000 руб.
7 месяц спустя: долг = 18545.105893679 руб, выплачено всего 35000 руб.
8 месяц спустя: долг = 15101.459070489 руб, выплачено всего 40000 руб.
9 месяц спустя: долг = 11554.502842604 руб, выплачено всего 45000 руб.
10 месяц спустя: долг = 7901.137927882 руб, выплачено всего 50000 руб.
11 месяц спустя: долг = 4138.1720657184 руб, выплачено всего 55000 руб.
12 месяц спустя: долг = 0 руб, выплачено всего 59138.172065718 руб.
С меня хватит!
#323 #513087
https://htmlacademy.ru
Нормальная обучалка? Я полный даун в програмировании, но неплохо знаю англ. и могу в логику. Прошел первый курс, вроде не сложно.
#324 #513089
#325 #513093
>>513070

Тебе надо разобраться в чем ошибка. Иначе какой смысл, получается ты ничего не понял и едиснтвенное что ты умеешь это копипастить код с хабра. Так не пойдет.

> Если кто-то всё таки скажет в чём была трабла,


Очевидно в том что ты подставил несуществующую переменную $students в запрос.

>>513087

надо пройти все курсы, как минимум все бесплатные, а не только введение.
#326 #513094
>>513093
Ну не все сразу же!
#327 #513099
>>513051

> STRTR ПОДДЕРЖИВАЕТ UTF-8



Пруф плиз, не ссылку на какойто еоба гитхаб где пхп уже 40 лет существует, а описание в документации что это так, и дальше будет так (а не просто багофича очередной версии)
#328 #513102
>>513070

> Php написан на С



А Си написал Ричи, которому 70, это значит что PHP 70? Ведь Без Ричи и PHPбы небыло
#329 #513105
ссыль не туда
>>513066
>>513102
#330 #513108
>>513099

Она подерживает utf-8 при использовании массива. Если ты указываешь пары для поиска /замены как строки то нет, так как она разбивает их на байты, а в utf-8 символ занимает несколько байт.

Это очевидно если подумать про алгоритм, по которому она работает. Она заменяет валидную последовательность utf-8 символов на другую валидную последовательность, не разрывая их на части.

>Пруф плиз, не ссылку на какойто еоба гитхаб где пхп уже 40 лет существует, а описание в документации что это так, и дальше будет так


Не знаю, есть ли это в документации. Мне лень искать пруф, и лень предлагать в нее дополнения если там этого не написано. Можешь заняться исправлением документации сам, если хочешь.
#331 #513109
>>513081

Првильный ответ 61270. Ты в послежний месяц выплачиваешь сразу 5000 + 4000 и из-за этого получаешь неправильный ответ.
#332 #513111
>>513099

если тебе нужны гарантии что поведение функции не изменится то лучший вариант это никогда не обновлять php.
#333 #513117
>>513108
Пипец ты долбоеб, утверждаеш бред который даже пруфнуть неможеш, специально для тебя болдом напишу
STRTR НЕ ПОДДЕРЖИВАЕТ UTF-8

> Она заменяет валидную последовательность utf-8 символов на другую валидную последовательность, не разрывая их на части.



Она заменяет последовательность байт другой последовательностью байт, а UTF-8 она не поддерживает, то что у тебя правильно заменяться символы в UTF-8 строке, это так, но не вовсех случаях т.к. про UTF-8 она ничего не знает
#334 #513119
>>513117
>>513108
болдом не получилось поэтому еще раз

STRTR НЕ ПОДДЕРЖИВАЕТ UTF-8
26 Кб, 343x256
#335 #513122
>>513111

> никогда не обновлять php

#336 #513128
>>513117

Раз ты такой умный то для тебя не составит труда продемонстрировать код который, давая функции strtr валидные utf-8 строки получает на выходе невалидную. Чтобы тем самым показать насколько глубоко я заблуждаюсь.
#337 #513132
http://ideone.com/34PDkN
Задачку про йоду, жду критики, оп.Спасибо за труды
6 Кб, 250x250
#338 #513139
>>513109
самое интересное, я помню находил позавчера решение этой задачки в одном из тредов, а теперь не могу решить.

Пиздец, где мои 17 лет и нормальные мозги...
#339 #513140
>>513139

Лучше всего стереть код и написать с нуля, так как в учебнике специально дан неправильный код.

Попробуй переписать код внутри цикла примерно так:

- прибавляем проценты и комиссию к остатку долга
- если остаток маленький, выплачиваем сколько осталось и уходим
- иначе платим 5000
#340 #513141
>>513128
Ты так ничего и не понял, я лиш пытался опровергнуть твое без основательное заявление про UTF-8, strtr НЕ поддерживает UTF-8, также как и все остальные не mb_ функции, то что из за специфики работы алгоритма strtr она работает с последовательность байт, и поэтому если на вход давать обычные utf-8 символы, то все корректно проходит, но если дать не просто символы а именно последовательность байт которая не совместима с двумя рядом стоящими utf-8 символами, то она их сломает и на выходе будут крякозябры, чегобы не было еслиб функция поддерживала UTF-8 и работала на уровне символов а не байт
#341 #513143
>>510035
ОПчик, чому кака выходит?
http://ideone.com/ITkBbO
#342 #513146
>>513141

Если ты передаешь на вход невалидные utf-8 последовательности, ты не можешь ожидать валидную последовательность на выходе.

>>513143

> $random4 = mt_rand(1, count($word4));


Индексы в массиве идут от нуля до N - 1
#343 #513157
>>513146

> Если ты передаешь на вход невалидные utf-8 последовательности



Пипец ты глупый, strtr на вход получает не utf-8 а последовательность байт (пускай преобразованную из utf-8 символов) и дальше алгоритм работает с байтами и про символы ничего не знает, поэтому если на входе были байты, а функция именно для байт сделана, и эти байты не являются utf-8 символами, но присудствуют по одиночке в utf-8 символах, то в результирующем наборе байт если там должна быть utf-8 строка она будет сломана.

> ты не можешь ожидать валидную последовательность на выходе



Да потому что функция сделана не для работы с символами а для работы с байтами, в одно байтовых кодировках это не имеет разницы а в двух байтовых, выходная строка сломаеться если дать на вход определенную последовательность байт, чего не былобы еслиб функция работала с символами (в установленной кодировке) а не с байтами.

Раз так тупо с понимание этого, то пример напишу чуть позже
#344 #513158
>>513146
А почему 1 и 2 строка одинаковые выходят, как переделать?
#345 #513159
лол, я натравил школьника на опа
с другой стороны вундеркинд растет, респект таким школьникам
я в его возрасте мамок вконтакте ебал, а он уже что-то знает, спорит с авторитетным челом
#346 #513162
>>513158
Ты выводишь одни и те же переменные несколько раз. С чего ты взял, что их содержимое должно поменяться?
#347 #513165
>>513162
Посмотри по той же ссылку, я правильно поправил или через костыли и есть способ проще намного?
#348 #513168
И всё таки анончики, из головы у меня не может выйти скрипт проверки уникальности текста. Вот написал такой код:

$text = "я баран известен всем уже очень давно и это мне только помогает";

$text = explode(" ", $text);

for($i=0; $i<count($text); $i++) {

if($i>1) {
$r[] = $text[$i-1]." ".$text[$i]." ".$text[$i+1];
}

}

for($j=0; $j<count($r); $j++)
{
$res[] = file_get_contents("https://www.google.com.ru/search?q=".$r[$j]);

/Далее лезим в DOM (не помню правдо как) и ищем совпадение с текущим $res[$j]
далее записываем результат, если совпадение есть помечаем строку красным
и также записываем адрес сайта с которым есть совпадение данной\tфразы
далее математически высчитываем процент уникальности. Уже дальше можно занести результат
в базу данных и сохранить на некоторое время по какому-то сгенерированому адресу
на определённое время.
/

}

Он не полный в конце в комментарии я указал что надо делать дальше, поясните ход мыслей правильный? Какие есть подводные камни? Я вижу как минимум один я не знаю как разобраться с тем что к этому скрипту может быть большое количество одновременных запросов, там какие-то заглушки есть кажется не можете подсказать? По поводу того что гугл не любит подобного это я знаю, суть сейчас не в этом. Ещё я читал что у гугла есть API и всё это можно сделать ещё легче, поясните пожалуйста в подробностях если не сложно по поводу всего этого.
#348 #513168
И всё таки анончики, из головы у меня не может выйти скрипт проверки уникальности текста. Вот написал такой код:

$text = "я баран известен всем уже очень давно и это мне только помогает";

$text = explode(" ", $text);

for($i=0; $i<count($text); $i++) {

if($i>1) {
$r[] = $text[$i-1]." ".$text[$i]." ".$text[$i+1];
}

}

for($j=0; $j<count($r); $j++)
{
$res[] = file_get_contents("https://www.google.com.ru/search?q=".$r[$j]);

/Далее лезим в DOM (не помню правдо как) и ищем совпадение с текущим $res[$j]
далее записываем результат, если совпадение есть помечаем строку красным
и также записываем адрес сайта с которым есть совпадение данной\tфразы
далее математически высчитываем процент уникальности. Уже дальше можно занести результат
в базу данных и сохранить на некоторое время по какому-то сгенерированому адресу
на определённое время.
/

}

Он не полный в конце в комментарии я указал что надо делать дальше, поясните ход мыслей правильный? Какие есть подводные камни? Я вижу как минимум один я не знаю как разобраться с тем что к этому скрипту может быть большое количество одновременных запросов, там какие-то заглушки есть кажется не можете подсказать? По поводу того что гугл не любит подобного это я знаю, суть сейчас не в этом. Ещё я читал что у гугла есть API и всё это можно сделать ещё легче, поясните пожалуйста в подробностях если не сложно по поводу всего этого.
#349 #513170
>>513165
Все правильно, count($array) - 1, так и должно быть.
Только смотри, у тебя после \n пробел прилепился. В результате в начале второй и третьей строки получается лишний пробел.
#350 #513173
>>513170
Спасибо
#351 #513182
Сакральный вопрос посоны, ПХП начал учить месяцев 6-7 назад, вроде бы ознакомился и кажется достиг того уровня когда можно пробоваться на вакансию пхп джуниора. Но есть один нюанс, мне 24 года, через 3 месяца будет 25 лет. По образованию я вообще не программист, сейчас работа есть (неофициальная), но хотелось бы попробовать устроиться программистом в ближайшие 2-3 месяца, не поздно ли это делать в 24-25 лет?
#352 #513187
>>513132
+
http://ideone.com/DL243G
Вот ещё сделал калькулятор, но не способом из методички, ты же не обижаешься, ОП?
#353 #513188
>>513182
Поздно. Выпей йаду.

Не, ну серьезно, сходи в несколько мест и узнай, не убьют же тебя.
На самом деле всем насрать на возраст (ты бы еще про внешность начал), главное чтобы ты справлялся со своей работой.
В худшем случае посадят чистить вордпресс, если туго соображаешь.

А насколько ты готов? В Москве и других крупных городах будут собеседования с тупыми вопросами по теории. Погугли вопросы, которые там задают.
В мухосранях никто даже разговаривать не будет, пока не принесешь пяток качественно выполненных работ в портфолио.
#354 #513192
>>513165
Так у тебя все еще одни и те же строки выводятся.
#355 #513193
>>513192
сраницу обнови
#356 #513215
ОП, помоги пожалуйста. В задании, где нужно вывести текст сверху вниз, заступорился на самом выводе букв. Подскажи, как это сделать. http://ideone.com/MysZ2D
#357 #513217
>>513188
Файлообменник, почти копия Ргхоста из задания ОПа будет нормально как для портфолио?
#358 #513225
хуяси, все мой вопрос про админку игнорируют, че не знаете, как практические задачи решать? ну идите считайте бананы в задачках ОПа хуле - это вам безусловно пригодится.
#359 #513226
>>513225

Я не решаю тестовые и домашние задания, и вообще я тут только задачи проверяю. Может впрочем кто-то другой захочет решить твое тестовое задание за тебя.

>>513217

Зависит от компании.

>>513215

Текст с помощью echo выводится только слева направо. Следовательно, надо сначала вывести все первые буквы из каждой строки, затем перейти на вторую строку и вывести вторые буквы из каждой строки, и тд.

>>513188

Про пять работ, точно глупость, какой смысл столько делать за бесплатно? Хватит и одной наверно, или если работ нет, можно предложить сделать тестовое задание.

>>513187

Если в начале идет минус то не работает: http://ideone.com/wkbAi4

При ошибке надо завершать скрипт, нет смысла продолжать выполнять далее.Также желательно писать какой именно символ неправильный.

Вместо предположения что знаки идут нечетными, лучше сделать переменную, которая показывает что было в предыдущий раз.

> break 2;


Таких вещей лучше бы избегать (так как они ломаются при добавлении/вынесении цикла), лучше сделать флаг-переменную наверно или поместить код внутрь функции и использовать return.
#359 #513226
>>513225

Я не решаю тестовые и домашние задания, и вообще я тут только задачи проверяю. Может впрочем кто-то другой захочет решить твое тестовое задание за тебя.

>>513217

Зависит от компании.

>>513215

Текст с помощью echo выводится только слева направо. Следовательно, надо сначала вывести все первые буквы из каждой строки, затем перейти на вторую строку и вывести вторые буквы из каждой строки, и тд.

>>513188

Про пять работ, точно глупость, какой смысл столько делать за бесплатно? Хватит и одной наверно, или если работ нет, можно предложить сделать тестовое задание.

>>513187

Если в начале идет минус то не работает: http://ideone.com/wkbAi4

При ошибке надо завершать скрипт, нет смысла продолжать выполнять далее.Также желательно писать какой именно символ неправильный.

Вместо предположения что знаки идут нечетными, лучше сделать переменную, которая показывает что было в предыдущий раз.

> break 2;


Таких вещей лучше бы избегать (так как они ломаются при добавлении/вынесении цикла), лучше сделать флаг-переменную наверно или поместить код внутрь функции и использовать return.
#360 #513227
>>513226
Вопрос снят. Проблемка была в серваке.
Но спасибо за ответ, тем не менее.
#361 #513228
>>513168

Тут много ошибок, например не кодируются параметры в URL, никак не обрабатываются сетевые ошибки, непонятно почему текст разбивается на куски по 3 слова, слова могут быть разделены не только проблелом, в общем весь скрипт одна большая ошибка. Из-за этих ошибок он будет выдавать неверные результаты. Ну и ты гарантирвоанно получишь временный бан в гугле (у моего провайдера например общий IP и достаточно одному дурачку запустить такой скрипт чтобы все остались без гугла).

Ну и как я сказал, поисковые системы не одобряют такое использование, ты их ресурсы нагружаешь, а прибыли не приносишь. Мы тоже не одобряем, так как это бессмысленная возня, и твой скрипт будет периодически переставать работать.
#362 #513229
>>513165

Еще есть функция array_rand, смотри мануал, с ней код был бы чуть короче.

>>513141

Ты придираешься к терминам. Если на вход давать валидные utf-8 строки то на выходе тоже получим вылидную строку. Это значит что она корректно обрабатывает строки в этой кодировке.

Так же как например str_repeat: она специально не заточена на работу с utf-8 но корректно с ней работает.

>>513132

> $sentences = array();


> $wordsInSentence = array();


Эта строка не нужна

> if ($key % 2 === 0) {


Это плохой подход, он делает понимание кода сложным (причем в коде комментария к этой строке нет, а вот там, где все и так очевидно, они есть) и опирается на предположение, что предложения и знаки между ними идут в определенном порядке. А что если идет несколько знаков препинания подряд? Лучше обойтись без этого. Например, использовать в регулярке

> $key > 0) ? $preKey = $key - 1: $preKey = 1;


Если ты хочешь написать if то и пиши if а не пытайся его замаскировать и запутать читателя.

?: используется в выражениях, а не как замена if

Само выражение абсолютно непонятное. Непонятно что за манипуляции с индексами, непонятно почему строка для сравнения выглядит как точка с запятой и пробел после нее. Это выглядит хрупким и сломается если чуть поменять код выше.

Так конечно писать не стоит, код должен быть проще и без мин замедленного действия.

В твоем случае можно завести переменную, хранящую предыдущую фразу (или предыдущий зна препинания). И проверять ее регуляркой или ка-кто еще.

> function makeFirstletterLowercase($text) {


А нужна ли эта функция? Не проще всю строку строчными буквами сделать?

> &$value)


Лучше не использовать ссылки так как у них много подводных камней. Также, надо давать нормальные названия переменным, $value бессмысленно и ничего не значит. Очевидно переменная должна называться $sentence.

> \t$regPunct = "/[,:]/u";


>$text = preg_replace($regPunct, '', $text); //у
тут можно не заводить отдельную переменную для регулярки, а вписать ее в функцию.

> $wordsInSentence = preg_split("/(\s)/u", $value, 0,


>PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE);



Незачем захватывать пробелы. Проще просто указать их в implode.
#362 #513229
>>513165

Еще есть функция array_rand, смотри мануал, с ней код был бы чуть короче.

>>513141

Ты придираешься к терминам. Если на вход давать валидные utf-8 строки то на выходе тоже получим вылидную строку. Это значит что она корректно обрабатывает строки в этой кодировке.

Так же как например str_repeat: она специально не заточена на работу с utf-8 но корректно с ней работает.

>>513132

> $sentences = array();


> $wordsInSentence = array();


Эта строка не нужна

> if ($key % 2 === 0) {


Это плохой подход, он делает понимание кода сложным (причем в коде комментария к этой строке нет, а вот там, где все и так очевидно, они есть) и опирается на предположение, что предложения и знаки между ними идут в определенном порядке. А что если идет несколько знаков препинания подряд? Лучше обойтись без этого. Например, использовать в регулярке

> $key > 0) ? $preKey = $key - 1: $preKey = 1;


Если ты хочешь написать if то и пиши if а не пытайся его замаскировать и запутать читателя.

?: используется в выражениях, а не как замена if

Само выражение абсолютно непонятное. Непонятно что за манипуляции с индексами, непонятно почему строка для сравнения выглядит как точка с запятой и пробел после нее. Это выглядит хрупким и сломается если чуть поменять код выше.

Так конечно писать не стоит, код должен быть проще и без мин замедленного действия.

В твоем случае можно завести переменную, хранящую предыдущую фразу (или предыдущий зна препинания). И проверять ее регуляркой или ка-кто еще.

> function makeFirstletterLowercase($text) {


А нужна ли эта функция? Не проще всю строку строчными буквами сделать?

> &$value)


Лучше не использовать ссылки так как у них много подводных камней. Также, надо давать нормальные названия переменным, $value бессмысленно и ничего не значит. Очевидно переменная должна называться $sentence.

> \t$regPunct = "/[,:]/u";


>$text = preg_replace($regPunct, '', $text); //у
тут можно не заводить отдельную переменную для регулярки, а вписать ее в функцию.

> $wordsInSentence = preg_split("/(\s)/u", $value, 0,


>PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE);



Незачем захватывать пробелы. Проще просто указать их в implode.
#363 #513231
>>513132

В случае со знаками препинания, можно их проверять той же регуляркой вместо условия с индексом.

>>512952

> До этого доллара не было, дописал - думал поможет и забыл убрать. Я вижу, что ошибка в синтаксисе поэтому и спрашиваю, ибо делаю по мануалу.


Это не праивльно, ты должен понимать что ты пишешь а не ставить наугад разные значки.

Доллар обозначает что в строку в это место вставится значение переменной. Чему она у тебя равна? И какая ошибка была без доллара?

И еще, проверь не совпадают ли имена колонок с зарезервированными словами mysql: http://www.mysql.ru/docs/man/Reserved_words.html

Если да то нужны косые кавычки.

>>512922

Лень разбираться. Почитай мануалы к используемой CMS, погугли. Это же твоя работа, ты за нее деньги получаешь, ты ее и делай. Я не знаю кстати даже о какой CMS речь идет.

>>512896

C++ и java очень сложные для новика и требуют много времени. Плюс на собеседованиях по ним могут задавать заковыристые вопросы.

>>512881

Позовляет сделать методы и поля, которые можно добавлять в классы. Мне кажется это скорее вредная штука так как я не могу вспомнить примеров где они бы были правильным решением. я видел несколько раз их использование, это были неправильные случаи так как там правильнее было сделать наследование.

Если у классов много общего, их наверно стоит наследовать и трейты не нужны. Если в классы надо добавить общий функционал, наверно лучше сделать его отдельным объектом и внедрять через конструктор.

Лучше уметь правильно пользоваться обычными возможностями ООП.

>>512891

Плохая аналогия, так как намекает что трейты неплохая вещь, хотя я не могу вспомнить адекватных примеров где они были бы нужны.

>>512846

Твой пост никак не помогает разобраться и потому не нужен тут.

> Чем однобитовая кодировка отличаеться от двух битной.


Ты же сам фигню пишешь, какая еще двухбитная кодировка? Это в которой всего 4 символа что ли?

>>512836

> а большинстве сайтов почему-то скачивается с непонятным именем, или хеш, или какая-то последовательность цифр.


Низкий уровень знания потому что, люди не хотят учиться в нашем треде а хотят учиться по мутным видеокурсам где про это не рассказывают. Конечно, имя должно быть нормальное чтобы пользователь потом не рылся среди кучи непонятных файлов.

> Можно ли и стоит ли писать "кросс-серверный код", чтобы можно было затем перенести с апача на nginx?


Можно но на практике не нужно так как известно под каким сервером будет работать проект, а если очень требуется, можно просто сделать опцию в конфиге или проверять через get_sapi_name().

> Подскажите, куда копать в плане работы с архиваторами в php.


Есть расширения, но их установка под windows може тсодержать подвохи в виде поиска нужных dll.

Также, на крайний случай, можно взять консольную версию архиватора 7zip и вызвыать ее, она поддерживает кучу форматов, но надо разбираться с тем как правильно запускать и контроллировать дочерний процесс, как получать информацию о успехе/неудаче операции, как экранировать передаваемые имена файлов, как логгировать сообщения об ошибках, где гарантия что не получится архив с пропщенными файлами.
#363 #513231
>>513132

В случае со знаками препинания, можно их проверять той же регуляркой вместо условия с индексом.

>>512952

> До этого доллара не было, дописал - думал поможет и забыл убрать. Я вижу, что ошибка в синтаксисе поэтому и спрашиваю, ибо делаю по мануалу.


Это не праивльно, ты должен понимать что ты пишешь а не ставить наугад разные значки.

Доллар обозначает что в строку в это место вставится значение переменной. Чему она у тебя равна? И какая ошибка была без доллара?

И еще, проверь не совпадают ли имена колонок с зарезервированными словами mysql: http://www.mysql.ru/docs/man/Reserved_words.html

Если да то нужны косые кавычки.

>>512922

Лень разбираться. Почитай мануалы к используемой CMS, погугли. Это же твоя работа, ты за нее деньги получаешь, ты ее и делай. Я не знаю кстати даже о какой CMS речь идет.

>>512896

C++ и java очень сложные для новика и требуют много времени. Плюс на собеседованиях по ним могут задавать заковыристые вопросы.

>>512881

Позовляет сделать методы и поля, которые можно добавлять в классы. Мне кажется это скорее вредная штука так как я не могу вспомнить примеров где они бы были правильным решением. я видел несколько раз их использование, это были неправильные случаи так как там правильнее было сделать наследование.

Если у классов много общего, их наверно стоит наследовать и трейты не нужны. Если в классы надо добавить общий функционал, наверно лучше сделать его отдельным объектом и внедрять через конструктор.

Лучше уметь правильно пользоваться обычными возможностями ООП.

>>512891

Плохая аналогия, так как намекает что трейты неплохая вещь, хотя я не могу вспомнить адекватных примеров где они были бы нужны.

>>512846

Твой пост никак не помогает разобраться и потому не нужен тут.

> Чем однобитовая кодировка отличаеться от двух битной.


Ты же сам фигню пишешь, какая еще двухбитная кодировка? Это в которой всего 4 символа что ли?

>>512836

> а большинстве сайтов почему-то скачивается с непонятным именем, или хеш, или какая-то последовательность цифр.


Низкий уровень знания потому что, люди не хотят учиться в нашем треде а хотят учиться по мутным видеокурсам где про это не рассказывают. Конечно, имя должно быть нормальное чтобы пользователь потом не рылся среди кучи непонятных файлов.

> Можно ли и стоит ли писать "кросс-серверный код", чтобы можно было затем перенести с апача на nginx?


Можно но на практике не нужно так как известно под каким сервером будет работать проект, а если очень требуется, можно просто сделать опцию в конфиге или проверять через get_sapi_name().

> Подскажите, куда копать в плане работы с архиваторами в php.


Есть расширения, но их установка под windows може тсодержать подвохи в виде поиска нужных dll.

Также, на крайний случай, можно взять консольную версию архиватора 7zip и вызвыать ее, она поддерживает кучу форматов, но надо разбираться с тем как правильно запускать и контроллировать дочерний процесс, как получать информацию о успехе/неудаче операции, как экранировать передаваемые имена файлов, как логгировать сообщения об ошибках, где гарантия что не получится архив с пропщенными файлами.
22 Кб, 793x459
#364 #513232
Срань господня, прислали сайт доделать, ТЗ легкое, но я сейчас смотрю на файлы и даже не понимаю, что это вообще, хтмл тэгов нихуя нет, все как-то динамически создано на пхп и достается из БД. Текст на главной сделан так:
<script type="text/javascript">
Cufon.replace("div.font");
Cufon.replace("div.font1");
Cufon.replace("div.brev");
Cufon.replace(".catalog_text");
Cufon.replace(".catalog_text_2");
Cufon.replace(".prnext");
Cufon.replace(".prcatalog_text");
Cufon.replace(".m_fonts");
</script>

Что это блять? ЦМСка какая-то?
#365 #513233
>>513226
Если ты не знаешь, как динамически из админки создавать инпуты, то что ты вообще в вебе делаешь? чисто задачки из ОП-поста решаешь?
#366 #513235
>>512815

Почему? Там же есть API и хуки для плагинов.

>>512758

Мануал по CMS читал для начала?

>>512740

Хороший программист и с ними справится.

>>512562

> Если увидишь ошибку "cookie already sent",


Новые версии PHP пишут строку в которой начался вывод, так что искать долго не придется (если конечно это не невидимый BOM который путает новичков).

>>512539

Это полезный дискомфорт, старайся всегда разбираться если что-то непонятно или нелогично.

>>512254

> Я должен замапить класс МедиаИнфо как колонку таблицы files?


Ну тип в доктрине определяет как данные преобразуются при записи или загрузке из БД. Соответственно твой класс, реализующий этот тип, должен преобразовывать данные между объектом класса MediaInfo и строкой в формате JSON. То есть пара строчек на каждый случай.

После этого помечаешь поле в объекте File этим типом и доктрина сама начинает сохранять/загружать MediaInfo из него в базу.

> Но у меня оно почему-то нормально работает с кирилицей.


Потому что ты не тестировал во всех бразерах, а те что у тебя интерпретируют заголовки как utf-8 хотя не обязаны.

> то можешь подсказать что почитать чтоб сделать правильно?


Древний и 100% способ это сделать чтоыб ссылка на скаичванеи заканчивалась именем файла. В новых браузерах ты также можешь закодировать имя в специальном формате: https://tools.ietf.org/html/rfc5987#section-3.2.2

Мне кажется старый способ работающий везде, пока что лучше. То есть делай ссылку вида

/download/123/название%20файла.jpg

Не забудь кодировать имя файла процентным кодированием (urlencode) при подстановке в ссылку.

> Что-то мне эта слимовская функция не помогла, она возвращает совсем не то что мне нужно


Покажи пример кода.
#366 #513235
>>512815

Почему? Там же есть API и хуки для плагинов.

>>512758

Мануал по CMS читал для начала?

>>512740

Хороший программист и с ними справится.

>>512562

> Если увидишь ошибку "cookie already sent",


Новые версии PHP пишут строку в которой начался вывод, так что искать долго не придется (если конечно это не невидимый BOM который путает новичков).

>>512539

Это полезный дискомфорт, старайся всегда разбираться если что-то непонятно или нелогично.

>>512254

> Я должен замапить класс МедиаИнфо как колонку таблицы files?


Ну тип в доктрине определяет как данные преобразуются при записи или загрузке из БД. Соответственно твой класс, реализующий этот тип, должен преобразовывать данные между объектом класса MediaInfo и строкой в формате JSON. То есть пара строчек на каждый случай.

После этого помечаешь поле в объекте File этим типом и доктрина сама начинает сохранять/загружать MediaInfo из него в базу.

> Но у меня оно почему-то нормально работает с кирилицей.


Потому что ты не тестировал во всех бразерах, а те что у тебя интерпретируют заголовки как utf-8 хотя не обязаны.

> то можешь подсказать что почитать чтоб сделать правильно?


Древний и 100% способ это сделать чтоыб ссылка на скаичванеи заканчивалась именем файла. В новых браузерах ты также можешь закодировать имя в специальном формате: https://tools.ietf.org/html/rfc5987#section-3.2.2

Мне кажется старый способ работающий везде, пока что лучше. То есть делай ссылку вида

/download/123/название%20файла.jpg

Не забудь кодировать имя файла процентным кодированием (urlencode) при подстановке в ссылку.

> Что-то мне эта слимовская функция не помогла, она возвращает совсем не то что мне нужно


Покажи пример кода.
#367 #513237
Напомню не забыть проверить https://github.com/V3N0m21/Uppu3

>>512226

Действительно, какой-то клуб 40-летних неудачников получается. Хочу всем напомнить что наш тред посвящен программированию, а нытьем лучше заниматься в других разделах. Сопли тут вам вытирать никто не будет.

>>512226

Насчет SQL, ты смотрел ссылки отсюда: https://gist.github.com/codedokode/10539213

?

Там хороший туториал для начинающих есть.

>>512054

> if (!isset($this->$class)) {


Вот это неправильно. Завязывай с динамиечскими свойствами, объект это не массив чтобы в него их добавлять (а если тебе нужны динамические свойства, используй лучше массив).

Вместо swtch лучше сделать функции вида

public function getValidator()
{
if (!$this->validator) {
$this->validator = new ... ;
}

return $this->validator;
}

Тогда и код будет логичнее и будет сразу видно какие есть методы у класса, и в IDE автодополнение будет работать.

Ты вместо простого и очевидного решения (сделать метод для каждого класа) зачем-то решил усложнить код, сделав процесс создания объекта более сложным и непрямолинейным.

В фреймфорках есть готовые решения для этого, так что думаю в будущем тебе не придется такие контейнеры писать.

> default:


> $this->$class = new $class;


Это неправитльно. Ты готов создавать что угодно никак не проверяя вообще что это за класс.

Ну и как ты наверно успел заметить, контейнеры отравляют код, заставляя передавать его в каждый конструктор. Потому мы используем их только в контроллерах, которые все равно повторно исплоьзовать нельзя.

В фреймворках контейнеры реализуются по-разному. В симфони контейнер настраивается файлом конфигурации, ты в нем описываешь сервисы, какой класс используется, что ему надо передать в конструктор: http://symfony-gu.ru/documentation/ru/html/book/service_container.html

В микрофреймворке Слим ты можешь заполнять контейнер с помощью анонимных функций: http://docs.slimframework.com/di/overview/

В Юи сервисы получаются через объект фреймворка, доступный глобыльно:

$someModel = Yii::app()->model('some');

Ну Юи известен своими велосипедами, что с него взять.
#367 #513237
Напомню не забыть проверить https://github.com/V3N0m21/Uppu3

>>512226

Действительно, какой-то клуб 40-летних неудачников получается. Хочу всем напомнить что наш тред посвящен программированию, а нытьем лучше заниматься в других разделах. Сопли тут вам вытирать никто не будет.

>>512226

Насчет SQL, ты смотрел ссылки отсюда: https://gist.github.com/codedokode/10539213

?

Там хороший туториал для начинающих есть.

>>512054

> if (!isset($this->$class)) {


Вот это неправильно. Завязывай с динамиечскими свойствами, объект это не массив чтобы в него их добавлять (а если тебе нужны динамические свойства, используй лучше массив).

Вместо swtch лучше сделать функции вида

public function getValidator()
{
if (!$this->validator) {
$this->validator = new ... ;
}

return $this->validator;
}

Тогда и код будет логичнее и будет сразу видно какие есть методы у класса, и в IDE автодополнение будет работать.

Ты вместо простого и очевидного решения (сделать метод для каждого класа) зачем-то решил усложнить код, сделав процесс создания объекта более сложным и непрямолинейным.

В фреймфорках есть готовые решения для этого, так что думаю в будущем тебе не придется такие контейнеры писать.

> default:


> $this->$class = new $class;


Это неправитльно. Ты готов создавать что угодно никак не проверяя вообще что это за класс.

Ну и как ты наверно успел заметить, контейнеры отравляют код, заставляя передавать его в каждый конструктор. Потому мы используем их только в контроллерах, которые все равно повторно исплоьзовать нельзя.

В фреймворках контейнеры реализуются по-разному. В симфони контейнер настраивается файлом конфигурации, ты в нем описываешь сервисы, какой класс используется, что ему надо передать в конструктор: http://symfony-gu.ru/documentation/ru/html/book/service_container.html

В микрофреймворке Слим ты можешь заполнять контейнер с помощью анонимных функций: http://docs.slimframework.com/di/overview/

В Юи сервисы получаются через объект фреймворка, доступный глобыльно:

$someModel = Yii::app()->model('some');

Ну Юи известен своими велосипедами, что с него взять.
#368 #513238
лучше бы я выбрал построить проект с нуля, чем ковыряться в чужом говнокоде...
#369 #513241
>>511697

Пользователь полностью контроллирует что происходит на стороне браузера, как ты собрался от него защищаться? Ты можешь только выиграть немного времени, обфусцировав код и добавив какие-нибуь подписи и проверки, но принципиально защититься нельзя.

>>511627

Если эти ссылки не надо менять в админке то проще всего просто прописать их в нужный шаблон HTML-кодом без PHP. Чтобы вывести записи с определенным тегом достаточно кликнуть по нему и посмотреть как выглядит ссылка.

>>511629

Нет ты

>>511597

Зарплаты не рухнут так как их подпитывает западный рынок, а на нем пока даже зарплата уборщика в макдональдсе выше чем у нас. Если конечно ты не знаешь английский. то твоя зарплата вполне может и рухнуть (точнее, рухнет валюта в которой ее платят) в случае ухудшения международных отношений.

>>511544

Я думаю, для обезьяны превратиться в образованного человека займет меньше времени чем напечатать текст.

>>511521

Работа с флеш сообщениями должна быть в отдельных функциях/методах. Никаких таких проверок быть не должно:

> f (array_key_exists('flashMessage', $_COOKIE)) {


Потмоу что ими ты размаывешь логику работы с сообщениями (как они хранятся, под каким ключом, где) по всему коду вместо того чтобы изолировать в классе или функции. Это неправильно.

Также, я не понимаю почему работа с флеш сообщенями помещена в AbiturientService. Их можно использовать для любых объектов, не только абиутриетов, и значит в этом сервисе их не должно быть.

>>511503

Зря, по моему неплохой учебник.

>>511456

абсолютно необходимиы.

>>511452

Не все же должны уметь в программирование. Ты может быть петь или бегать марафоны не умеешь и как-то же живешь с этим.

А понять можно при желании, если изучать все последовательно и задавать вопросы. А не смотреть мутные статьи и видеокурсы.

>>511392

> Если же вы описываете сущность, единственное предназначение которой - сгруппировать данные, то это не объект, это структура, и тут (чаще всего) геттеры и сеттеры не нужны


это не очень дальновидный подход так как завтра тебе понадобится например при записи проверять что знаечние поля находится в диапазоне от 1 до 100. Или при смене одного поля менять и другое. В случае сеттера ты добавишь эту проверку туда. В случае публичного поля тебя ждет проход по всему коду и замена поля на геттер/сеттер. Потому некоторые рекомендуют вообще не использовать публичные поля.

В очень простых случаях, когда ты знаешь что такого не будет, это допустимо. То есть мы уменьшает время написания кода ценой потенциальнх исправлений в будущем (хотя проще наверно макрос в редакторе сдеать для геттеров/сеттеров, вот мой для саблайма: https://gist.github.com/codedokode/cd2f41c8dcf1237fde4b )

Рассуждения про стурктуры дурь, так как в большом приложении рано или поздно необходимость что-то проверять или делать при изменении поля появится, по моему опыту.

Люди которые любят рассуждать что ООП не нужен, как правило в нем не особо хорошо разбираются.
#369 #513241
>>511697

Пользователь полностью контроллирует что происходит на стороне браузера, как ты собрался от него защищаться? Ты можешь только выиграть немного времени, обфусцировав код и добавив какие-нибуь подписи и проверки, но принципиально защититься нельзя.

>>511627

Если эти ссылки не надо менять в админке то проще всего просто прописать их в нужный шаблон HTML-кодом без PHP. Чтобы вывести записи с определенным тегом достаточно кликнуть по нему и посмотреть как выглядит ссылка.

>>511629

Нет ты

>>511597

Зарплаты не рухнут так как их подпитывает западный рынок, а на нем пока даже зарплата уборщика в макдональдсе выше чем у нас. Если конечно ты не знаешь английский. то твоя зарплата вполне может и рухнуть (точнее, рухнет валюта в которой ее платят) в случае ухудшения международных отношений.

>>511544

Я думаю, для обезьяны превратиться в образованного человека займет меньше времени чем напечатать текст.

>>511521

Работа с флеш сообщениями должна быть в отдельных функциях/методах. Никаких таких проверок быть не должно:

> f (array_key_exists('flashMessage', $_COOKIE)) {


Потмоу что ими ты размаывешь логику работы с сообщениями (как они хранятся, под каким ключом, где) по всему коду вместо того чтобы изолировать в классе или функции. Это неправильно.

Также, я не понимаю почему работа с флеш сообщенями помещена в AbiturientService. Их можно использовать для любых объектов, не только абиутриетов, и значит в этом сервисе их не должно быть.

>>511503

Зря, по моему неплохой учебник.

>>511456

абсолютно необходимиы.

>>511452

Не все же должны уметь в программирование. Ты может быть петь или бегать марафоны не умеешь и как-то же живешь с этим.

А понять можно при желании, если изучать все последовательно и задавать вопросы. А не смотреть мутные статьи и видеокурсы.

>>511392

> Если же вы описываете сущность, единственное предназначение которой - сгруппировать данные, то это не объект, это структура, и тут (чаще всего) геттеры и сеттеры не нужны


это не очень дальновидный подход так как завтра тебе понадобится например при записи проверять что знаечние поля находится в диапазоне от 1 до 100. Или при смене одного поля менять и другое. В случае сеттера ты добавишь эту проверку туда. В случае публичного поля тебя ждет проход по всему коду и замена поля на геттер/сеттер. Потому некоторые рекомендуют вообще не использовать публичные поля.

В очень простых случаях, когда ты знаешь что такого не будет, это допустимо. То есть мы уменьшает время написания кода ценой потенциальнх исправлений в будущем (хотя проще наверно макрос в редакторе сдеать для геттеров/сеттеров, вот мой для саблайма: https://gist.github.com/codedokode/cd2f41c8dcf1237fde4b )

Рассуждения про стурктуры дурь, так как в большом приложении рано или поздно необходимость что-то проверять или делать при изменении поля появится, по моему опыту.

Люди которые любят рассуждать что ООП не нужен, как правило в нем не особо хорошо разбираются.
#370 #513242
>>513237
Спасибо, попробую пересмотреть свою реализацию контейнера.

>В фреймфорках есть готовые решения для этого, так что думаю в будущем тебе не придется такие контейнеры писать.


Ну хотелось бы, чтоб фреймворки являлись для меня этими самыми "чОрными ящиками" как можно в более меньшей степени. И не быть потом сильно от них зависимым.
#371 #513243
>>511391

Наш урок про реуглярки прошел?

Есть сайт regex101, на нем можно тестировать регулярки.

Есть маунал PHP, подробный но малопонятный: http://php.net/manual/ru/pcre.pattern.php

Можно задать вопрос в треде.

>>511382

если бы в твоем посте было поменьше слов «быдло», он мог бы выглядеть адекватным. Ну и требования все же устанавливает работодатель, сделаешь свою компанию и будешь сам с соискателями общаться как хочешь.

>>511381

Удалять надо через пуск - настройка - установку/удаление программ. У тебя мог остаться запущенный сервис например.

Зайди в пуск -> services.msc и посмотри нет ли там лишних сервисов mysql. Ну и в установке/удалении программ посмотри.

И поясни что значит «mysql не работает». Это как?

>>511352

Судя по тексту твоего поста ты недалеко ушел от тех кого критикуешь. Читать невозможно.

Вместо того чтобы баттхертить ты бы мог просто устроиться в нормальную компанию и/или развиваться в то время пока ковырятели вордпрессов передвигают очередное меню на 5 пикселей выше.

>>511273

Я видел такое требование и в других программах под линуксом. как я понимаю это для единообразия, чтобы в конце каждой строки стоял \n:

Строка1\n
Строка2\n

PHP будет работать нормально независимо от этого, да и большинство других программ тоже, по моему эта проблема из прошлого. Хотя гит и сегодня предупреждает про отстутсвующую пустую строку в конце файла.
#371 #513243
>>511391

Наш урок про реуглярки прошел?

Есть сайт regex101, на нем можно тестировать регулярки.

Есть маунал PHP, подробный но малопонятный: http://php.net/manual/ru/pcre.pattern.php

Можно задать вопрос в треде.

>>511382

если бы в твоем посте было поменьше слов «быдло», он мог бы выглядеть адекватным. Ну и требования все же устанавливает работодатель, сделаешь свою компанию и будешь сам с соискателями общаться как хочешь.

>>511381

Удалять надо через пуск - настройка - установку/удаление программ. У тебя мог остаться запущенный сервис например.

Зайди в пуск -> services.msc и посмотри нет ли там лишних сервисов mysql. Ну и в установке/удалении программ посмотри.

И поясни что значит «mysql не работает». Это как?

>>511352

Судя по тексту твоего поста ты недалеко ушел от тех кого критикуешь. Читать невозможно.

Вместо того чтобы баттхертить ты бы мог просто устроиться в нормальную компанию и/или развиваться в то время пока ковырятели вордпрессов передвигают очередное меню на 5 пикселей выше.

>>511273

Я видел такое требование и в других программах под линуксом. как я понимаю это для единообразия, чтобы в конце каждой строки стоял \n:

Строка1\n
Строка2\n

PHP будет работать нормально независимо от этого, да и большинство других программ тоже, по моему эта проблема из прошлого. Хотя гит и сегодня предупреждает про отстутсвующую пустую строку в конце файла.
#372 #513244
>>511273

Алсо если бы ты погуглил по словам why end file with empty line ты бы нашел:

http://stackoverflow.com/questions/2287967/why-is-it-recommended-to-have-empty-line-in-the-end-of-file
(тут здравая мысль что в консоли файл лучше выводтся в этом случае и отсылка к POSIX) http://stackoverflow.com/questions/729692/why-should-files-end-with-a-newline
http://unix.stackexchange.com/questions/18743/whats-the-point-in-adding-a-new-line-to-the-end-of-a-file
http://www.reddit.com/r/Python/comments/1zjugg/question_why_does_pep8_recommend_leaving_a_blank/

В общем остылка к тому что в linux принято ставить симвл \n в конце каждой строки включая последнюю.
#373 #513245
>>513232
Это движок для шрифтов на Javascriptе.
https://github.com/sorccu/cufon/wiki/About
#374 #513247
>>513238
Можно подумать, ты лучше напишешь.
#375 #513248
>>511116

Не забыть проверить этого анона https://github.com/soulsteel/studentProject

В проекте нет SQL файла где описана структура таблицы.

> if($locality === "local") {


Значения locality и пола надо сделать константами в классе студента:

const LOCALITY_LOCAL = 'local';

Константы принято использовать когда есть несколько вариантов значения. Не использовать их считается плохой практикой так как легче ошиьиться и неочевидно какие значения есть вообще.

Впрочем если ты хоанишь локальность в виде 0\1 то лучше не делать константы а использовать true/false. А для пола — сделать.

validate должна очищать список ошибок в начале работы.

> use PDO;


Это наверно не требуется, можно писать просто \PDO. Но можно и как у тебя.

> $data = [


> "firstName" => $student->getFirstName(),


Надо писать имя плейсхолдера вместе с двоеточием в массиве.

Что еще за поле password? Скопировал не задумываясь?

> public function getStudents($mask, $num, $offset, $direction)


Все вставялемые в запрос значения надо проверят по белому списку для защиты от SQL инхекций.

> " LIMIT " . $offset . ", " . $num;


Тут нужны плейсхолдеры

> LIKE " . "\"%" . $phrase . "%\"";


И тут. Пока у тебя тут SQL инъекция с помощью которой можно легко взломать сайт.

> $recordsNum = $statement->fetch(PDO::FETCH_ASSOC)["recordsNum"];


Исплоьзуй fetchColumn

> $options = array(


> PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',


> PDO::MYSQL_ATTR_INIT_COMMAND => 'SET sql_mode=\'STRICT_ALL_TABLES\'',


Это лучше вынести из конфига так как это не надо менять, также второй ключ в массиве затрет первый.

> https://github.com/soulsteel/studentProject/blob/master/app/helpers.php#L21


Тут надо сделать грамотно защиту от XSS в переменной $text. ЧТО если тамкакие-то HTML теги?

Твое нынешнее решение конечно предотвращает XSS:

> html(highlightMatch($student->getFirstName(), $phrase))


но оно же превращает тег <mark> в текст. ты тестировал подсветку?

> require_once "/config.php";


Сомневаюсь что это работает так как это абсолютный путь указывающий в корень диска или ФС.

> <?php if (isset($errors["firstName"])): ?>


> <input type="text" class="form-control" id="inputError2"


> <?php else: ?>


> input type="text" id="inputFirstName"


надо избежать дублирования кода инпута. Попробуй переделать этот if, например засунув в него только отдельные атрибуты и теги.

Аналогично с радиокнопками.

> https://github.com/soulsteel/studentProject/blob/master/templates/navbar.php#L6


Почему по английски?

Почему есть header.php но нет footer.php?

Папку vendor надо добавить в гитигнор и убрать из репозитория.

Ну и я немного побуду граммар наци:

> which contains two pages: main and register


frontpage and registration page

> List of students, currently registered is shown


list of currently registered students is shown (порядок слов)

> In this project a part of web app created, which contains two pages:


The project is a (part of a) web app that consists of two pages

> in the form of table


as a table
#375 #513248
>>511116

Не забыть проверить этого анона https://github.com/soulsteel/studentProject

В проекте нет SQL файла где описана структура таблицы.

> if($locality === "local") {


Значения locality и пола надо сделать константами в классе студента:

const LOCALITY_LOCAL = 'local';

Константы принято использовать когда есть несколько вариантов значения. Не использовать их считается плохой практикой так как легче ошиьиться и неочевидно какие значения есть вообще.

Впрочем если ты хоанишь локальность в виде 0\1 то лучше не делать константы а использовать true/false. А для пола — сделать.

validate должна очищать список ошибок в начале работы.

> use PDO;


Это наверно не требуется, можно писать просто \PDO. Но можно и как у тебя.

> $data = [


> "firstName" => $student->getFirstName(),


Надо писать имя плейсхолдера вместе с двоеточием в массиве.

Что еще за поле password? Скопировал не задумываясь?

> public function getStudents($mask, $num, $offset, $direction)


Все вставялемые в запрос значения надо проверят по белому списку для защиты от SQL инхекций.

> " LIMIT " . $offset . ", " . $num;


Тут нужны плейсхолдеры

> LIKE " . "\"%" . $phrase . "%\"";


И тут. Пока у тебя тут SQL инъекция с помощью которой можно легко взломать сайт.

> $recordsNum = $statement->fetch(PDO::FETCH_ASSOC)["recordsNum"];


Исплоьзуй fetchColumn

> $options = array(


> PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',


> PDO::MYSQL_ATTR_INIT_COMMAND => 'SET sql_mode=\'STRICT_ALL_TABLES\'',


Это лучше вынести из конфига так как это не надо менять, также второй ключ в массиве затрет первый.

> https://github.com/soulsteel/studentProject/blob/master/app/helpers.php#L21


Тут надо сделать грамотно защиту от XSS в переменной $text. ЧТО если тамкакие-то HTML теги?

Твое нынешнее решение конечно предотвращает XSS:

> html(highlightMatch($student->getFirstName(), $phrase))


но оно же превращает тег <mark> в текст. ты тестировал подсветку?

> require_once "/config.php";


Сомневаюсь что это работает так как это абсолютный путь указывающий в корень диска или ФС.

> <?php if (isset($errors["firstName"])): ?>


> <input type="text" class="form-control" id="inputError2"


> <?php else: ?>


> input type="text" id="inputFirstName"


надо избежать дублирования кода инпута. Попробуй переделать этот if, например засунув в него только отдельные атрибуты и теги.

Аналогично с радиокнопками.

> https://github.com/soulsteel/studentProject/blob/master/templates/navbar.php#L6


Почему по английски?

Почему есть header.php но нет footer.php?

Папку vendor надо добавить в гитигнор и убрать из репозитория.

Ну и я немного побуду граммар наци:

> which contains two pages: main and register


frontpage and registration page

> List of students, currently registered is shown


list of currently registered students is shown (порядок слов)

> In this project a part of web app created, which contains two pages:


The project is a (part of a) web app that consists of two pages

> in the form of table


as a table
#376 #513249
Знаете, господа, вот я сколько в вебе ковыряюсь, у меня назрела идея написать толстый общий подробный мануал, который все расписывает по пунктикам, потому что вот это вот ковырять в гугле - там урвал кусок, там кусок, потом при решении практической задачи, когда ты думал, что уже все знаешь, ты внезапно открываешь для себя грани непознанного и понимаешь дна нет, что тебе еще пару месяц надо это ковырять.
#377 #513250
>>513247
Можно подумать, я хотя бы буду знать, что писать. Вообще да, лучше бы я начал задрачивать ЦМСки и писать их и учить готовые, потому что сайты НЕ ДЛЯ СЕБЯ со всякими шаблонами и редакторами я еще не делал.
#378 #513251
>>513249

Обширная работенка то.
#379 #513252
>>513250
Я к тому, что когда начнешь что-то масштабное писать, в итоге у тебя через некоторое время такая же мешанина непонятная выйдет, в которой другому разбираться полгода. ЦМСки для того и созданы, чтобы хоть как-то облегчить задачу вникания в чужой код. Ну и расширять их легче, чем самописный велосипед с костылями.
#380 #513253
>>511088

> Я уже писал, но там тупо гоняются json-строки, это не дело, надо через сокеты.


Веб-сокеты и просто сокеты разные вещи, я имел в виду именно обычные сокеты, то есть TCp-соединения и UDP-пакеты. Вебсокеты поверх них построены и их имеет смысл наверно чут позже изучить (хотя можно и наоборот, они не сложные вроде).

> verbose наверное, опции b я не нашел.


В виндоуз она показывает программу занявшую порт. В линукс это опция

> -p, --program


> Show the PID and name of the program to which each socket belongs.



> Давай я пока побалуюсь немного с курлом


Тогда можешь сделать задачу про определение адреса через яндекс-API. Если не хочешь заморочиться с XMl, то геокодер позволяет отдавать ответ в формате JSON который одной функцией превращается в массив:

https://tech.yandex.ru/maps/doc/geocoder/desc/concepts/response_structure-docpage/

Реши тогда задачу про определение адреса.

Не забудь сделать проверки на сетевые ошибки. и указать разумный таймаут для запроса.

Не пиши все одной простыней, разбивай на действия в функциях или методах.

зазубривать справочники не надо, но прочесть (не запоминая) эту страницу с опциями придется: http://php.net/manual/ru/function.curl-setopt.php

> Как скачать сайт курлом, не wgetом?


О, кстати, хорошая задача, можешь ее тоже сделать. Тебе понадобится очередь или массив для хранения старниц которые надо скачать в будущем.

> Как загрузить/скачать файлы по ftp на хостинг (если они это позволяют, конечно)?


Смотри опции курла, он поддерживает FTP, как минимум скачивание. насчет закачки я не помню, если нет то надо либо найти библиоеку для FTP либо написать свою функцию, изучив протокол FTP, он простой и текстовый. думаю, это полезно, заодно научишься с TCP сокетами работать.

> а тупо зазубривать команды, не понимая их смысла не охота.


Так у курла всего несколько функций надо знать, там правда опций много но наизусть их знать не надо.

Ну и я не советую использовать курл напрямую, я советую в приложениях исопльзовать библиотеку HTTP клиента с удобным синтаксисом, напрмер Guzzle или Buzz, так как код на сыром курле смотрится плохо и плохо читается, часто также он содержит ошибки или отстутствие проверок результата. Меня он раздражает.

Конечно это не относится к учебному коду. для изучения курл можно использовать напрямую.
#380 #513253
>>511088

> Я уже писал, но там тупо гоняются json-строки, это не дело, надо через сокеты.


Веб-сокеты и просто сокеты разные вещи, я имел в виду именно обычные сокеты, то есть TCp-соединения и UDP-пакеты. Вебсокеты поверх них построены и их имеет смысл наверно чут позже изучить (хотя можно и наоборот, они не сложные вроде).

> verbose наверное, опции b я не нашел.


В виндоуз она показывает программу занявшую порт. В линукс это опция

> -p, --program


> Show the PID and name of the program to which each socket belongs.



> Давай я пока побалуюсь немного с курлом


Тогда можешь сделать задачу про определение адреса через яндекс-API. Если не хочешь заморочиться с XMl, то геокодер позволяет отдавать ответ в формате JSON который одной функцией превращается в массив:

https://tech.yandex.ru/maps/doc/geocoder/desc/concepts/response_structure-docpage/

Реши тогда задачу про определение адреса.

Не забудь сделать проверки на сетевые ошибки. и указать разумный таймаут для запроса.

Не пиши все одной простыней, разбивай на действия в функциях или методах.

зазубривать справочники не надо, но прочесть (не запоминая) эту страницу с опциями придется: http://php.net/manual/ru/function.curl-setopt.php

> Как скачать сайт курлом, не wgetом?


О, кстати, хорошая задача, можешь ее тоже сделать. Тебе понадобится очередь или массив для хранения старниц которые надо скачать в будущем.

> Как загрузить/скачать файлы по ftp на хостинг (если они это позволяют, конечно)?


Смотри опции курла, он поддерживает FTP, как минимум скачивание. насчет закачки я не помню, если нет то надо либо найти библиоеку для FTP либо написать свою функцию, изучив протокол FTP, он простой и текстовый. думаю, это полезно, заодно научишься с TCP сокетами работать.

> а тупо зазубривать команды, не понимая их смысла не охота.


Так у курла всего несколько функций надо знать, там правда опций много но наизусть их знать не надо.

Ну и я не советую использовать курл напрямую, я советую в приложениях исопльзовать библиотеку HTTP клиента с удобным синтаксисом, напрмер Guzzle или Buzz, так как код на сыром курле смотрится плохо и плохо читается, часто также он содержит ошибки или отстутствие проверок результата. Меня он раздражает.

Конечно это не относится к учебному коду. для изучения курл можно использовать напрямую.
#381 #513254
>>513253

>Если не хочешь заморочиться с XMl


$json = json_encode(simplexml_load_string($xml_string));
$array = json_decode($json,TRUE);
Или о чем ты?
мимокрокодил
#382 #513256

> Как скачать сайт курлом, не wgetом?


http://codepad.org/dv2jWkWH
#383 #513257
>>511052

Опиши подробнее как именно ты ставишь и что делаешь. Скриншот ошибки это хорошо но хотелось бы знать как повторить проблему.

>>511020

Тебе придется писать свою функцию для аякса и со временем, наращива я возможности ты придешь к тому что перепишешь половину функции $.ajax

Если не нравится jQuery (мне он тоже не очень нравится) можно найти маленькую только аякс библиотеку или написать свою.

>>510845

Работа низкоквалифицированная и наверно не очень хорошо оплачиваемая если только ты не способен стабильно выполнть большой объем работы без косяков.

Так как знаний много не надо то много конкуренции включая индусов и пакистанцев дерущихся за $1-2 в час.

> Если искать заказы на зарубежных фриланс биржах.


Может выйти так что большую часть времени ты будешь тратить на поиски и переговоры не получая денег.

>>510842

Таблицы объединяют через джойны, если они связаны. Если ты делаешь поиск по нескольким то через UNION.

Также, код у тебя ужасный, я бы убрал PREFIX (кому нужны префиксы в наши дни) и использовал плейсхолдеры вместо переменных.

Алсо что это за название? Ты издеваешься?

> user_delet



Что за delet?

> WHERE user_search_pref LIKE '%".$query."%'


Это не индексируется и работает толкьо пока юзеров мало. Плюс, если введено несколько слов то работать не будет номально. Поиск надо делать либо через FULLTEXT индексы либо внешние движки вроде sphinx.

В общем у меня ощущение что тебе рановато писать соцсети и стоит начать с изучения SQL.

> user_country_city_name


Стоит сделать отдельнуб таблицу городов.
#383 #513257
>>511052

Опиши подробнее как именно ты ставишь и что делаешь. Скриншот ошибки это хорошо но хотелось бы знать как повторить проблему.

>>511020

Тебе придется писать свою функцию для аякса и со временем, наращива я возможности ты придешь к тому что перепишешь половину функции $.ajax

Если не нравится jQuery (мне он тоже не очень нравится) можно найти маленькую только аякс библиотеку или написать свою.

>>510845

Работа низкоквалифицированная и наверно не очень хорошо оплачиваемая если только ты не способен стабильно выполнть большой объем работы без косяков.

Так как знаний много не надо то много конкуренции включая индусов и пакистанцев дерущихся за $1-2 в час.

> Если искать заказы на зарубежных фриланс биржах.


Может выйти так что большую часть времени ты будешь тратить на поиски и переговоры не получая денег.

>>510842

Таблицы объединяют через джойны, если они связаны. Если ты делаешь поиск по нескольким то через UNION.

Также, код у тебя ужасный, я бы убрал PREFIX (кому нужны префиксы в наши дни) и использовал плейсхолдеры вместо переменных.

Алсо что это за название? Ты издеваешься?

> user_delet



Что за delet?

> WHERE user_search_pref LIKE '%".$query."%'


Это не индексируется и работает толкьо пока юзеров мало. Плюс, если введено несколько слов то работать не будет номально. Поиск надо делать либо через FULLTEXT индексы либо внешние движки вроде sphinx.

В общем у меня ощущение что тебе рановато писать соцсети и стоит начать с изучения SQL.

> user_country_city_name


Стоит сделать отдельнуб таблицу городов.
#384 #513258

>О, кстати, хорошая задача, можешь ее тоже сделать. Тебе понадобится очередь или массив для хранения старниц которые надо скачать в будущем.


>Тебе понадобится очередь


http://codepad.org/FlmoLOwG
#385 #513260
>>513253

>насчет закачки я не помню, если нет то надо либо найти библиоеку для FTP


http://php.net/manual/ru/function.ftp-put.php
#386 #513261
>>510035

>а также JS/CSS/HTML/SQL


Сап /pr/, подкинте годных уроков по изучению JS !!НА ПРАКТИКЕ!!, всегда всё учу именно на практике, я такой человек, что теория в голову ну никак не лезет, по этой причине по началалу не могу читать книги по различным языкам.
Что мне надо? Да любая тема, только бы там объясняли про js в любом его проявлении.
То есть как это, а так - человек что-то делает, описываю это в статье или снимая видео, попутно немного разъясняя, а я повторяю при этом пытаюсь понять как это всё работает, таким боком изучаю.

Как вам вообще такой стиль изучения?
#387 #513262
>>510504

Олифер кстати хороший. нас по моему в универе этими сетевыми технологиями мучали, причем трафик мы изучали не через GUI в Wireshark а дапмили через tcpdump у которой мануал размером сопосставим с моим учеьником PHP. Зато как видишь я теперь в этих технологиях разбираюсь.

Так что читай, экспериментируй, это полезно.

> Это и DNS-адреса где-то кешируются получается?


Это внутренний кеш курла в памяти и он сработает только например когда ресурс делает редирект на том же домене, курл может не отправлять повторно DNS запрос а взять ответ из кеша. Браузеры тоже кешируют DNS так как на каждой странице куча картинок и для каждой делать новый DNS запрос быдо бы медленнее.

> Что такое Accept


Там перечисляется MIME типы которые клиент предпочел бы получить в случае если у сервера есть несколько вариантов ответа. Гугли HTTP Content negotiation:

http://www.google.ru/search?sourceid=chrome&ie=UTF-8&q=HTTP+Content+negotiation

там даже есть ссылка на русском ( http://www.lib.ru/WEBMASTER/rfc2068/section-12.html ). Ну и в стандарте посмотри.

На практике это не используется, и мне не очень нравится. Проще когда сервер дает одинаковый ответ для одинаковых URL.
#388 #513263
>>510386

не работал

>>510336

> На такое согласится только совсем опущенный унтерменш без личной жизни.


почему же? Это зависит от того как ты организуешь свое время, никто не мешает тебе днем учить мануалы а вечером гулять с тян (у которой все равно днем учеба или работа).

Да и погода сейчас такая что днем на улицу вылезать неохота, жарко же.

>>510286

sudo apt-get update сделал? Алсо, погугли текст ошибки из первого скрина.

Алсо погугли debian install postrgresql может ему репозитори какой надо подключить?

На втором скрине опечатка в названии

Ну и локаль ты как-то криво настроил.

>>510258

Нет. В COOKIE записываются пришедшие из браузера в заголовках куки. Это делается до запуска скрипта и в дальнейшем массив не меняется.

>>510155

Наверно.
#388 #513263
>>510386

не работал

>>510336

> На такое согласится только совсем опущенный унтерменш без личной жизни.


почему же? Это зависит от того как ты организуешь свое время, никто не мешает тебе днем учить мануалы а вечером гулять с тян (у которой все равно днем учеба или работа).

Да и погода сейчас такая что днем на улицу вылезать неохота, жарко же.

>>510286

sudo apt-get update сделал? Алсо, погугли текст ошибки из первого скрина.

Алсо погугли debian install postrgresql может ему репозитори какой надо подключить?

На втором скрине опечатка в названии

Ну и локаль ты как-то криво настроил.

>>510258

Нет. В COOKIE записываются пришедшие из браузера в заголовках куки. Это делается до запуска скрипта и в дальнейшем массив не меняется.

>>510155

Наверно.
https://github.com/Si0n/register3 #389 #513264
>>510126

> MAIN_INSPECT_ACTIVE_TAB;


принято в начале писать что значит константа, то есть ACTIVE_TAB_INSPECT, чтобы все однотипные константы одинаково начинались.

Я не понимаю зачем для одного действия нам 2 файла:

/inspect.php
/scripts/inspect_action.php

Перенеси-ка все из второго в первый и удали inspect_action.php.

> https://github.com/Si0n/register3/blob/master/inspect.php#L6


> require './scripts/messages.php';



Я думаю, проверку сообщений можно перенести в ini.php. И вообще, оставь там только require '...ini.php';

> IMAGE_CRP_SIZE


Не стоит сокращать ради одной буквы. Лучше писать CROP. Вообще, не стоит сокращать названия.

> https://github.com/Si0n/register3/blob/master/scripts/inspect_action.php#L11


> if ($ID == '')


> {


> $ID = $student->getID();


> }


> $profileByID = $db->findStudentByID($ID);



Если у тебя уже загружен объект студента, какой смысл загружать его второй раз? тут надо переписать на if/else.

> $db = new StudentsMapper($pdo);


Одинаковые вещи надо назвать одинаково:

$studntMapper = new StudentMapper

чтобы не создавать путаницу.

> $student = new Student();


> $student->setFieldsWithWhiteSpaces();


Можно сделать чтобы у полей по умолчанию были нужные значения и тогда вызывать функцию не придется.

> https://github.com/Si0n/register3/blob/e2c034bf4563363908504cec9ba6846ae2ded121/scripts/messages.php


Это надо перенести в функцию и удалить этот файл.

Еще кое-что. Файл ini.php у тебя становится слишком большой и в нем слишком много переменных. Если что-то из него можно вынести в функции, стоит это сделать.

> $photoError = FALSE; //ошибки по загрузке фото, которые в случае ошибок заполнятся в savePhoto.php, и выведутся в inspect.php


Это надо перенести в файл работающий с загрузкой фотографий.

> $register = FALSE; // =>savePhoto.php, reg.php => TRUE = > обрабатывается в edit.php


Это наверно перенести в файл работы с формой регистрации. Зачем оно в savePhoto?

> $ID = isset($_GET['ID']) ? $_GET['ID'] : '' ;


> $err = isset($_GET['err']) ? 'Вы ничего не ввели, либо использовали недопустимые символы' : FALSE ;


Это перенести туда где оно используется.

> $search = '';


это в файл вывода списка студентов, если он используется только там. Если везде то можно оставить.

Константы перенеси-ка в functions.php

> $headerMessage = 'К сожалению, Вас нет в списке студентов.';


Я думаю, эту переменную можно убрать, а в шаблоне проверять есть ли id у студента или нет и соовтетственно выводить разные сообщения в этом случае.

> https://github.com/Si0n/register3/blob/master/scripts/ini.php#L33


Чему будет равна переменная $student если студент не найден в базе и if не сработал?

> https://github.com/Si0n/register3/blob/master/scripts/list_action.php#L4


> $recordsPerPage = 4; //Количество результатов на страницу, для теста 4


> $takeRes = 4; //сколько взять результатов


Это разве не одно и то же? Тогда зачем 2 переменных?

> https://github.com/Si0n/register3/blob/master/scripts/list_action.php#L20


Вот тут есть несколько ифов, которые выставляют значения вроде $tablePanelHeadingText = TAB_HEADER_WRONG_REQUEST;

Так ли нам нужна эта переменная? Нельзя просто эти ифы перенести в шаблон?

> } elseif ($students == 'failed')


Хотя это конечно не перенесешь. Лучше наверно при передаче неправильного имени поля потихому его исправлять на поле по умолчанию и тогда эта проверка станет не нужна.

> https://github.com/Si0n/register3/blob/master/lib/Image.php#L65


> $src = 'E:/OpenServer/domains/localhost/php/register3/upload/'. 'full-'.$name;


Это неправильно. Как я запущу твой проект если у меня папка другая? Надо либо вынести путь в конфиг либо (что лучше) определять его в ini.php автоматически через константу _ _ DIR _ _

> https://github.com/Si0n/register3/blob/master/inspect.php#L14


После успешной обработки формы надо редиректить и завершать скрипт.

> https://github.com/Si0n/register3/blob/master/list.php


Если файл list_action.php подключается только здесь то лучше перенести его содержимое сюда.

> https://github.com/Si0n/register3/blob/master/list.php#L2


> error_reporting(-1);


> ini_set('display_errors', 1);


Это перенеси в ini.php, не надо эти строчки копипастить в каждый скрипт.

> https://github.com/Si0n/register3/blob/master/messages.sql#L29


В таблице messages добавь внешние ключи как описано тут: http://denis.in.ua/foreign-keys-in-mysql.htm

Не забудь обновить файл messages.sql

> UNIQUE KEY `id_message` (`id_message`)


Это правильнее сделать первичным ключом так как первычный ключ это уникальный идентификатор записи и тут как раз такой случай.

В проверку валидности сообщения добавь проверку валидности id автора и id_target. для этого придется наверно вызвать другие мапперы, рабтающие с этим и таблицами.

Пока все, как исправишь, проверим еще.

Не жди пока я проверю, делай какие-то другие фичи или задания.
https://github.com/Si0n/register3 #389 #513264
>>510126

> MAIN_INSPECT_ACTIVE_TAB;


принято в начале писать что значит константа, то есть ACTIVE_TAB_INSPECT, чтобы все однотипные константы одинаково начинались.

Я не понимаю зачем для одного действия нам 2 файла:

/inspect.php
/scripts/inspect_action.php

Перенеси-ка все из второго в первый и удали inspect_action.php.

> https://github.com/Si0n/register3/blob/master/inspect.php#L6


> require './scripts/messages.php';



Я думаю, проверку сообщений можно перенести в ini.php. И вообще, оставь там только require '...ini.php';

> IMAGE_CRP_SIZE


Не стоит сокращать ради одной буквы. Лучше писать CROP. Вообще, не стоит сокращать названия.

> https://github.com/Si0n/register3/blob/master/scripts/inspect_action.php#L11


> if ($ID == '')


> {


> $ID = $student->getID();


> }


> $profileByID = $db->findStudentByID($ID);



Если у тебя уже загружен объект студента, какой смысл загружать его второй раз? тут надо переписать на if/else.

> $db = new StudentsMapper($pdo);


Одинаковые вещи надо назвать одинаково:

$studntMapper = new StudentMapper

чтобы не создавать путаницу.

> $student = new Student();


> $student->setFieldsWithWhiteSpaces();


Можно сделать чтобы у полей по умолчанию были нужные значения и тогда вызывать функцию не придется.

> https://github.com/Si0n/register3/blob/e2c034bf4563363908504cec9ba6846ae2ded121/scripts/messages.php


Это надо перенести в функцию и удалить этот файл.

Еще кое-что. Файл ini.php у тебя становится слишком большой и в нем слишком много переменных. Если что-то из него можно вынести в функции, стоит это сделать.

> $photoError = FALSE; //ошибки по загрузке фото, которые в случае ошибок заполнятся в savePhoto.php, и выведутся в inspect.php


Это надо перенести в файл работающий с загрузкой фотографий.

> $register = FALSE; // =>savePhoto.php, reg.php => TRUE = > обрабатывается в edit.php


Это наверно перенести в файл работы с формой регистрации. Зачем оно в savePhoto?

> $ID = isset($_GET['ID']) ? $_GET['ID'] : '' ;


> $err = isset($_GET['err']) ? 'Вы ничего не ввели, либо использовали недопустимые символы' : FALSE ;


Это перенести туда где оно используется.

> $search = '';


это в файл вывода списка студентов, если он используется только там. Если везде то можно оставить.

Константы перенеси-ка в functions.php

> $headerMessage = 'К сожалению, Вас нет в списке студентов.';


Я думаю, эту переменную можно убрать, а в шаблоне проверять есть ли id у студента или нет и соовтетственно выводить разные сообщения в этом случае.

> https://github.com/Si0n/register3/blob/master/scripts/ini.php#L33


Чему будет равна переменная $student если студент не найден в базе и if не сработал?

> https://github.com/Si0n/register3/blob/master/scripts/list_action.php#L4


> $recordsPerPage = 4; //Количество результатов на страницу, для теста 4


> $takeRes = 4; //сколько взять результатов


Это разве не одно и то же? Тогда зачем 2 переменных?

> https://github.com/Si0n/register3/blob/master/scripts/list_action.php#L20


Вот тут есть несколько ифов, которые выставляют значения вроде $tablePanelHeadingText = TAB_HEADER_WRONG_REQUEST;

Так ли нам нужна эта переменная? Нельзя просто эти ифы перенести в шаблон?

> } elseif ($students == 'failed')


Хотя это конечно не перенесешь. Лучше наверно при передаче неправильного имени поля потихому его исправлять на поле по умолчанию и тогда эта проверка станет не нужна.

> https://github.com/Si0n/register3/blob/master/lib/Image.php#L65


> $src = 'E:/OpenServer/domains/localhost/php/register3/upload/'. 'full-'.$name;


Это неправильно. Как я запущу твой проект если у меня папка другая? Надо либо вынести путь в конфиг либо (что лучше) определять его в ini.php автоматически через константу _ _ DIR _ _

> https://github.com/Si0n/register3/blob/master/inspect.php#L14


После успешной обработки формы надо редиректить и завершать скрипт.

> https://github.com/Si0n/register3/blob/master/list.php


Если файл list_action.php подключается только здесь то лучше перенести его содержимое сюда.

> https://github.com/Si0n/register3/blob/master/list.php#L2


> error_reporting(-1);


> ini_set('display_errors', 1);


Это перенеси в ini.php, не надо эти строчки копипастить в каждый скрипт.

> https://github.com/Si0n/register3/blob/master/messages.sql#L29


В таблице messages добавь внешние ключи как описано тут: http://denis.in.ua/foreign-keys-in-mysql.htm

Не забудь обновить файл messages.sql

> UNIQUE KEY `id_message` (`id_message`)


Это правильнее сделать первичным ключом так как первычный ключ это уникальный идентификатор записи и тут как раз такой случай.

В проверку валидности сообщения добавь проверку валидности id автора и id_target. для этого придется наверно вызвать другие мапперы, рабтающие с этим и таблицами.

Пока все, как исправишь, проверим еще.

Не жди пока я проверю, делай какие-то другие фичи или задания.
#390 #513265
>>513232

Это всего лишь подключение кастомных шрифтов с помощью flash по моему (в наше время не треубется, новые браузеры умеют поддерживать загружаемые шрифты без флеша и яваскрипта).

Судя по расшиению это шаблоны.

>>513233

> то что ты вообще в вебе делаешь? чисто задачки из ОП-поста решаешь?


Я не решаю, а составляю задачки, пишу уроки и проверяю решения.

Мне не охота за тебя читать документацию к твоей CMS. У меня своей работы достаточно.

>>513238

Тот кто делал тот проект тоже так думал.

Надо писать хороший и поддерживаемый код чтобы про тебя потом так же не говорили.

>>513242

Надо читать доки и иногда смотреть в код и сравнивать. Как насчет посмотреть на несложный контейнер из фреймворка Slim?

http://docs.slimframework.com/di/overview/
https://github.com/slimphp/Slim/blob/2.x/Slim/Helper/Set.php

как видишь он напоминает массив с методами.

Микрофреймворк Silex ( http://silex.sensiolabs.org/doc/services.html ) использует Pimple ( http://pimple.sensiolabs.org/ ) как контейнер (там основной класс от него унаследован):

https://github.com/silexphp/Pimple
https://github.com/silexphp/Pimple/blob/master/src/Pimple/Container.php

Тоже по сути массив с методами.

Имей в виду что это решения для микрофреймворков.
#390 #513265
>>513232

Это всего лишь подключение кастомных шрифтов с помощью flash по моему (в наше время не треубется, новые браузеры умеют поддерживать загружаемые шрифты без флеша и яваскрипта).

Судя по расшиению это шаблоны.

>>513233

> то что ты вообще в вебе делаешь? чисто задачки из ОП-поста решаешь?


Я не решаю, а составляю задачки, пишу уроки и проверяю решения.

Мне не охота за тебя читать документацию к твоей CMS. У меня своей работы достаточно.

>>513238

Тот кто делал тот проект тоже так думал.

Надо писать хороший и поддерживаемый код чтобы про тебя потом так же не говорили.

>>513242

Надо читать доки и иногда смотреть в код и сравнивать. Как насчет посмотреть на несложный контейнер из фреймворка Slim?

http://docs.slimframework.com/di/overview/
https://github.com/slimphp/Slim/blob/2.x/Slim/Helper/Set.php

как видишь он напоминает массив с методами.

Микрофреймворк Silex ( http://silex.sensiolabs.org/doc/services.html ) использует Pimple ( http://pimple.sensiolabs.org/ ) как контейнер (там основной класс от него унаследован):

https://github.com/silexphp/Pimple
https://github.com/silexphp/Pimple/blob/master/src/Pimple/Container.php

Тоже по сути массив с методами.

Имей в виду что это решения для микрофреймворков.
#391 #513267
>>513249

Заведи блог и пиши. Это бесплатно.

>>513254

А где проверка ошибок? Это плохой код. Также XML невыгодно превращать в JSON так как ты тераяешь возмодность использовать XPath например.

Ну и яндекс API и так умеет отдавать JSON если хорошо попросить.

>>513256

Это скчивание однй страницы причем простыней без разбинения на функции.

> url_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko)


Так неправильно писать в учебном примере. Код должен учить хорошим практикам и объяснять каждую опцию.

> curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, false);


>\t\tcurl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, false);


Это требует объяснений. И небезопасно.

> if(is_array($headers))


А если не массив?

Также нет проверки результата.

Код плохой.

Это лучше сделать не функцией с 100500 аргументов а классом. В 99% случаев тебе не нужен прокси например.
#391 #513267
>>513249

Заведи блог и пиши. Это бесплатно.

>>513254

А где проверка ошибок? Это плохой код. Также XML невыгодно превращать в JSON так как ты тераяешь возмодность использовать XPath например.

Ну и яндекс API и так умеет отдавать JSON если хорошо попросить.

>>513256

Это скчивание однй страницы причем простыней без разбинения на функции.

> url_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko)


Так неправильно писать в учебном примере. Код должен учить хорошим практикам и объяснять каждую опцию.

> curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, false);


>\t\tcurl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, false);


Это требует объяснений. И небезопасно.

> if(is_array($headers))


А если не массив?

Также нет проверки результата.

Код плохой.

Это лучше сделать не функцией с 100500 аргументов а классом. В 99% случаев тебе не нужен прокси например.
#392 #513268
>>513258

Это же нечитаемая простыня. Есть ограничение глубины ссылок, ограничение по путям и доменам? Это не учебный пример, он если чему и учит то дурным практикам.

Плюс асинхронный курл требует удобного интерфейса. А тут вообще непонтяно корректно он реализован и все ли ситуации обрабатываются.
#393 #513269
>>513261

learn.javascript.ru читал?

ПРежде чем заниматься практикой надо выучить сам язык программирования. Перепсывание кода с экрана ничего не дает.

> Как вам вообще такой стиль изучения?


Ты ничему так не науичшься и свалишься на первом же вопросе на соеседовании.
#394 #513270
Порекомендуйте книгу про jQuery или напишите что сами читали. Только на русском, а то я дибил.

По сути нужно пройтись по популярным методам, а справочник ломает читать.
#395 #513271
Аноны, хороший пост про URL, все кто изучает веб-приложения, прочтите и поймите: http://m.habrahabr.ru/post/232385/
#396 #513272
>>513267

>Это скчивание однй страницы причем простыней без разбинения на функции.


Ну я не так понял, значит. Алсо, для этого курл и не нужен тогда.

>Так неправильно писать в учебном примере.


Неправильно что? Функция для эмуляции запросов из браузера, обычная установка юзерагента, а уж какой туда засунуть - другое дело.

>Это требует объяснений. И небезопасно.


И не нужно ебаться с валидацией сертификатов, когда тебе это не нужно вообще. А так:
curl_setopt($ch, CURLOPT_SSLCERT, 'cert.pem');
curl_setopt($ch, CURLOPT_SSLCERTPASSWD,'certpass');

>А если не массив?


Очевидно что if не сработает, не?

>Также нет проверки результата.


Не в этой функции это надо делать, ибо можно обращаться к сотням разных сервисов, и что, под каждый писать свою обработку? На что проверять результат? В ответе тебе и так приходят заголовки, а если ты про ошибки курла, то опять же добавить всего пару строчек:

$response = curl_exec($ch);
if(curl_errno($ch))
{
echo 'curl error: ' . curl_error($ch);
error_wrapper(curl_errno($ch));
}

>Код плохой. Это лучше сделать...


Ты уж покажи тогда как сделать хорошо, и не тянуть за собой огромные движки, тонну ненужного в данных целях ООП и прочего.

>В 99% случаев тебе не нужен прокси например.


Поэтому там есть дефолтные значение и определенный порядок.

Алсо, я просто в качестве мини-примера запостил, в самом простом варианте, а там уж кому надо допилит и переделает под свои вкусы.
#396 #513272
>>513267

>Это скчивание однй страницы причем простыней без разбинения на функции.


Ну я не так понял, значит. Алсо, для этого курл и не нужен тогда.

>Так неправильно писать в учебном примере.


Неправильно что? Функция для эмуляции запросов из браузера, обычная установка юзерагента, а уж какой туда засунуть - другое дело.

>Это требует объяснений. И небезопасно.


И не нужно ебаться с валидацией сертификатов, когда тебе это не нужно вообще. А так:
curl_setopt($ch, CURLOPT_SSLCERT, 'cert.pem');
curl_setopt($ch, CURLOPT_SSLCERTPASSWD,'certpass');

>А если не массив?


Очевидно что if не сработает, не?

>Также нет проверки результата.


Не в этой функции это надо делать, ибо можно обращаться к сотням разных сервисов, и что, под каждый писать свою обработку? На что проверять результат? В ответе тебе и так приходят заголовки, а если ты про ошибки курла, то опять же добавить всего пару строчек:

$response = curl_exec($ch);
if(curl_errno($ch))
{
echo 'curl error: ' . curl_error($ch);
error_wrapper(curl_errno($ch));
}

>Код плохой. Это лучше сделать...


Ты уж покажи тогда как сделать хорошо, и не тянуть за собой огромные движки, тонну ненужного в данных целях ООП и прочего.

>В 99% случаев тебе не нужен прокси например.


Поэтому там есть дефолтные значение и определенный порядок.

Алсо, я просто в качестве мини-примера запостил, в самом простом варианте, а там уж кому надо допилит и переделает под свои вкусы.
#397 #513273
>>513269
learn.javascript.ru не читал, почитаю.

Это не тупое переписывание кода с экрана, конечно просто бездумное переписывание даст чуть более чем ничего. Я же при написании чего либо стараюсь понять, что я написал, как это работает и т.д, таким образом информация отлично отлаживаеться в голове.

Сначала таким образом хочу выучить чуть более основ, а потом уже смогу нормально читать книги по теме.
#398 #513275
>>513273

Я не очень советую learn.javascript.ru. Поначалу там все хорошо, но потом какая-то хуйня начинается ближе к концу. Куча всякой лишней инфы, какие-то ебанутые вставки с примечаниями аля "это инфа прост тут, можете не читать)))0" и прочая херня.

Советую посмотреть курс от неких ITVDN, там все подробно разжевывается. Иногда даже чересчур. Но если что мотануть можно. Правда он платный, но при желании можно всегда на торрентах его купить.

анон со схожим стилем обучения
#399 #513276
>>513261
В курсе специалиста происходит так как ты хочешь. Если конспектировать, то материал легко усвоится, ну кроме замыканий, даже блондинкой. Чистый ЖС - самая сложная часть, DOM вообще легкотня, события тоже, хотя всплытие заставило поломать голову. jQuery тоже ничего сложного.
Диржи http://nnm-club.me/?q=%F1%EF%E5%F6%E8%E0%EB%E8%F1%F2+javascript+2014&w=title
#400 #513277
>>513275
>>513276
Спасибо анончики, гляну как будет время.
37 Кб, 869x192
#401 #513278
>>513245
А почему оно текст криво отрисовывает?
#402 #513279
>>513278
Ты еще криво не видел. Это ок. Хотя попробуй по-человечески, через @font-face.
#403 #513281
>>513265
У него вся страница динамически из темплейтов отрисована и каждый текст канвасом в свг отрисовывается через инпут в админке. ояхуею как это редактировать вообще.
#404 #513282
>>513265

> а составляю задачки, пишу уроки и проверяю решения.


препод что ли?
#405 #513283
>>513279
это хуйня из датабазы отрисовывается, а в дб через инпут в админке засовывается, там ПРОСТО БУКОВКАМИ в хтмл тегах не напишешь это.
#406 #513298
Анон, подскажи как реализовать сортировку по необходимому параметру в задаче про студентов, когда выводишь таблицу. Сделать название параметров в виде кнопок и обрабатывать их нажатие или есть лучше вариант?
#407 #513320
>>513298
ORDER BY.
#408 #513321
>>513320
Предложение проебал
Сделай просто треугольник, при нажатии котором колонка сортируется по ORDER BY.
#409 #513329
Решаю сейчас задачу про айпад. Вчера ебался весь вечер с ней, а сегодня утром встал и написал, как будто во сне уже обдумал все решение.
Только есть одно но: в условии строуберрибанка есть плата за открытие счета, которую надо сделать единожды, а не через цикл. Не могу понять, как сделать это. Помогите, антошки.
#410 #513332
>>513228

>Тут много ошибок, например не кодируются параметры в URL, никак не обрабатываются сетевые ошибки, непонятно почему текст разбивается на куски по 3 слова, слова могут быть разделены не только проблелом,


Это всё понятно, это черновик, текст разбивается по 3 слова по тому что именно так чаще всего проверяют текст на уникальность, то есть шингл = 3, а как кроме пробелов могут разделяться слова? запятыми, точками и восклицательными знаками? Ну в этом случае всё равно есть пробелы, а если они не нужны для проверки на уникальность их можно просто почистить, заменить все эти символы на ничто например, ну не в этом дело, меня интересует сама технология, как это вообще делается? Если откинуть все недоработки, сама основа скрипта верная, так это делается или нет? Много же существует ресурсов для проверки уникальности, как они это сделали?
#411 #513343
>>513332
сразу видно опытного копирайтера. привет, коллега.
#412 #513364
>>513272

Твой пример содержит ошибки и не содержит объяснений. Плюс у тебя тараканы в голове в виде представления о «ненужном» ООП. Это не годится как учебный пример, так как учеьный пример должен учить правильным техникам и объяснять.

В качестве User-Agnet очевидно принято указывать название библиотеки а не прикидываться браузером (что легко проверить при желании).

> я просто в качестве мини-примера запостил


пример как делать не надо.
#413 #513365
Пых может поломать жизнь не хуже любой дури, поэтому слушай, мой юный друг. Да, Пых — самый короткий и быстрый путь к баблу. Но если ты решил связать свою жизнь с программированием, то совет один: даже и не думай о Пыхе, иначе через пару лет будешь рвать волосы на жопе.

PHP (вместе с Pascal) — самые низкооплачиваемые языки программирования. Сколько бы книг ты ни прочитал, сколько бы мегабайт кода ни написал, ты никогда не будешь получать больше, чем Java-быдлокодер средней криворукости. «На Яве пишут Корпорации», а на Пыхе…Порог выхода такой же низкий, как и порог входа: если у программиста на полноценных языках с возрастом есть шанс стать ценным высокооплачиваемым специалистом, то у похапе-олдфага такой возможности нет просто ввиду убогости и примитивности решаемых задач. Его спокойно можно выгнать на улицу, взяв взамен школьника, который обучится всем премудростям похапе-быдлокоддинга за пару месяцев, потребляя при этом в три раза меньше доширака.Возможно, сейчас тебе кажется, что делать сайты — достойное и интересное занятие, но если ты хоть немного программист, через пару лет такой работы ты просто завоешь от того, насколько это унылая и далекая от программирования деятельность.Большинство проектов кроме того, что по сути своей убоги, представляют из себя чудовищный говнокод на кривых самодельных говнофреймворках и говноCMS (потому как сам язык не только не заставляет писать правильно, но и фактически подталкивает к производству быдловелосипедов). Как следствие такой работы — необратимое поражение мозга и окончательная потеря квалификации. Чему также способствует работа в коллективе невероятно тупых похапешников, постоянные оскорбления и обвинения (просто потому, что умный человек PHP не выберет).Некоторые начинают работать на PHP с надеждой потом перейти на что-нибудь другое. Но это тоже большая ошибка: во-первых, теряется драгоценное время для старта (наверное, самое важное и ценное в и без того короткой профессиональной жизни программиста), а во-вторых, PHP-опыт никому не нужен и нормальные программисты справедливо смотрят на него как на говно. «PHP» — клеймо быдлокодера на лбу и крест на карьере профессионального программиста, если ты пошёл по этому пути, назад дороги уже не будет. Единственное исключение — устроится похапешником на многопрофильную фирму, где тебя каким-то чудом заметят и предложат перейти на полноценную технологию, но это невероятная удача.Чуть более, чем вся относительно хорошо оплачиваемая работа для похапешников состоит из поддержки ботнетов, порносайтов, говносайтов с вирусами и прочего подобного дерьма. Подумай, хочешь ли ты потратить свою жизнь на засирание интернетов.

PHP погубил очень много потенциально хороших программистов просто благодаря легкости изучения на начальных этапах. Он затягивает как наркотик, с ним очень легко и приятно начать, вот только когда приходит понимание принципиальных недостатков как самого языка, как и (что гораздо более важно) его убогой ниши — часто оказывается уже слишком поздно что-то менять. Так что учись программировать, думай о будущем и обходи PHP стороной. Потому что с PHP у тебя нет будущего — это путь в никуда.
#413 #513365
Пых может поломать жизнь не хуже любой дури, поэтому слушай, мой юный друг. Да, Пых — самый короткий и быстрый путь к баблу. Но если ты решил связать свою жизнь с программированием, то совет один: даже и не думай о Пыхе, иначе через пару лет будешь рвать волосы на жопе.

PHP (вместе с Pascal) — самые низкооплачиваемые языки программирования. Сколько бы книг ты ни прочитал, сколько бы мегабайт кода ни написал, ты никогда не будешь получать больше, чем Java-быдлокодер средней криворукости. «На Яве пишут Корпорации», а на Пыхе…Порог выхода такой же низкий, как и порог входа: если у программиста на полноценных языках с возрастом есть шанс стать ценным высокооплачиваемым специалистом, то у похапе-олдфага такой возможности нет просто ввиду убогости и примитивности решаемых задач. Его спокойно можно выгнать на улицу, взяв взамен школьника, который обучится всем премудростям похапе-быдлокоддинга за пару месяцев, потребляя при этом в три раза меньше доширака.Возможно, сейчас тебе кажется, что делать сайты — достойное и интересное занятие, но если ты хоть немного программист, через пару лет такой работы ты просто завоешь от того, насколько это унылая и далекая от программирования деятельность.Большинство проектов кроме того, что по сути своей убоги, представляют из себя чудовищный говнокод на кривых самодельных говнофреймворках и говноCMS (потому как сам язык не только не заставляет писать правильно, но и фактически подталкивает к производству быдловелосипедов). Как следствие такой работы — необратимое поражение мозга и окончательная потеря квалификации. Чему также способствует работа в коллективе невероятно тупых похапешников, постоянные оскорбления и обвинения (просто потому, что умный человек PHP не выберет).Некоторые начинают работать на PHP с надеждой потом перейти на что-нибудь другое. Но это тоже большая ошибка: во-первых, теряется драгоценное время для старта (наверное, самое важное и ценное в и без того короткой профессиональной жизни программиста), а во-вторых, PHP-опыт никому не нужен и нормальные программисты справедливо смотрят на него как на говно. «PHP» — клеймо быдлокодера на лбу и крест на карьере профессионального программиста, если ты пошёл по этому пути, назад дороги уже не будет. Единственное исключение — устроится похапешником на многопрофильную фирму, где тебя каким-то чудом заметят и предложат перейти на полноценную технологию, но это невероятная удача.Чуть более, чем вся относительно хорошо оплачиваемая работа для похапешников состоит из поддержки ботнетов, порносайтов, говносайтов с вирусами и прочего подобного дерьма. Подумай, хочешь ли ты потратить свою жизнь на засирание интернетов.

PHP погубил очень много потенциально хороших программистов просто благодаря легкости изучения на начальных этапах. Он затягивает как наркотик, с ним очень легко и приятно начать, вот только когда приходит понимание принципиальных недостатков как самого языка, как и (что гораздо более важно) его убогой ниши — часто оказывается уже слишком поздно что-то менять. Так что учись программировать, думай о будущем и обходи PHP стороной. Потому что с PHP у тебя нет будущего — это путь в никуда.
#414 #513370
>>513281

Ты бы (или он бы) документацию по cufon почитал для начала.

>>513298

Сделай заголовок колонки ссылкой вида index.php?sort=name

Алсо в комментариях к задаче разве это не написано?

>>513329

Перед началом цикла прибавь эти 7777 к сумме долга.

>>513332

> текст разбивается по 3 слова по тому что именно так чаще всего проверяют текст на уникальность, то есть шингл = 3,


Какой еще шингл? Для поиска в гугле они тебе не нужны.

Алсо для сеошников есть раздел /web.
#415 #513371
>>513365

>(вместе с Pascal) — самые низкооплачиваемые языки программирования.


Подскажи куда устроиться на паскале программировать.
#416 #513379
Уважаемы, делаю задачу с ГомоКредитБанком, решил для теста только на одном банке проверить, но выбивает ошбку.
Ткните, пожалуйста, в чем она?
http://ideone.com/5ZiBQT
#417 #513381
>>513379
Все, потерял "}"
#418 #513383
>>513379
>>513381
Вроде сделал, но с последним банком выходит слишком мало, 40к+7к и еще 2%, а оплатит всего 45к.
Подскажите, пожалуйста
#419 #513384
>>513379
>>513381
Вроде сделал, но с последним банком выходит слишком мало, 40к+7к и еще 2%, а оплатит всего 45к.
Подскажите, пожалуйста
#420 #513387
Помогите подправить цмску и парсер (
#421 #513388
>>513365

> можно выгнать на улицу


воу воу, да я не работаю нигде - мой потолок фриланс.
#422 #513389
>>513379
>>513381
Вроде сделал, но с последним банком выходит слишком мало, 40к+7к и еще 2%, а оплатит всего 45к.
Подскажите, пожалуйста
#423 #513390
>>513389
Абу, зачем вакабу расшатал?!
#424 #513391
>>513390
У меня вообще не отправляется, а у них сук по три раза.
#425 #513392
>>513381
В блокноте погромируешь?
#426 #513404
наговнякал
http://ideone.com/xSPWmX
#427 #513405
800 строк чистого php кода - и не лень же кому-то было писать? и мне их надо пофиксить, а я даже не понимаю где, защо?
#428 #513408
>>513405
По-твоему это много?
У меня в файлообменнике 461 строка php-кода, не считая js, css и html.
И это простейшее хелловорлдное приложение, его за два дня можно написать, если знать как.
На больших фреймворках проекты могут спокойно переваливать за десятки тысяч строк.
#429 #513414
>>513408
А как в них не путаются потом? По-моему в чужом коде вообще бесполезно ковырять, потмоу что не ты писал..
39 Кб, 744x583
#430 #513422
>>513414
Именно поэтому мы и учим тут ООП. Все очень логично упаковано в классы, сами классы соответствуют паттернам.
Например если ты видишь какой-нибудь UserMapper, то сразу можешь понять: "ага, это же известнейший паттерн DataMapper, у него точно есть методы для работы с базой данных для сохранения, обновления или удаления записей". Я даже не залезая внутрь этого класса знаю, что внутри него находится и как он устроен! В этом суть ООП, в четкой логичной структуре.
Или вот я вижу запись типа $app = Applicattion::getInstance();
Я сразу понимаю, что это паттерн синглтон, и что объект $app у меня все время будет один и тот же, не будет двух его копий по всему проекту.

И так далее. То есть все очень хорошо стандартизировано. Это как раз функциональный код совершенно неудобный, нечитабельный и нередактируемый: тут какая-то функция. Лезем в файл с функциями, поиском ее находим, в ней вызывается еще десять функций с невнятными названиями. Лезем в каждую из этих десяти. Там творится тоже какая-то неведомая хрень, и вызываются другие функции с ни о чем не говорящими именами. В результате ты не имеешь никакого представления, что, куда и зачем, как эта хрень вообще между собой связана и как оно работает. Если попытаешься что-то редактировать, то это потянет за собой еще кучу правок.
Так написано большинство cms, и именно за это их не любят.

В ООП все четко, последовательно, все связи даже рисуют на uml-диаграммах, и разобраться что и где не составит труда и времени. Это похоже на схемы баз данных, если ты работал в Воркбенче например. Пикрелейтед.
Но учиться конечно нужно очень много.
#431 #513425
>>513422
Где про эти паттерны почитать, которые часто встречаются?
#432 #513427
Переделал задачку про йоду http://ideone.com/34PDkN
И кальулятор http://ideone.com/DL243G
#433 #513435
>>513422
А твой пикрелейтед в чем нарисован?
#434 #513448
>>513425
Для общего развития можешь на хабре почитать
http://habrahabr.ru/post/214285/
http://habrahabr.ru/post/210288/
Или послушать лекции Борисова (4 курс php), он неплохо объясняет.

Но это сейчас не важно. Без практического применения все равно мало поймешь.
Решай задания ОПа, когда дойдешь до файлообменника, будешь тащиться от красоты объектно-ориентированного кода, я гарантирую это.

Затем когда будешь учить большие фреймворки, там эти шаблоны друг на друге сидят и шаблоном погоняют, и это правильно и здорово.
Ну и потом уже можно будет почитать хардкорный первоисточник, книгу Мартина Фаулера "Шаблоны проектирования".

>>513435
Хз, я из гугла взял. И вообще я хуй простой, мне просто нравится всех поучать с умным видом.
#435 #513452
>>513422

>Это как раз функциональный код совершенно неудобный, нечитабельный и нередактируемый: тут какая-то функция. Лезем в файл с функциями, поиском ее находим, в ней вызывается еще десять функций с невнятными названиями.


Ойнинада приёмы кодирования везде одинаковы. Вот функция scan_files получает на вход переменные path и mask и ещё одну функцию, догадайся что она делает. А вот такая же функция scan_words, получает на вход строку... продолжать?
#436 #513454
>>513452

Догадаться можно если у переменных хорошие названия или если комментарий есть.

Ну и общепринятые подходы это хорошо. Разбирать MVC код на Юи гораздо легче чем на самописаной CMS.
#437 #513461
>>513452
Scan_words мне ни о чем не говорит. Ну да, оно сканирует какие-то слова. А к чему эта функция вообще относится? Что за words? Это относится к валидации? Или может быть вообще к чему-то другому? Если к валидации, то валидации чего? Какой-то формы? Какой?
Вот-вот.
А в ООП все четенько, каждый метод строго относится к классу, а класс точно описывает объект. Классы можно наследовать, если объект нужно слегка изменить. А твоя функция заточена под какие-то условия, и ее нужно либо переписывать, либо копипастить в новую функцию и уже там менять.
#438 #513465
>>513461

>А твоя функция заточена под какие-то условия, и ее нужно либо переписывать, либо копипастить в новую функцию и уже там менять.


ВЫ ВСЁ ВРЁТИ.
Я дополню её другой функцией, подам на вход. Слова она выбирает из строки, не надо там ничего переписывать, цикл while это.
#439 #513496
что взять с рнр-ребёнка?
#440 #513508
Ну что же меня, по-крайней мере утешает один факт - хуже пхп только жс.
Вообще, такое ощущение, что я делаю сайт 14летней девочке.
#441 #513509
>>513343
Привет, до сих пор работаю на этом поприще уже как второй год, вот пытаюсь перейти на ПХП.
#442 #513510
>>513370

>Какой еще шингл? Для поиска в гугле они тебе не нужны.


Так уникальность проверяется, то есть смотри как найти совпадение с другим текстом в интернете, надо проверить текст по частям, разбивать на 3 слова самый удачный вариант, так как если разбить на два слова то почти все тексты в сети будут не уникальными, а на 4 уже довольно много, 3 идеально, как у Пифагора.
#443 #513511
>>513422
да, я очень рад за ООП, но ковыряться-то мне приходится в цмс.
#444 #513512
Я вообще-то честно говоря распаковал файлы с этой ебучей динамической цмской и они у меня даже на хосте нормально не отображаются (конфиг изменил, дб закачал).
#445 #513515
>>513512
Конфиги крути, пути сбиты.
#446 #513516
Я что то не могу понять как работает __autoload, вот например типичный пример:

function __autoload($class_name) {
include $class_name . '.php';
}

$obj = new MyClass1();
$obj2 = new MyClass2();

Как эта функция определяет какой класс надо подключить? И как она вообще его находит?
#447 #513519
>>513516
Ну в php вшито, что если он не может найти класс, то не орать об ошибке, а исполнить функцию __autoload, подставив в нее в качестве аргумента имя отсутствующего класса. А внутри функции тупо подставляется это имя, и файл подключается. Но это сработает, только если ты будешь называть файлы с классами так же, как и сами классы, разумеется.
#448 #513521
>>513515
с конфигами все нормальное, нулевая частично отрисовывается (а вот стили и пути к товарам - нет). эх, пичклька, уже второй день из пяти, а я до сих пор не могу даже копнуть цмску, потому что у меня она нихуя не работает на локалке, в слепую же не править, право.
#449 #513525
\tcase "logout":
\t\t\t$_SESSION['admins'] = "";
\t\t\techo $common->re("0", "admin/");
\t\tbreak;

Говорит ли это о том, что при разлогинивании сессия удаляется?
#450 #513530
>>513519
Ясно, спасибо, вот ещё один момент не могу никак понять, как работает вот эта вещь?

set_include_path(get_include_path()
.PATH_SEPARATOR . "путь к папке1".
PATH_SEPARATOR . "путь к папке2".
PATH_SEPARATOR . "путь к папке");

И как она помогает при аутолоаде, у меня выбивает ошибку.
#451 #513536
>>513530
Для аутолоада используй Composer.
112 Кб, 635x394
#452 #513540
Хэй, пыхари, привет. Я тут сидел на интерпалсе, и нашёл интересную штуку(см.пик): я не могу писать этому пользователю или оставлять комменты, т.к. в настройках приватности она отказалась принимать сообщения от пользователей, живущих в Европе. Но кнопка тут каким-то хуем просочилась. Я с пхп вообще никак не был связан, даже не знаю, только ли это UI, или UI+BE. Сам я жавакодер + знаю JS + в свободное время клепаю сайтик на ангуларе. Вопрос - можно ли как-нибудь обойти UI ограничение и попробовать достучаться до BE? Возможно он был написан индусом левой пяткой, и комменты там вообще не проверяются.
#453 #513543
>>513540
Всё возможно, ты сайт то скинь и код элемента кнопки.
#454 #513545
>>513540
Если в бэкенде проверки на принадлежность к европкам нет, то элементарно обходится, достаточно код странички подправить.
38 Кб, 951x155
8 Кб, 330x108
#455 #513548
>>513543
interpals.com
Написан он очень криво, сейчас при частом обновлении он мне на профиль накинул метку, мол, я не могу этому пользователю писать.
Отправляет он коммент формой.
pid - id фотки.
uid - user id (он подставляется после отправки запроса)
aid - так и не понял что это. Возможно какой-то action id.
Остальные поля, думаю, понятно.
#456 #513549
В общем, суть я понял, подставить id её фотки и попробовать достучаться.
Щя проверю на других страницах action id.
#457 #513552
>>513548

>2 пик


Стоп, но это параметры, которые летят на BE. это получается, что uid подставляется ещё до отправки. И если нет валидации, можно под любым пользователем писать что хочешь?!
#458 #513553
>>513552
Вангую, там cookies и session.
6 Кб, 200x200
#459 #513563
ОП, я еле нашел ответ на задачу про школьника и айфоны, https://ideone.com/TJopCN

Я себе чуть очко не порвал когда понял что ошибкой было вместо этого:
$monthlyPayment = $creditBalance; (правильно)
вот эта хуета:
$creditBalance = $monthlyPayment;

я сидел весь день над этим, чувствую себя макакой
#460 #513565
>>513563
Ты серьезно? Я ее в голове решил за 30 секунд. На худой конец можно было дамп всех переменных на экран по очереди делать.
мимокрок
#461 #513568
>>513540
что, тяночки не дают, дрочер? съеби.
#462 #513569
>>513568
Нет. Я общаюсь с тянками из разных стран, а одна настроила себе страницу так, чтобы ей не писали из Европы. Вот у меня и появился спортивный интерес ей написать.
#463 #513570
>>513565
та хуй его знает, я не могу понять сам ход мыслей при решении подобной хуеты, уже не первый раз замечаю, а вроде и не гуманитарий...
#464 #513572
>>513570
Если понять ход не можешь, дампай все на экран по очереди, пока понятно не станет.
8 Кб, 623x80
#465 #513575
К сожалению, вываливается такое.
#466 #513578
>>513569
Думаешь она потечет, когда узнает какой ты крутой хакир?
#467 #513579
>>513578
Нет.
#468 #513580
>>513569
Даун ебучий, смени страну в профайле или сделай другой профайл с нужной страной и не еби мозг своими формами.
#469 #513581
>>513580
Слишком просто. Ладно, пойду дальше копать. Решайте дальше свои задачки.
#470 #513582
>>513581
Сменил страну, написал комент, сменил страну обратно. Тян думает, ты хакир.
#471 #513583
>>513572
спасибо, пожалуй запомню. Ато чот после кодакадеми эти задачки меня в тупик ставят...хотя я понимаю что это детский сад лол
#472 #513585
За сколько времени вы бы написали проект полностью с темплейтами и полностью своей цмс на 800 строк и собственной админкой с возможностью удалять и фиксить? И сколько бы вы за такое взяли?
#473 #513586
>>513585
это инет-магазин если что.
#474 #513587
>>513585
>>513586
знаю типа который сделал всё это, но при этом ещё и работает на постоянной основе на заказчика (обслуживание + пополнение БД и тд), в месяц ему платят около 500 уе только за обслуживание. За весь проэкт хз сколько он получил. Расценки Хохляндии
#475 #513595
>>513587
зачем обслуживание? проект под ключ.
#476 #513598
Вот написал я сайт, в котором используется база данных, хочу разметить его на бесплатном хостинге, как это сделать? Сделать дамп базы данных и закинуть файлы сайта в архив и загрузить по фтп?
#477 #513604
>>513585

>цмс на 800 строк


Это что за недоцмс такая?
#478 #513606
>>513585
Если вообще без всего, одни темплейты и удалялка/редактилка, то неделю и 500 баксов. Если со стандартными фичами, то недели 2 и тысяча баксов. Ну и дальше в таком же духе в зависимости от количества нужных фич.
#479 #513609
Вечер в тред, анончики. Прошу проверить:
http://ideone.com/UZ70da и http://ideone.com/7v0UOe - 2 решения задачи про палиндромы;

http://ideone.com/lxGzZj - задача про айпад в кредит;

http://ideone.com/LI0fa0 - первая задача из урока про регулярные выражения. Встрял со второй, не понимаю.
Вот тут типа черновик http://ideone.com/jzZqix.

Как я думаю - проверку ошибок, чтобы выводить с куском текста, надо делать через preg_match. Но я вот не понимаю, я хочу вывести в массив ошибок каждое из этих слов:
$regexp = '/(Сдесь)|(зделан)|(зделаю)/';
Но в массиве у меня остается только первое слово - "Сдесь". Что я делаю не так?
#480 #513614
>>513272

Все же твой пример плох, так как содержит много ошибок и недоработок и не учит.

А если тебе нужна готовая библиотека лучше брать Guzzle или Buzz или что-нибудь еще с нормальным API а не функцию с 10 параметрами без проверки правильности и непонятно как их передавать. Этим ты экономишь свое время на отладку и разработку. Велосипеды не нужны.

> curl_setopt($ch, CURLOPT_SSLCERTPASSWD,'certpass');


Зачем нужен пароль для набора корневых сертификатов? Ты напутал что-то.

Для HTTPS тебе не нужен свой сертификат с приватным ключем, тебе просто нужен пак корневых сертификатов, например от мозиллы.

Вот комментарий про то как их устанавливать: http://php.net/manual/ru/function.curl-setopt.php#110457

>>А если не массив?


> Очевидно что if не сработает, не?


В таком случае надо не притворяться что все в порядке, а выбросить исключение, иначе как программист узнает об ошибке?

>>Также нет проверки результата.


> Не в этой функции это надо делать


Как минимум надо курловские ошибки обрабатывать, да и всякие 404 тоже желательно бы. Для этого стоит конечно переделать дизайн функции, может исключения выбрасывать.

>>Код плохой. Это лучше сделать...


> Ты уж покажи тогда как сделать хорошо,


Если дял практических целей, взять готовую библиотеку. Если для изучения курла, тут удоюбно применить ООП и сделать методы для задания редкоиспользуемых опций. Вроде такого:

$client = new HttpClient;
$client->setSomeOption(....);
$response = $client->get('http://exxample.com');
// здесь как ты видишь есть подвох в том, что если мы возщвращаем тело страницы то непонятно как получить заголовки, тип ответа, статус ошибки и тд. Нормальные библиотеки решают эту проблему, возвращая не строку, а объект Response. Так что стоит написать еще класс Response, причем для хранения информации о HTTP ответе есть и интерфейс в PSR: http://www.php-fig.org/psr/psr-7/#3-3-psr-http-message-responseinterface

$page = $client->post(....);

// для удобства можно добавить методы-обертки, делающие проверки результата, типа, кода ответа и возвращающие сразу HTML:

$html = $client->getHtmlPage('http://...');
#480 #513614
>>513272

Все же твой пример плох, так как содержит много ошибок и недоработок и не учит.

А если тебе нужна готовая библиотека лучше брать Guzzle или Buzz или что-нибудь еще с нормальным API а не функцию с 10 параметрами без проверки правильности и непонятно как их передавать. Этим ты экономишь свое время на отладку и разработку. Велосипеды не нужны.

> curl_setopt($ch, CURLOPT_SSLCERTPASSWD,'certpass');


Зачем нужен пароль для набора корневых сертификатов? Ты напутал что-то.

Для HTTPS тебе не нужен свой сертификат с приватным ключем, тебе просто нужен пак корневых сертификатов, например от мозиллы.

Вот комментарий про то как их устанавливать: http://php.net/manual/ru/function.curl-setopt.php#110457

>>А если не массив?


> Очевидно что if не сработает, не?


В таком случае надо не притворяться что все в порядке, а выбросить исключение, иначе как программист узнает об ошибке?

>>Также нет проверки результата.


> Не в этой функции это надо делать


Как минимум надо курловские ошибки обрабатывать, да и всякие 404 тоже желательно бы. Для этого стоит конечно переделать дизайн функции, может исключения выбрасывать.

>>Код плохой. Это лучше сделать...


> Ты уж покажи тогда как сделать хорошо,


Если дял практических целей, взять готовую библиотеку. Если для изучения курла, тут удоюбно применить ООП и сделать методы для задания редкоиспользуемых опций. Вроде такого:

$client = new HttpClient;
$client->setSomeOption(....);
$response = $client->get('http://exxample.com');
// здесь как ты видишь есть подвох в том, что если мы возщвращаем тело страницы то непонятно как получить заголовки, тип ответа, статус ошибки и тд. Нормальные библиотеки решают эту проблему, возвращая не строку, а объект Response. Так что стоит написать еще класс Response, причем для хранения информации о HTTP ответе есть и интерфейс в PSR: http://www.php-fig.org/psr/psr-7/#3-3-psr-http-message-responseinterface

$page = $client->post(....);

// для удобства можно добавить методы-обертки, делающие проверки результата, типа, кода ответа и возвращающие сразу HTML:

$html = $client->getHtmlPage('http://...');
#481 #513616
>>513379

Посмотри ошибки внизу, их надо исправить.

> PHP Warning: Missing argument 3 for credit(), called in /home/5LpEvn/prog.php on line 23 and defined in /home/5LpEvn/prog.php on line 5


Ты передал меньше аргументов в функцию чем требуется.

> PHP Notice: Undefined variable: fee in /home/5LpEvn/prog.php on line 6


Обращение к несуществующей (потому что ты ее не передал) переменной.

> \tif ($creditBalance < 0) {


> $paymentTotal = $paymentTotal - $creditBalance;


Это явно неправильно. Ведь если ты вычитаешь отрицательное число то paymentTotal становится больше. ну например:

5000 - (-1000) = 6000

Арифметику школьную забыл?

Решил ли ты задачу про айфон, с одним банком? Я вижу что не решил.

Надо смотреть чему равен остаток долга и обрабатывать ситуацию, когда он маленький, а не выплачивать сразу же 5000 вот в этом месте: ... + $servicePayment - $payOut;

Попробуй переписать код внутри цикла примерно так:

- прибавляем проценты и комиссию к остатку долга
- если остаток маленький, выплачиваем сколько осталось и уходим
- иначе платим 5000

Ответ во втором банке должен быть около 61270.
#481 #513616
>>513379

Посмотри ошибки внизу, их надо исправить.

> PHP Warning: Missing argument 3 for credit(), called in /home/5LpEvn/prog.php on line 23 and defined in /home/5LpEvn/prog.php on line 5


Ты передал меньше аргументов в функцию чем требуется.

> PHP Notice: Undefined variable: fee in /home/5LpEvn/prog.php on line 6


Обращение к несуществующей (потому что ты ее не передал) переменной.

> \tif ($creditBalance < 0) {


> $paymentTotal = $paymentTotal - $creditBalance;


Это явно неправильно. Ведь если ты вычитаешь отрицательное число то paymentTotal становится больше. ну например:

5000 - (-1000) = 6000

Арифметику школьную забыл?

Решил ли ты задачу про айфон, с одним банком? Я вижу что не решил.

Надо смотреть чему равен остаток долга и обрабатывать ситуацию, когда он маленький, а не выплачивать сразу же 5000 вот в этом месте: ... + $servicePayment - $payOut;

Попробуй переписать код внутри цикла примерно так:

- прибавляем проценты и комиссию к остатку долга
- если остаток маленький, выплачиваем сколько осталось и уходим
- иначе платим 5000

Ответ во втором банке должен быть около 61270.
#482 #513618
>>513404

> member emp.Tugriki = emp.Compute (500, 400, 200, 800, 1.5)


> member emp.Koffee = emp.Compute (20, 15, 5, 50, 2.0)


это не очень дальновидный подход, что ты пытаешься вычислять кофе/тугрики/деньги по одной схеме так как нет никаких гарантий что формула общая. И понимание кода усложняется. Лучше для каждого ресурса сделать свой метод подсчета.

> type employee =


> ...


> | Boss of employee


Есть защита от Boss of Boss of Boss of Manager ?

Мне кажется, босс это не тип, а флаг так как мы можем назначать/разжаловать из него. Как ты это собрался делать?

Тут нужен именно объект (или структура или что там есть для этого) со свойствами, свойства это ранг и флаг босса. Более того, если ты хочешь писать хороший код то стоит предусмотреть возможность добавлять новые свойства (вдруг мы введем премию за выслугу лет например).

Представлять инженера как обертку над интом на мой взгляд неверно.

> static member (*) (n : int, emp : employee) = List.replicate n emp


Что за странная конструкция? Ручное копирование методов? У вас там прототипов или наследования или каких-нибудь type classes нет что ли?

Можно ли в твоем варианте добавлять профессии не трогая исходный код? С наследованием и ООП можно.

> type department =


> | Buys of employee list


На мой взгляд департамент это один тип, а название просто его свойство. А то в твоем варианте нельзя добавлять департаменты не трогая исходный код.

> ((sprintf "%A" dept)


Костыль же? Можно русское название с пробелами сделать департаменту?

Вывод данных таблицей хорошо бы отделить и вынести в отдельный универсальный модуль или как там у вас это называется.

Также, для тебя есть дополнительное задание (на самом деле я всем его даю), чтобы ты продемонстрировал гибкость языка и расширяемость твоего кода на нем:

### Антикризисные меры

Задание: напиши программу для учета расходов и результатов работы всего дружного коддектива компании «Вектор».

Пока ты решал задачу по выводу отчета о сотрудниках и департаментах, разразился мировой экономический кризис. Доходы компании начали снижаться, и совет директоров поставил перед руководством задачу принять меры. Менеджеры 3-го ранга, блестящие выпускники топовых экономических вузов столицы, быстро смогли разработать три альтернативных антикризисных решения:

1. Сократить в каждом департаменте 40% (округляя в большую сторону) инженеров, преимущественно самого низкого ранга. Если инженер является боссом, вместо него надо уволить другого инженера, не босса.

2. Увеличить в целях стимуляции умственной деятельности базовую ставку аналитика с 800 до 1100 тугриков, а количество выпиваемого им кофе с 50 до 75 литров. В тех департаментах, где руководитель не является аналитиком, заменить его на аналитика самого высшего ранга из этого департамента (а бывшего руководителя вернуть к обычной работе)

3. В каждом департаменте повысить 50% (округляя в большую сторону) менеджеров 1-го и 2-го ранга на один ранг с целью расширить их полномочия.

Совет директоров в затруднении: какой путь выбрать? Помоги им с этим, распечатав прогноз по потреблению и расходам (аналогичный тому что требуется в задаче) после принятия каждой из мер.
#482 #513618
>>513404

> member emp.Tugriki = emp.Compute (500, 400, 200, 800, 1.5)


> member emp.Koffee = emp.Compute (20, 15, 5, 50, 2.0)


это не очень дальновидный подход, что ты пытаешься вычислять кофе/тугрики/деньги по одной схеме так как нет никаких гарантий что формула общая. И понимание кода усложняется. Лучше для каждого ресурса сделать свой метод подсчета.

> type employee =


> ...


> | Boss of employee


Есть защита от Boss of Boss of Boss of Manager ?

Мне кажется, босс это не тип, а флаг так как мы можем назначать/разжаловать из него. Как ты это собрался делать?

Тут нужен именно объект (или структура или что там есть для этого) со свойствами, свойства это ранг и флаг босса. Более того, если ты хочешь писать хороший код то стоит предусмотреть возможность добавлять новые свойства (вдруг мы введем премию за выслугу лет например).

Представлять инженера как обертку над интом на мой взгляд неверно.

> static member (*) (n : int, emp : employee) = List.replicate n emp


Что за странная конструкция? Ручное копирование методов? У вас там прототипов или наследования или каких-нибудь type classes нет что ли?

Можно ли в твоем варианте добавлять профессии не трогая исходный код? С наследованием и ООП можно.

> type department =


> | Buys of employee list


На мой взгляд департамент это один тип, а название просто его свойство. А то в твоем варианте нельзя добавлять департаменты не трогая исходный код.

> ((sprintf "%A" dept)


Костыль же? Можно русское название с пробелами сделать департаменту?

Вывод данных таблицей хорошо бы отделить и вынести в отдельный универсальный модуль или как там у вас это называется.

Также, для тебя есть дополнительное задание (на самом деле я всем его даю), чтобы ты продемонстрировал гибкость языка и расширяемость твоего кода на нем:

### Антикризисные меры

Задание: напиши программу для учета расходов и результатов работы всего дружного коддектива компании «Вектор».

Пока ты решал задачу по выводу отчета о сотрудниках и департаментах, разразился мировой экономический кризис. Доходы компании начали снижаться, и совет директоров поставил перед руководством задачу принять меры. Менеджеры 3-го ранга, блестящие выпускники топовых экономических вузов столицы, быстро смогли разработать три альтернативных антикризисных решения:

1. Сократить в каждом департаменте 40% (округляя в большую сторону) инженеров, преимущественно самого низкого ранга. Если инженер является боссом, вместо него надо уволить другого инженера, не босса.

2. Увеличить в целях стимуляции умственной деятельности базовую ставку аналитика с 800 до 1100 тугриков, а количество выпиваемого им кофе с 50 до 75 литров. В тех департаментах, где руководитель не является аналитиком, заменить его на аналитика самого высшего ранга из этого департамента (а бывшего руководителя вернуть к обычной работе)

3. В каждом департаменте повысить 50% (округляя в большую сторону) менеджеров 1-го и 2-го ранга на один ранг с целью расширить их полномочия.

Совет директоров в затруднении: какой путь выбрать? Помоги им с этим, распечатав прогноз по потреблению и расходам (аналогичный тому что требуется в задаче) после принятия каждой из мер.
#483 #513621
>>513408

Два дня это если в перерыве между написанием кода смотреть аниме. Два дня это же минимум 16 часов, за которые можно гору перевернуть, не то что файлообменник сделать.

>>513414

Надо писать качественный понятный самодокументирующий код используя распространенные библиотеки и фреймворки.

>>513427
Иода

> implode($wordsInSentence, ' ');


разделитель идет первым, смотри мануал

> if (!preg_match("/;/u", $sign))


Не пропускай фигурные скобки, это либо ведет к ошибкам и ухудшению читаемости, либо кому-то придется их ставить за тебя при модификации кода.

Если у тебя есть код

if (условие) {
50 строк
} else {
2 строки
}

То его надо попробовать перевернуть, чтобы было

if (не выполняется условие) {
2 строки
} else {
50 строк
}

То есть лучше короткую ветку сделать первой.

А так, вообще, неплохо сделано, все работает.

Калькулятор

> \tcase '+': $result += (float)$number; break;


Принято писать это в 3 строки, да еще и с отступом. Я понимаю что так нагляднее но не стоит от стандарта оформления ради одног ослучая отступать.

А так, хорошо, все работает.
#483 #513621
>>513408

Два дня это если в перерыве между написанием кода смотреть аниме. Два дня это же минимум 16 часов, за которые можно гору перевернуть, не то что файлообменник сделать.

>>513414

Надо писать качественный понятный самодокументирующий код используя распространенные библиотеки и фреймворки.

>>513427
Иода

> implode($wordsInSentence, ' ');


разделитель идет первым, смотри мануал

> if (!preg_match("/;/u", $sign))


Не пропускай фигурные скобки, это либо ведет к ошибкам и ухудшению читаемости, либо кому-то придется их ставить за тебя при модификации кода.

Если у тебя есть код

if (условие) {
50 строк
} else {
2 строки
}

То его надо попробовать перевернуть, чтобы было

if (не выполняется условие) {
2 строки
} else {
50 строк
}

То есть лучше короткую ветку сделать первой.

А так, вообще, неплохо сделано, все работает.

Калькулятор

> \tcase '+': $result += (float)$number; break;


Принято писать это в 3 строки, да еще и с отступом. Я понимаю что так нагляднее но не стоит от стандарта оформления ради одног ослучая отступать.

А так, хорошо, все работает.
#484 #513626
>>513422

Ты наверно имел в виду процедурный код, функциональный это когда функции оперируют функциями, как на Хаскелле.

>>513512

Смотри лог ошибок, исправляй их.

>>513516

Это устаревшая функция, не используй ее, используй добавление автозагрузчика через spl_autoload_register. Статья: http://habrahabr.ru/post/136761/

> Как эта функция определяет какой класс надо подключить? И как она вообще его находит?


Когда ты в коде обращаешься к несуществующему классу, например:

$a = new MyClass;
MyClass::doSomething();
if (class_exists('MyClass')) {

PHP прежде чем выдать ошибку что класс не существует, вызывает зарегистрированные функции-автозагрузчики передавая им имя класса. Если одна из них подключит файл с классом то выполнение продолжится, если нет то будет ошибка.

> И как она вообще его находит?


Функция получает на вход имя класса и должна как-то определить в каком файле он находится (как именно решаешь ты). Можно например назвать файлы точно так же как и классы, добавляя в конец '.php': MyClass -> MyClass.php

Есть готовый стандарт на эту тему — PSR-4 (хотя он может быть немного сложен, но вся суть в том что имя класса и неймспейсов должно соответсвовать пути к файлу с этим классом).

Если ты будешь называть свои классы в соответствие с PSR-4 то сможешь использовать готовые автозагрузчики, например встроенный в композер.
#484 #513626
>>513422

Ты наверно имел в виду процедурный код, функциональный это когда функции оперируют функциями, как на Хаскелле.

>>513512

Смотри лог ошибок, исправляй их.

>>513516

Это устаревшая функция, не используй ее, используй добавление автозагрузчика через spl_autoload_register. Статья: http://habrahabr.ru/post/136761/

> Как эта функция определяет какой класс надо подключить? И как она вообще его находит?


Когда ты в коде обращаешься к несуществующему классу, например:

$a = new MyClass;
MyClass::doSomething();
if (class_exists('MyClass')) {

PHP прежде чем выдать ошибку что класс не существует, вызывает зарегистрированные функции-автозагрузчики передавая им имя класса. Если одна из них подключит файл с классом то выполнение продолжится, если нет то будет ошибка.

> И как она вообще его находит?


Функция получает на вход имя класса и должна как-то определить в каком файле он находится (как именно решаешь ты). Можно например назвать файлы точно так же как и классы, добавляя в конец '.php': MyClass -> MyClass.php

Есть готовый стандарт на эту тему — PSR-4 (хотя он может быть немного сложен, но вся суть в том что имя класса и неймспейсов должно соответсвовать пути к файлу с этим классом).

Если ты будешь называть свои классы в соответствие с PSR-4 то сможешь использовать готовые автозагрузчики, например встроенный в композер.
#485 #513628
>>513521

Разберись почему, смотри лог ошибок (если CMS отключает логгирование меняя error_reporting то пошли разработчикам нехороших пожеданий и включи). Можешь для удобства также включить display_errors (только не в коде, чтобы на продакшене ошиьки не вываливались на экран).

С путями, смотри какие пути выводятся и откуда они формируются, может какую настройку поменять надо.

Натыкай var_dump или смотри значения переменных отладчиком.

Что ты как маленький.

>>513525

Это не удаление все сессии а только замена значения поля admins на пустую строку.

Но сессии все равно удаляются если к ней 20-30 минут не обращаться.

> $common->re


Это 2 примера как не надо называть переменные и методы. Хорошие дети, не делайте так.

>>513530

include_path это список папок в которых ищется файл если в include/require указан относительный (не идущий от корня диска) путь. читай мануал:

http://php.net/manual/ru/function.require.php
http://php.net/manual/ru/function.set-include-path.php
http://php.net/manual/ru/ini.core.php#ini.include-path

> И как она помогает при аутолоаде, у меня выбивает ошибку.


Разберись почему ошибка. Сдампь имя переданного в автозагрузчик класса и какой файл он пытается подулючить и проанализируй что идет не так.

>>513536

Плохой совет. Анон должен сначала научиться писать автозагрузчики а потом брать готовый. Иначе ничему не научится.
#485 #513628
>>513521

Разберись почему, смотри лог ошибок (если CMS отключает логгирование меняя error_reporting то пошли разработчикам нехороших пожеданий и включи). Можешь для удобства также включить display_errors (только не в коде, чтобы на продакшене ошиьки не вываливались на экран).

С путями, смотри какие пути выводятся и откуда они формируются, может какую настройку поменять надо.

Натыкай var_dump или смотри значения переменных отладчиком.

Что ты как маленький.

>>513525

Это не удаление все сессии а только замена значения поля admins на пустую строку.

Но сессии все равно удаляются если к ней 20-30 минут не обращаться.

> $common->re


Это 2 примера как не надо называть переменные и методы. Хорошие дети, не делайте так.

>>513530

include_path это список папок в которых ищется файл если в include/require указан относительный (не идущий от корня диска) путь. читай мануал:

http://php.net/manual/ru/function.require.php
http://php.net/manual/ru/function.set-include-path.php
http://php.net/manual/ru/ini.core.php#ini.include-path

> И как она помогает при аутолоаде, у меня выбивает ошибку.


Разберись почему ошибка. Сдампь имя переданного в автозагрузчик класса и какой файл он пытается подулючить и проанализируй что идет не так.

>>513536

Плохой совет. Анон должен сначала научиться писать автозагрузчики а потом брать готовый. Иначе ничему не научится.
#486 #513631
>>513563

У вас уже готовые решения есть? Пора видимо условия задач чуть поменять для выявления списывальщиков.

>>513568

Не ругайся.

>>513583

кодеакадеми очень-очень базовый уровень, скорее просто ознакомление с языком. Решай наши задачки (все подряд) чтобы продвинуться дальше.

>>513585

Зачем писать свою CMS? Ты в своем уме? Хочешь платить за то что можно взять готовое? И при этом получить результат худшего качества?

Ты хлеб тоже сам выращиваешь и печешь или в магазине покупаешь?

>>513586

Для этого есть сотни готовых CMS. В 800 строк ты нормальный магазин не уложишь. Я думаю в 800 строк тебе сделают только страничку «о нас».

>>513595

Это вряд ли получится. Все равно надо будет что-то менять.

>>513598

Да, как вариант. Но на хостингах обычно дают пхпмайадмин и можно грузить дамп сразу в него.

Закачивать лучше гзипнутый файл, быстрее будет.

Я бы по scp скпировал и закачал в mysql, там можно даже сделать это не сохраняя на диск.

>>513606

Мне кажется за 2000 в месяц (с нынешним то курсом!) можно несколько натягивателей шаблонов на фрилансе найти. Ой, кажется я сломал твой хитрый план.
#486 #513631
>>513563

У вас уже готовые решения есть? Пора видимо условия задач чуть поменять для выявления списывальщиков.

>>513568

Не ругайся.

>>513583

кодеакадеми очень-очень базовый уровень, скорее просто ознакомление с языком. Решай наши задачки (все подряд) чтобы продвинуться дальше.

>>513585

Зачем писать свою CMS? Ты в своем уме? Хочешь платить за то что можно взять готовое? И при этом получить результат худшего качества?

Ты хлеб тоже сам выращиваешь и печешь или в магазине покупаешь?

>>513586

Для этого есть сотни готовых CMS. В 800 строк ты нормальный магазин не уложишь. Я думаю в 800 строк тебе сделают только страничку «о нас».

>>513595

Это вряд ли получится. Все равно надо будет что-то менять.

>>513598

Да, как вариант. Но на хостингах обычно дают пхпмайадмин и можно грузить дамп сразу в него.

Закачивать лучше гзипнутый файл, быстрее будет.

Я бы по scp скпировал и закачал в mysql, там можно даже сделать это не сохраняя на диск.

>>513606

Мне кажется за 2000 в месяц (с нынешним то курсом!) можно несколько натягивателей шаблонов на фрилансе найти. Ой, кажется я сломал твой хитрый план.
#487 #513637
Сайт на денвере работает нормально, использует бутстрап, все пути прописаны к разным файлам прописаны и нормально работают. Закачиваю файл на бесплатный хостинг, в итоге ничего не работает, вылазит кривой хтмл без стилей на index.html при попытке зайти на другие страницы сайта браузер их загружает, в чём дело? .htacces нет на этом сайте нет.
#488 #513638
>>513637

>при попытке зайти на другие страницы сайта браузер их загружает


Я имел ввиду браузер их СКАЧИВАЕТ как текстовые файлы
#489 #513639
Вчера при обсуждения TCP, оп скидывал книгу про tcp и работу сети в целом, напомните как называлась, пожалуйста.
#490 #513641
>>513639

>обсуждения


*обсуждении
#491 #513642
>>513609

> http://ideone.com/UZ70da



> $array[$i] = $letter;


для добавления элемента в конец лучше писать просто $letters[] = ...

Название array не годится, оно ничего не говорит.

> $letter = mb_substr($text, $i, 1);


> $array[$i] = $letter;


Это лучше писать в 1 строку без лишней переменной.

> for ($i=$letters; $i > -1 ; $i--) {


> $comparisson = $comparisson . $array[$i];


Есть функции array_reverse и implode, цикл не нужен, погугли мануал.

Кстати для разбиения на буквы тоже есть хак с preg_split, где-то в учебнике в главе про строки описан.

Алгоритм правильный.

> http://ideone.com/7v0UOe



> $lenght-1-$i


Можно писать просто -$i - 1, отрицательные числа отситываются с конца строки.

Алгоритм верный.

> задача про айпад в кредит;



> for($i = 0; $credit > 0; $i++){


Если ты не используешь $i то можно ее не писать:

for( ; $credit > 0; ){

А можно вообще заменить это на цикл «повторять пока»:

while ($credit > 0) {
...
}

Мануал http://php.net/manual/ru/control-structures.while.php

> $mountPercent = round(($credit + $comission) * $percent/100, 2);


> $credit = $credit + $mountPercent + $comission;


Можно наверно упростить, умножая долг на (100 + процент) / 100

> $totalPay = $totalPay + $mountPay;


Тут можно использовать +=

А так, решено правильно.
#491 #513642
>>513609

> http://ideone.com/UZ70da



> $array[$i] = $letter;


для добавления элемента в конец лучше писать просто $letters[] = ...

Название array не годится, оно ничего не говорит.

> $letter = mb_substr($text, $i, 1);


> $array[$i] = $letter;


Это лучше писать в 1 строку без лишней переменной.

> for ($i=$letters; $i > -1 ; $i--) {


> $comparisson = $comparisson . $array[$i];


Есть функции array_reverse и implode, цикл не нужен, погугли мануал.

Кстати для разбиения на буквы тоже есть хак с preg_split, где-то в учебнике в главе про строки описан.

Алгоритм правильный.

> http://ideone.com/7v0UOe



> $lenght-1-$i


Можно писать просто -$i - 1, отрицательные числа отситываются с конца строки.

Алгоритм верный.

> задача про айпад в кредит;



> for($i = 0; $credit > 0; $i++){


Если ты не используешь $i то можно ее не писать:

for( ; $credit > 0; ){

А можно вообще заменить это на цикл «повторять пока»:

while ($credit > 0) {
...
}

Мануал http://php.net/manual/ru/control-structures.while.php

> $mountPercent = round(($credit + $comission) * $percent/100, 2);


> $credit = $credit + $mountPercent + $comission;


Можно наверно упростить, умножая долг на (100 + процент) / 100

> $totalPay = $totalPay + $mountPay;


Тут можно использовать +=

А так, решено правильно.
#492 #513644
>>513609

> первая задача из урока про регулярные выражения


Регулярка слишком сложная, надо сдеать проще, по принципу «10 цифр и любое число дефисов/пробелов/скобко между ними»

Также задачу про номера телефонов надо проверить на большом числе телефонов, чтобы убедиться что твой код правильный. Но руками подставлять номера — долго и скучно. Пусть работает робот, а не человек!

Для этого давай добавим в программу тесты, чтобы сразу было видно, верно все работает или нет. Сделай 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_match


preg_match ищет только первое совпадение, а тебе нужны все и значит функция preg_match_all которая где-то в уроке в конце описана.
#493 #513645
>>513639

Не ОП, а кто-то другой упоминал книгу Олифера:

Олифер В.Г., Олифер Н.А. "Компьютерные сети. Принципы, технологии, протоколы"

По моему я тоже по ней учился.
#494 #513646
>>513645
Годная книга? Или есть что более понятное? Для саморазвития решил вникнуть в тему работы сетей
#495 #513647
Увидел в группе вконтакте видеоуроки по бустрапу. По бутстрапу!

Мне интересно, на кого они рассчитаны. на тех кто неспособен просто прочесть или пролистать документацию?

Я вообще негативно отношусь к видеоурокам. зачем они нужны? Маиериал в виде текста и картинок по моему воспринимается лучше чем на слух.

Зачем это? Вы не можете сами догадаться что открыть и что нажать? На собеседовании и на работе же вам все равно придется своей головой думать.
#496 #513659
>>513618
отлично, спасибо
#497 #513671
Аноны, все кто изучает PHP, читайте на хабре еженедельный дайджест о новостях из мира PHP: http://m.habrahabr.ru/company/zfort/blog/262401/ подписывайтесь там, ставьте лайки.

Я вот например узнал что хотят сделать типизированные энумы.
#498 #513709
>>513647

А что такого то собственно? В видеоуроках можно гораздо все подробнее рассказать и буквально показать на пальцах то, как оно все работает. В текстовом виде этого сделать невозможно, в виду его ограниченности.

А если есть возможность изучить какую-то тему более подробно, то почему бы ей не воспользоваться?
#499 #513732
голова отказывается думать, а пальцы печатают какую-то хрень, хотя все легко и в гугле полно туториалов..
#500 #513733
>>513631

>Зачем писать свою CMS? Ты в своем уме?


Допустим у заказчика очень специфичные требования к Админке. Плюс надо же это все с шаблонами и теплейтами связать.
#501 #513734
>>513606
хуяси.
#502 #513737
SELECT `book` .*, 'comments' . 'name' . 'text' FROM 'vedma_book' WHERE `id` = '".$id."' = 'comments' . 'comments_id'
$numrows = $db->n($result);
\t\t\tif($numrows>0) {
\t\t\t\t$row = mysql_fetch_array($result);
\t\t\t\techo $row['text'];
echo $row['name_comments'];
echo $row['text_comments'];
\t\t\t}

Такое запрос выведет ли циклом таблицу с внешними ключами, т.е. инфу из двух таблиц (статья и комменты)? Циклом, это важно. Родительская таблица book, дочерняя book. ключи: id = id book, id comments = id_comments.
#503 #513742
>>513237

>> if (!isset($this->$class)) {


>Вот это неправильно. Завязывай с динамиечскими свойствами, объект это не массив чтобы в него их добавлять (а если тебе нужны динамические свойства, используй лучше массив).


А что плохого в динамических свойствах? И в каких случаях они уместны?
#504 #513744
Как в php можно спарсить данные со страницы? Например, получаю я с формы адрес страницы, и надо мне с этой страницы из какого-то тега вытащить текст, подскажите как это делается?
#505 #513751
Алсо, что думаете по поводу такого запроса id - id страницы, на каждой выводится коммент.
#506 #513752
>>513751
код забыл
SELECT `vedma_book` .*, `comments` . `name_comments` . `text_comments` FROM `vedma_book` INNER JOIN `comments` ON `vedma_book`.`id` = '".$id."=`comments`.`id`

echo "<form method='post' action='".$path."index.php'><input type='text' name='name_comments'/><input type='text' name='text_comments'><button type='submit'>Оставить комментарий</button></form>";
\t\t\t$name_comments=$_POST['name_comments'];
\t\t\t$text_comments=$_POST['text_comments'];
\t\t\t$result2 = $db->q("INSERT INTO `comments` VALUES(``, ,``,`$name_comments`, `$text_comments`) WHERE `id`=".$id."");
#507 #513753
#508 #513770
И еще вопрос, что именно эта хуйня парсирует? function style_if($doc, $array) {
\t\t$ar = array_keys($array);
\t\t$coun = count($array);
\t\tfor($i=0; $i<$coun; $i++) {
\t\t\tif(strpos($doc,'<!-- IF '.$ar[$i].' -->')) {
\t\t\t\tif($array[$ar[$i]]) {
\t\t\t\t\t$doc = preg_replace('#\<!-- IF '.$ar[$i].' -->(.?)\<!-- ENDIF -->#isu', '\\1', $doc);
\t\t\t\t} else {
\t\t\t\t\t$doc = preg_replace('#\<!-- IF '.$ar[$i].' -->(.
?)\<!-- ENDIF -->#isu', '', $doc);
\t\t\t\t}
\t\t\t}
\t\t\tif(strpos($doc,'<!-- IF !'.$ar[$i].' -->')) {
\t\t\t\tif($array[$ar[$i]]) {
\t\t\t\t\t$doc = preg_replace('#\<!-- IF !'.$ar[$i].' -->(.?)\<!-- ENDIF -->#isu', '', $doc);
\t\t\t\t} else {
\t\t\t\t\t$doc = preg_replace('#\<!-- IF !'.$ar[$i].' -->(.
?)\<!-- ENDIF -->#isu', '\\1', $doc);
\t\t\t\t}
\t\t\t}
\t\t}
\t\treturn $doc;
\t}
#509 #513772
class style {
\tfunction style_tpl($tpl, $array) {
\t\tglobal $style;
\t\t$doc1 = fopen('templates/tpl/'.$tpl, "r");
\t\t$doc = fread($doc1, filesize('templates/tpl/'.$tpl));
\t\tfclose($doc1);
\t\t$doc = $style->style_if($doc, $array);
\t\t$doc = $style->style_begin($doc, $array);
\t\t$doc = $style->style_for($doc, $array);
\t\t$doc = $style->style_const($doc, $array);
\t\treturn $doc;
\t}

берет ли она всю инфу из tpl или какую-то определенную хуйню, минуя дописанные дивы?
#510 #513775
https://github.com/V3N0m21/Uppu3
Исправил загрузку через имя ссылки, все оказалось в разы проще чем я думал в самом начале

Сделал загрузку mediaInfo через json_array в Доктрине, это походу не совсем то что ты имел в виду ОП, но я что-то не разобрался как нужно было сделать правильно
#511 #513778
Что при регистрации/логине сохранять в куки?
Или достаточно просто повесить $_COOKIE['login'] = '1'?
Может ли "злоумышленник" подделать куки и записать туда значение?

Или лучше сохранять в куки хешированный пароль, а потом сверять с базой каждый раз при запросе?
#512 #513786
>>513778
Да, походу нужно сохранять в куки хеш и id.
#513 #513814
>>513778
Вкачусь в тред дебилов.

>$_COOKIE['login'] = '1


Слишком толсто.

Используй фреймворк с реализованной из коробки авторизацией и аутентификацией, там будет таблица сессий, нормальная шифровка паролей, етс... Или ищи standalone php-библиотеки качественные.
#514 #513821
>>513814
Выкатывайся обратно.
Это учебный тред, мы тут учимся пониманию, как реализуется тот или иной функционал, а не используем обезьяньи готовые решения.
Если ты используешь фреймворк, но не понимаешь как он работает, то ты макака, а не программист.
#515 #513822
>>513265

>https://github.com/slimphp/Slim/blob/2.x/Slim/Helper/Set.php


>https://github.com/silexphp/Pimple/blob/master/src/Pimple/Container.php


Код контейнера в Slim для меня выглядит понятней. Непонятно только, зачем эта функция: https://github.com/slimphp/Slim/blob/2.x/Slim/Helper/Set.php#L62

А мой di-контейнер теперь выглядит так:
https://github.com/blackberryJam/abiturients/blob/master/app/classes/Container.php
Не такой гибкий, как в Slim и Silex.
#516 #513825
Посоны, меня отовсюду гонят ссыными тряпками, а тут я так понимаю самое место для новичка. PHP пока не изучаю, хочу для начала освоить фронт-энд.
Прохожу курсы htmlacademy по html и css, потом уже думаю за js взяться, и только потом за php.

Как вы мотивируетесь учиться? Я успешно прошел 5 курсов основ, вроде все просто, все понял, все запомнил, пора бы идти дальше, но что-то никак. Сажусь за комп, чтобы учиться, но какой-то стопор нападает и ничего в голову не лезет. Заставляй, не заставляй, не помогает. Как замотивироваться? Сиже у мамки на шее, хочу слезть, но видимо пока в зоне комфорта нахожусь, мозг ничего не хочет менять. Что делать?
#517 #513828
>>513825
Очевидно выйти из зоны комфорта.
Устройся на пару месяцев работать в какое-нибудь гнусное место, типа продавца в фокстроте, офигей от осознания, что если не будешь учиться, то проживешь так всю жизнь.
Мотивация появится, гарантирую.

>меня отовсюду гонят ссыными тряпками


Кажется, я понимаю почему.
482 Кб, 1366x739
#518 #513854
>>513646
Нет, для саморазвития лучше "Основы компьютерных сетей" тех же авторов, семейства Олифер.
Там все излагается гораздо более кратко и доступно. "Компьютерные сети" для гиков, "Основы" для нубов. Сами аффтары тралят в предисловии, говорят мол для ниасиляторов выпускаем лайт-версию, пикрелейтед.
#519 #513866
>>513825
Лол, описал мою стори 1в1, толко я с тян живу в ее квартире в ДС и она меня обеспечивает, я только изредка подрабатываю на всяки-разных шабашках. Тоже грозится выгнать, если работу не найду. Тоже по htmlacademy занимаюсь, думаю куда попробовать стажером-верстальщиком за еду на первое время попробовать устроится. Но пока везде отказывают, даже контентщиком не хотят брать. От этого мотивация совсем испаряется, думаю появится, когда тян меня на мороз выкинет.
192 Кб, 1400x452
#520 #513883
Как же неудобно нажимать эти стрелочки курсора.
Я уже набираю не глядя на клавиатуру, запомнил почти все хоткеи саблайма, но дурацкие стрелочки все портят, приходится отвлекаться и смотреть на клаву.
У меня еще ноут неудобный, у него стрелки как на пике.
Слышал, что в саблайме есть какой-то Vintage Mode, где можно переключаться в режим вставки, как в линуксовых редакторах. http://habrahabr.ru/post/193176/
Как оно, долго осваивается? ОП, я знаю ты кодишь в саблайме. Пользуешься этой хренью, или тыкаешь на стрелочки? Может там есть другие настройки, не хочу я еще вим учить в придачу (все равно придется, но пока рано я считаю).
#521 #513891
>>513883
Зоракс еще рекомендует изимоушн.
https://www.youtube.com/watch?v=6OIBxzgLNFE
#522 #513911
>>513866
Ебать ты лох.
#523 #513962
И почему, когда код на вк. апи при добавлении виджета комментов не генерируется, блеать.
#524 #513963
>>513866
представляю, какая она уебище.
#525 #513964
>>513828
можно копирайтером еще годик поработать.
31 Кб, 873x469
#526 #513965
>>513963
Тян 8 из 10, правда сисек почти нет и от хламидий лечится.

Тем временем завершил 4-ый курс на htmlacademy. Перехожу наконец к таблицам, надеюсь наконец разберусь почему верстка div'ами лучше табличной. Помню в школе все таблицами хуярил и был доволен.
#527 #513966
>>513965

>и от хламидий лечится.


ясно, кем работает.
#528 #513967
>>513964
Ну это уж совсем зашквар, тем более я очень херово пишу. Не умею свои мысли на бумаге хорошо выражать и все тут.
#529 #513968
>>513966
Бухгалтером. Хламидии от бывшего остались. Вместе переживаем. Зато трахаться не нужно, не очень это люблю.
#530 #513973
>>513968
Ясно быдло, версткатред в воркаче - съеби туда мразь тупая.
#531 #513976
>>513973
Добра, за наводку. Искал там, но не нашел. Перекатываюсь.
#532 #513979
привет мальчики, я тян :з
научите меня программировать на компьютере, позязя =)))
#533 #513994
>>513979
Сперва асечку писечку :3333
#534 #514016
Я так и не понял, как проверять имейл регулярными выражениями?
По одной ссылке от опа нечитабельные регекспы по 3 строки http://habrahabr.ru/post/55820/
По второй ссылке аффтар говорит "ни парьтесь))" и предлагает использовать /@/ либо /.+@.+/, то есть лишь бы была собачка.
http://habrahabr.ru/post/175375/
Самым правильным кажется действительно высылать юзеру письмо со ссылкой, перейдя по которой его данные будут подтверждены.
#535 #514022
>>514016
Собачка только и есть теперь. Сейчас кучу доменов же новых ввели, плюс многоязычные url. Если как в хабрапосте делать, часть юзеров тупо зарегаться не сможет.
#536 #514028
>>514022
Так под /.+@.+/ подойдет любая галиматья, в том числе куча собачек 'abc@@@@hello.world'

Ладно, пока просто исключу пробелы и лишние собачки
$regExp = '/^[^@\s]+@[^@\s]+\.[^@\s]+$/ui';
#537 #514034
>>514028
Множественные собачки тоже разрешены http://tools.ietf.org/html/rfc5322#section-3.2.1
Валидный емайл может быть типа "vanka@erohin"@быдло.рф
#538 #514036
Что лучше использовать while или for? Честно говоря, не вижу разницы. Мне удобнее юзать второе.
#539 #514040
>>514036
Do while . Сначала делай, потом думай
#540 #514041
>>514028
Пробелы тоже разрешены "vanka@erohin ebashit ebalo"@быдло.рф
#541 #514042
>>514036
Где постоянно крутиться будет и неизвестно сколько циклов, юзаю while.
Где заранее известно, сколько циклов, юзаю for.
#542 #514043
>>513979
Да и меня заодно, я тоже тян)) скайпик дать кому?))
#543 #514044
>>514043
Сиськи с сапом или иди нахуй.
#544 #514045
>>514043
И я тоже Тян, хочу уметь в программирование, ч же не та. Научите ^_^
#545 #514046
>>514036
Всегда использую foreach. Нахуй вы эти циклы крутите - не понимат
#546 #514061
Откопал видеокурсы Борисова на этом трекере, но почему-то только три уровня из четырех, если у кого есть четвертый, поделитесь, пожалуйста.

1. infomania.cc/viewtopic.php?t=3596
2. infomania.cc/viewtopic.php?t=3597
3. infomania.cc/viewtopic.php?t=3598
#547 #514064
>>514061
на nnm-club есть, разных годов, разного качества

И четвертый курс кстати отстой. Там намешано бессвязной информации, все подряд, лишь бы набрать время: паттерны, отражения, curl, обзор фреймворков и т.д.
#548 #514065
>>514064

Reflection не стоит переводить на русский, ибо никто не поймет о чем речь.
#549 #514068
>>514065
Ну там и рассчитано на обзор видимо, так как все это подробно разбирать оч долго. Предполагается, что ты дальше сам
#550 #514070
>>514068
У меня есть 2: старый и новый, но оба не полностью
#551 #514225
Как устроиться пхп-макакой? Я знаю пхп, но жс и верстку не знаю, я хочу быть только бекэнд-пхп макакой.
#552 #514247
>>514225
Освоить какой-нибудь фреймворк, можно сразу с symfony, всё остальное будет проще даваться, потом понять что такое REST и как должен выглядеть адеквакватный REST, чтобы фронтендер не блювал при работе с ним. Всё, ты бэкенд-пхп макака со знаниями чуть выше нулевых.
#553 #514248
Аноны, я тут обнаружил кое-что интересное (с точки зрения интерфейсов) в Хроме. Откройте несколько вкладок, затем щелкните правой кнопкой мыши на заголовок средней вкладки. Откроется меню, и там будет среди прочего 2 пункта:

Закрыть все вкладки справа
Закрыть остальные вкладки

Если навести мышь на эти пункты, то упомянутые в них заголовки вкладок наинают мигать. Мигать! Кому-то в гугле было не лень добавить обработчик события наведения мыши на этот пункт и написать код отвечающий за мигание вкладок.

Мне нравится когда люди подходят к разработке программ так тщательно и внимательно. Это не руби и нодошкольники, которые лепят код который хорошо если хоть иногда работает.

Жаль правда, все это делается не ради того чтобы сделать лучший браузер, а ради усиления монополии гугла и привязки людей к его сервисам.
#554 #514252
>>514248
Linux Mint
DE: XCFE
такой фичи не обнаружено.
#555 #514297
>>510035
Пиздец рано мне еще на фриланс вкатываться. Поделаю лучше задачки у ОПа, напишу свою цмску..
#556 #514320
Что такое фреймворк языком человека с улицы и почему их не любят?
#557 #514326
>>514320
Каркас приложения.
Не знаю, с чего ты взял, что их не любят. Может, перепутал с CMS?
#558 #514343
>>514326
>>514326
Что значит - каркас? Каркас как оболочка приложения? Графическая или техническая? Или как нечто, в который тебе нужно вписать нужный тебе код?
Не знаю, на хабре прочитал. А почему не любят цмс?
#559 #514351
>>514252
Я на ксубунту: мигает, если присмотреться. Но не сразу, и еле заметно.
Ерунда по-моему, но оп имел ввиду дотошность программистов, которые уделили внимание даже такой мелочи.
#560 #514377
Попытался этот кривожопый прожект с фл.ру натянуть на вордпресс, у меня аж интернет ахуел и перестал работать.
#561 #514378
>>514343
Потому что хуй пофиксишь это говно под хотелки заказчика.
#562 #514387
>>514343
Фреймворки это код, готовый для повторного использования.
Например на каждом сайте есть формы регистрации, вывод записей, сохранение в базу данных и так далее.
Чтобы не писать каждый раз одно и то же, подобный повторяющийся код сохраняют в отдельные пакеты, и затем используют эти готовые классы, вместо того чтобы писать с нуля.

Cms это программки, которые генерируют однотипные сайты. Выбираешь галочками или из выпадающего списка опции и нажимаешь "создать". И "оно само" тебе делает рабочий сайт.
Cms не любят по причине того, что они заточены именно под какие-то стандартные сайты, и не всегда удобно что-то изменить, дописать.
И они плохо развиваются, используют устаревшие технологии.
#563 #514388
>>514248
Опера 30, пункты есть, но ничего не мигает.
#564 #514389
>>514388
Переходи на Хром.
29 Кб, 367x367
#565 #514394
Подскажите, котаны, развернуто за ДЕЦИМАЛ в сикуэле. Что означает ДЕЦ(5,2)? Что означает 5? 2 - понятно, количество цифр после запятой, а 5? Какая нахуй точность, меня доебали ваши справочники, нaписанные мудаками для мудаков без номарльных объяснений, которыe вы с маниакальным упорством копируетe друг у друга, ща возбужусь, все в флоат пихать буду Что за точность такая? Почему чтобы 3.999 в базу лягло именно как 3.999 нужно поставить ДЕЦ(6,3), опять таки с тройкой вроде ясно, а вот при чем тут 6 нет.
#566 #514395
>>514389
Если я перейду на хром точно будеть мигать?
#567 #514399
>>514248
>>514388
В хроме под убунтой мигуют, но нахуя? Свистелка для тех, кто сам не понимает, что хочет сделать? Клево, че.
#568 #514401
>>514387
как же я ненавижу цмс, проще с нуля админку самому написать.
#569 #514408
>>514395
Атвичяю. У меня на бубунте мигает.
#570 #514410
>>514394
ДЕЦ(6,3) - 3 знака после запятой, 3 знака до запятой. Поэтому всего 6.
ДЕЦ(20,6) - 14 знаков до запятой, 6 знаков после запятой. Всего 20.
#571 #514411
>>514410
А сама запятая не считается что ли?
#572 #514416
>>514411
Считается, просто на группы делится по ней. В ДЕЦ(20,6) - хранится 9 знаков в 4х байтах, 5 знаков в 3х байтах (это все до запятой) и 6 знаков в 3х байтах (часть после запятой).
17 Кб, 360x288
#573 #514422
>>514410
Спасибо.
#574 #514433
Какой же codeception пока сырой. Я уже и модули к нему пишу, и разные костыли придумываю, но он не сдается. Сегодня решил обновить до 2.1 (в надежде что там можно пропускать тесты по if) и что? Тесты перестали вообще работать, падает исключение.

Но другого-то у нас нет, так что попью чаю и сяду исправлять.
#575 #514438
>>514433
Очередная модная поебень от хипстеров?
#576 #514452
>>513737

Нет, с чего бы это? Я советую не гадать, а почитать про джойны в любом учебнике по SQL или в туториале: http://jtest.ru/bazyi-dannyix/sql-dlya-nachinayushhix-chast-3.html

>>513742

да почти никогда не уместны. Объект тем и отличатся что у него заранее известный набор свойств. Если тебе надо добавлять свойства то бери массив а не объект.

Динамические свойства — верный путь в быдлокодеры.

>>513744

Это долго объяснять. Тебе нужна библиотека для скачивания страницы и библиотека для разбора DOM.

>>513752

У тебя код просит улучшения:

— не подставляй переменные в запрос, используй плейсхолдеры
— не смешивай логику по выборке данных и HTMl код в одном файле
— не используй echo для вывода HTML
— научись правильно работать с формами, например у меня есть урок по теме https://github.com/codedokode/pasta/blob/master/forms.md

Тебе рановато пока такие вещи писать, я бы советовал начать с нашего задания про список студентов. Там подробные комментарии к заданию.
#577 #514470
>>513770

Это самописный шабонизатор — один из лучших способов подложить свинью тем, кто работает с кодом после тебя (ну в данном случае подложили тебе).

>>513775

Правильно сделать свой тип который преобразует данные между объектом класса MediaInfo и строкой с JSON данными. Я же вроде даже давал ссылку на мануал:

http://doctrine-orm.readthedocs.org/en/latest/cookbook/custom-mapping-types.html

У тебя сделано непраивльно. У тебя при загрузке из БД получится не объект MediaInfo а массив или какой-нибудь StdClass (который по сути тот же масссов только без функций для работы с ним).

Также, вот это:

> https://github.com/V3N0m21/Uppu3/blob/master/app/Resource/FileResource.php#L88


Стоит вынести наружу из модели. Это не ее задача, анализировать типы файлов.

папку .idea надо убрать из репозитория и добавить в gitignore

> if ($bytes >= 1073741824)


Это лучше писать как 1024×1024×1024 а то какое-то магиеское число получилось.

> https://github.com/V3N0m21/Uppu3/blob/master/app/Helper/Resize.php#L13


> throw new Exception("File not an image", 1);


В сообщение об ошибке стоит добавлять имя файла, иначе наткнувшись на него в логе ничего не понять.

> https://github.com/V3N0m21/Uppu3/blob/master/app/Helper/Resize.php#L28


> $this->mime = $img['mime'];


getimagesize может вернуть false, надо это проверять

При ресайзе маленькие картинки не увеличиваются? ЧТо-то я не вижу проверки на это.

> https://github.com/V3N0m21/Uppu3/blob/master/app/bootstrap.php#L8


> $config->setQueryCacheImpl(new \Doctrine\Common\Cache\ApcCache());


Стоит сделать проверку на наличие apc и при отсуствии откатываться на файловый кеш

Имена и пароли к базе данных надо вынести в конфиг.

> https://github.com/V3N0m21/Uppu3/blob/master/app/templates/layout.html#L6


> {{ app.request.getRootUri() }}../css/bootstrap.min.css


Что-то это странно. Зачем тут две точки? Мне кажется сразу должен идти путь. Что у тебя выдает getRootUri() ?

Также, чтобы не копипастить стоит поместить этот путь в переменную.

> {% if helper.isPicture(file.extension) == true %}


Можно просто {% if helper.isPicture(file.extension) %}

> https://github.com/V3N0m21/Uppu3/blob/master/app/templates/view.html#L4


> {% if helper.isPicture(file.extension) == true %}


То-то мне эта проверка кажется ненадежной. Лучше бы записывать для файла флаг, есть у него картинка или нет. Ведь тип файла может определиться как картинка, но она окажется нечитаемой.

> https://github.com/V3N0m21/Uppu3/blob/master/files.sql#L31


> `name` varchar(255) DEFAULT NULL,


Почему DEFAULT NULL? МОжно не заполнять это поле?

Код загрузки файла стоит вынести из index.php и модели в какую-нибудь функцию или класс.

> https://github.com/V3N0m21/Uppu3/blob/master/public/index.php#L49


> $message = 'File was successfully uploaded';


переменная никуда не идет

> https://github.com/V3N0m21/Uppu3/blob/master/public/index.php#L74


>$name = FormatHelper::formatDownloadFile($id, $file->getName());


Ты переиспользуешь переменную для другой цели и это запутывает код. Я думал name это то что пришло от пользователя.

> https://github.com/V3N0m21/Uppu3/blob/master/public/index.php#L92


> ->createQuery('SELECT g FROM Uppu3\Resource\FileResource g ORDER BY g.uploaded DESC')


Тут надо добавить setMaxResults для ограничения числа файлов

Кстати для простой выборки без условий можно использовать

$files = $repository->findBy([], ['name' => 'ASC'], ...)

По моему там же и LIMIT можно задать: http://www.doctrine-project.org/api/orm/2.2/class-Doctrine.ORM.EntityRepository.html#_findBy

Вообще, пока неплохо. Сделашь древовидные комментарии? Там для доктрины есть расширение для работы с деревьями, было бы неплохо и с ним разобраться. Вот оно: https://github.com/Atlantic18/DoctrineExtensions

(тебе нужно Tree)

Вот урок про способы хранить древовидные данные в БД: https://gist.github.com/codedokode/10539720
#577 #514470
>>513770

Это самописный шабонизатор — один из лучших способов подложить свинью тем, кто работает с кодом после тебя (ну в данном случае подложили тебе).

>>513775

Правильно сделать свой тип который преобразует данные между объектом класса MediaInfo и строкой с JSON данными. Я же вроде даже давал ссылку на мануал:

http://doctrine-orm.readthedocs.org/en/latest/cookbook/custom-mapping-types.html

У тебя сделано непраивльно. У тебя при загрузке из БД получится не объект MediaInfo а массив или какой-нибудь StdClass (который по сути тот же масссов только без функций для работы с ним).

Также, вот это:

> https://github.com/V3N0m21/Uppu3/blob/master/app/Resource/FileResource.php#L88


Стоит вынести наружу из модели. Это не ее задача, анализировать типы файлов.

папку .idea надо убрать из репозитория и добавить в gitignore

> if ($bytes >= 1073741824)


Это лучше писать как 1024×1024×1024 а то какое-то магиеское число получилось.

> https://github.com/V3N0m21/Uppu3/blob/master/app/Helper/Resize.php#L13


> throw new Exception("File not an image", 1);


В сообщение об ошибке стоит добавлять имя файла, иначе наткнувшись на него в логе ничего не понять.

> https://github.com/V3N0m21/Uppu3/blob/master/app/Helper/Resize.php#L28


> $this->mime = $img['mime'];


getimagesize может вернуть false, надо это проверять

При ресайзе маленькие картинки не увеличиваются? ЧТо-то я не вижу проверки на это.

> https://github.com/V3N0m21/Uppu3/blob/master/app/bootstrap.php#L8


> $config->setQueryCacheImpl(new \Doctrine\Common\Cache\ApcCache());


Стоит сделать проверку на наличие apc и при отсуствии откатываться на файловый кеш

Имена и пароли к базе данных надо вынести в конфиг.

> https://github.com/V3N0m21/Uppu3/blob/master/app/templates/layout.html#L6


> {{ app.request.getRootUri() }}../css/bootstrap.min.css


Что-то это странно. Зачем тут две точки? Мне кажется сразу должен идти путь. Что у тебя выдает getRootUri() ?

Также, чтобы не копипастить стоит поместить этот путь в переменную.

> {% if helper.isPicture(file.extension) == true %}


Можно просто {% if helper.isPicture(file.extension) %}

> https://github.com/V3N0m21/Uppu3/blob/master/app/templates/view.html#L4


> {% if helper.isPicture(file.extension) == true %}


То-то мне эта проверка кажется ненадежной. Лучше бы записывать для файла флаг, есть у него картинка или нет. Ведь тип файла может определиться как картинка, но она окажется нечитаемой.

> https://github.com/V3N0m21/Uppu3/blob/master/files.sql#L31


> `name` varchar(255) DEFAULT NULL,


Почему DEFAULT NULL? МОжно не заполнять это поле?

Код загрузки файла стоит вынести из index.php и модели в какую-нибудь функцию или класс.

> https://github.com/V3N0m21/Uppu3/blob/master/public/index.php#L49


> $message = 'File was successfully uploaded';


переменная никуда не идет

> https://github.com/V3N0m21/Uppu3/blob/master/public/index.php#L74


>$name = FormatHelper::formatDownloadFile($id, $file->getName());


Ты переиспользуешь переменную для другой цели и это запутывает код. Я думал name это то что пришло от пользователя.

> https://github.com/V3N0m21/Uppu3/blob/master/public/index.php#L92


> ->createQuery('SELECT g FROM Uppu3\Resource\FileResource g ORDER BY g.uploaded DESC')


Тут надо добавить setMaxResults для ограничения числа файлов

Кстати для простой выборки без условий можно использовать

$files = $repository->findBy([], ['name' => 'ASC'], ...)

По моему там же и LIMIT можно задать: http://www.doctrine-project.org/api/orm/2.2/class-Doctrine.ORM.EntityRepository.html#_findBy

Вообще, пока неплохо. Сделашь древовидные комментарии? Там для доктрины есть расширение для работы с деревьями, было бы неплохо и с ним разобраться. Вот оно: https://github.com/Atlantic18/DoctrineExtensions

(тебе нужно Tree)

Вот урок про способы хранить древовидные данные в БД: https://gist.github.com/codedokode/10539720
#578 #514475
>>513778

> Или достаточно просто повесить $_COOKIE['login'] = '1'?


> Может ли "злоумышленник" подделать куки и записать туда значение?


Куки хранятся в браузере и с ними можно делать все что угодно. Для авторизации обычно либо используют сессию (но она умирает через полчаса неактивности) либо в куках хранят id пользователя + хеш пароля или какой-то длинный токен который не подобрать.

>>513822

> Непонятно только, зачем эта функция


Там класс Set используется не только как DI контейнер, но и для других целей вроде хранения HTTP заголовков.

Судя по комментарию

> Used in subclasses


> like \Slim\Http\Headers.



Она используется чтобы приводить их все к нижнему регистру так как имена заголовков нечувствительные к регистру. Скорее всего класс-наследник хранящий заголовки переопределяет ее, давай-ка глянем:

https://github.com/slimphp/Slim/blob/2.x/Slim/Http/Headers.php#L94

> А мой di-контейнер теперь выглядит так:



> https://github.com/blackberryJam/abiturients/blob/master/app/classes/Container.php#L26


> $this->validator = new Validator($this->abiturientsMapper);


Если вызвать getValidator самой первой то она упадет. Тут должно быть не оьращение к полю а вызов метода.

> Не такой гибкий, как в Slim и Silex.


Ну так у них на все случаи жизни а у тебя только для твоего приложения.
#578 #514475
>>513778

> Или достаточно просто повесить $_COOKIE['login'] = '1'?


> Может ли "злоумышленник" подделать куки и записать туда значение?


Куки хранятся в браузере и с ними можно делать все что угодно. Для авторизации обычно либо используют сессию (но она умирает через полчаса неактивности) либо в куках хранят id пользователя + хеш пароля или какой-то длинный токен который не подобрать.

>>513822

> Непонятно только, зачем эта функция


Там класс Set используется не только как DI контейнер, но и для других целей вроде хранения HTTP заголовков.

Судя по комментарию

> Used in subclasses


> like \Slim\Http\Headers.



Она используется чтобы приводить их все к нижнему регистру так как имена заголовков нечувствительные к регистру. Скорее всего класс-наследник хранящий заголовки переопределяет ее, давай-ка глянем:

https://github.com/slimphp/Slim/blob/2.x/Slim/Http/Headers.php#L94

> А мой di-контейнер теперь выглядит так:



> https://github.com/blackberryJam/abiturients/blob/master/app/classes/Container.php#L26


> $this->validator = new Validator($this->abiturientsMapper);


Если вызвать getValidator самой первой то она упадет. Тут должно быть не оьращение к полю а вызов метода.

> Не такой гибкий, как в Slim и Silex.


Ну так у них на все случаи жизни а у тебя только для твоего приложения.
#579 #514477
PHP-котята, помогите с задачей, пожалуйста:

https://2ch.hk/web/res/67517.html
#580 #514482
>>513883

Не знаю, я не использую, я не хочу изучать древние схемы клавиш с тех времен когда были терминалы-печатающие машинки без стрелок. На моей клавиатуре стрелки нормальные.

> не хочу я еще вим учить в придачу (все равно придется, но пока рано я считаю).


Я не учил и не собираюсь, единственная комбинация клавиш которую я знаю это :q! или как-то так, для выхода.

Режимы это зло с точки зрения юзабилити — вспомни сколько раз ты набирал текст не в той раскладке.

>>513962

Не знаю.

>>514016

Лучше той что проще.

>>514028

> Ладно, пока просто исключу пробелы и лишние собачки


Вполне подойдет

>>514034

Да, там всякие странные комбинации разрешены но мы будем считать что человек опечатался. На практике такой email наверно нигде не заработает.

>>514046

Для разных слуаев разные циклы.

>>514225

То есть ты ленив и не хочешь изучать технологии? я не думаю что это произведет впечатление на работодателя. Людив вузах по 5 лет учатся, а тебе лень несколько месяцев на основы фронтенда потратить?

Никто не будет тебе выделять личного верстальщика.

>>514247

Сразу симфони сложновато. ЛУчше начать с наших задачек а студентов и на файлообменник..
#580 #514482
>>513883

Не знаю, я не использую, я не хочу изучать древние схемы клавиш с тех времен когда были терминалы-печатающие машинки без стрелок. На моей клавиатуре стрелки нормальные.

> не хочу я еще вим учить в придачу (все равно придется, но пока рано я считаю).


Я не учил и не собираюсь, единственная комбинация клавиш которую я знаю это :q! или как-то так, для выхода.

Режимы это зло с точки зрения юзабилити — вспомни сколько раз ты набирал текст не в той раскладке.

>>513962

Не знаю.

>>514016

Лучше той что проще.

>>514028

> Ладно, пока просто исключу пробелы и лишние собачки


Вполне подойдет

>>514034

Да, там всякие странные комбинации разрешены но мы будем считать что человек опечатался. На практике такой email наверно нигде не заработает.

>>514046

Для разных слуаев разные циклы.

>>514225

То есть ты ленив и не хочешь изучать технологии? я не думаю что это произведет впечатление на работодателя. Людив вузах по 5 лет учатся, а тебе лень несколько месяцев на основы фронтенда потратить?

Никто не будет тебе выделять личного верстальщика.

>>514247

Сразу симфони сложновато. ЛУчше начать с наших задачек а студентов и на файлообменник..
#581 #514483
>>514320

Не любят те кто не осилил.

>>514343

Набор готовых классов.

>>514378

Отчего же, популярные фрйемворки типа Юи или Симфони очень гибкие.

>>514394

Флоат это приближенные данные, децимал гарантирует сохранение нужного числа знаков, и испоьзует более точную математику. ПРименяют для денег в основном.

>>514438

Фреймворк для тестов, хипстеры такими вещами не интересуются.

>>514477

Предложи денег в /web и желающие найдутся.
#582 #514501
>>514483

>хипстеры такими вещами не интересуются.


Хипстеры как раз и интересуются. Остальные тесты вручную пишут.
#583 #514507
http://habrahabr.ru/company/yandex/blog/262543/ охуеть задачки, чувствую себя никчемной макакой, работником макдональдса в программировании, глядя на них.
#584 #514512
>>514507
Это не на программирование задачки же. Просто отсев для тех, кто в понтовых физмат вузах учился. Яндексу скорее математики нужны, а не программисты.
#585 #514550
Объясните лаконично и доступно, в чем суть внедрения зависимости? (dependency injection для любителей вражеского языка)
Это когда метод принимает объект строго заданного класса? Будет ли следующий пример реализацией этого паттерна:

class FileMapper
{
public function save(File $file){//*}
}
#586 #514555
>>514550

>Объясните лаконично и доступно, в чем суть внедрения зависимости?


Суть в том, что класс, зависящий от другого класса, получает экземпляр этого другого класса извне, а не создаёт его в теле своих методов.

Тут объяснение о ОПа:
>>511406

>> $mapper = new AbiturientsMapper($GLOBALS['pdo']);


>Не, так не годится. Во-первых ты не должен создавать маппер в сервисе (а должен передавать извне), во-вторых не должен использовать GLOBALS.


>


>Лучше сделать так:


>


>$service = new AbiturientService($abiturientMapper, $validator);


>


>Это назвыается Dependency Injection через конструктор. Урок по теме: https://gist.github.com/codedokode/e1d31a31b37d5f635057


>


>Заметь что для контроллеров обычно это не применяют. Обычно контроллер имеет доступ к DI контейнеру и может получить любой сервис из него. Так что, раз уж ты решил нагородить ООП, сделай-ка DI container. Это класс, который создает или (при повторном обращении) возвращает ранее созданные сервисы, он выглядит примерно так:


>


>$mapper = $container->getAbiturientMapper();


>$service = $container->getAbiturientService();


>


>Сами сервисы и мапперы не должны ничего про него знать (иначе код будет запутанным и мы получим service locator), а вот контроллер вполне может иметь к нему доступ. Создавать сам контейнер удобно в bootstrap.php.


>


>Как альтернатива, можно создать контейнер с публичными свойствами и в bootstrap прописать в них мапперы и сервисы, тогда к ним можно обращаться как $container->someMapper. Это работает когда сервисов немного.


>


>В общем код вроде new AbiturientsMapper(...); должен быть только в одном месте. Любой сервис должен быть только в одном экземпляре и не должен создаваться по несколько раз (иначе будет путаница, один экземпляр проставил какое-то поле, а ты вызваешь другой экземпляр где у поля другое значение).


>

#586 #514555
>>514550

>Объясните лаконично и доступно, в чем суть внедрения зависимости?


Суть в том, что класс, зависящий от другого класса, получает экземпляр этого другого класса извне, а не создаёт его в теле своих методов.

Тут объяснение о ОПа:
>>511406

>> $mapper = new AbiturientsMapper($GLOBALS['pdo']);


>Не, так не годится. Во-первых ты не должен создавать маппер в сервисе (а должен передавать извне), во-вторых не должен использовать GLOBALS.


>


>Лучше сделать так:


>


>$service = new AbiturientService($abiturientMapper, $validator);


>


>Это назвыается Dependency Injection через конструктор. Урок по теме: https://gist.github.com/codedokode/e1d31a31b37d5f635057


>


>Заметь что для контроллеров обычно это не применяют. Обычно контроллер имеет доступ к DI контейнеру и может получить любой сервис из него. Так что, раз уж ты решил нагородить ООП, сделай-ка DI container. Это класс, который создает или (при повторном обращении) возвращает ранее созданные сервисы, он выглядит примерно так:


>


>$mapper = $container->getAbiturientMapper();


>$service = $container->getAbiturientService();


>


>Сами сервисы и мапперы не должны ничего про него знать (иначе код будет запутанным и мы получим service locator), а вот контроллер вполне может иметь к нему доступ. Создавать сам контейнер удобно в bootstrap.php.


>


>Как альтернатива, можно создать контейнер с публичными свойствами и в bootstrap прописать в них мапперы и сервисы, тогда к ним можно обращаться как $container->someMapper. Это работает когда сервисов немного.


>


>В общем код вроде new AbiturientsMapper(...); должен быть только в одном месте. Любой сервис должен быть только в одном экземпляре и не должен создаваться по несколько раз (иначе будет путаница, один экземпляр проставил какое-то поле, а ты вызваешь другой экземпляр где у поля другое значение).


>

#587 #514561
>>514555

>класс, зависящий от другого класса, получает экземпляр этого другого класса извне, а не создаёт его в теле своих методов


Это понял.

>можно создать контейнер с публичными свойствами и в bootstrap прописать в них мапперы и сервисы


Тут речь походу о синглтонах, чтобы эти мапперы и сервисы были одним и тем же объектом, а не плодились новые экземпляры, я так понял.

Статью почитаю на досуге, но выглядит тяжеловатой. Неужели нельзя излагать мысли ясно и понятно?
#588 #514568
>>514555

>Урок по теме: https://gist.github.com/codedokode/e1d31a31b37d5f635057


Урок невнятный какой-то, непонятно чем Service Locator лучше Registry, можно и тех и других разных насоздавать.
#589 #514578
>>514568
Нормальный урок, че ты.
Чтобы насоздавать разных Registry, тебе придётся описывать много классов и потом бегать по всему коду и заменять имя на новое везде, где он используется. А в случае с SL создаются именно экземпляры, которые пишутся в переменную, например. Это проще.

Ну и минусы Registry и его отличия от SL описаны в уроке.
#590 #514591
Комментарий через # решетку в php валидный?
Редко почему-то вижу, чтобы его кто-то использовал.
#591 #514597
>>514578
Ну хз, как-то очень непонятно там все автор описывает, неясно где и что он имеет в виду.
Как я понял, единственное отличие, что Registry статический, а SL обычный класс, которому экземпляр надо делать. Ну и чем он тогда лучше? Что там, что там методы писать одинаково. Если нужно, чтобы разные настройки были, у Registry можно массив настроек сделать и вызывать нужную в геттере по индексу, в сеттере так же с индексом ставить.
По минусам вроде все тоже одинаково.
#592 #514599
>>514591
Валидный. / под рукой просто, а к # тянуться надо и shift нажимать, неудобно же.
#593 #514602
А какой там сейчас самый большой хеш? sha1 вроде всегда возвращает 40 символов, есть кто больше?
Я просто собираюсь хранить хеш в базе, поставил бы char, но вдруг понадобится другой хеш, который возвращает скажем строку из 80 символов.
Что будет, если через alter table поменять char(40) на char(80)? Все записи, которые уже есть в базе, добьются пробелами до 80 символов?
Наверное я лучше поставлю varchar, и не будет хлопот.

И расскажите о "миграциях", потому что я слышал что не нужно лезть в базу и править таблицы руками, это нужно делать через эти самые миграции. Что это вообще?
#594 #514608
>>514602
Меняй на varchar(80) и включи ALTER TABLE imyatablici ROW_FORMAT=FIXED;
Тогда по скорости будет как char, а по объему как для 80.
#595 #514615
полез в код вордпресса. как там можно что-то фиксить? там же все так запутанно..
#596 #514618
>>514615
Ты еще битрикс не видел.

Если зазубрить api, то будет легче разобраться.
Во фреймворках тоже кстати придется долго заучивать, как разрабы назвали тот или иной класс, метод, свойство. Но там хоть какая-то логика есть, и все взаимосвязано.
44 Кб, 300x300
#597 #514622
Наверное платина, но все же. Есть один апач на убунте. Есть дефолтный сайт, файлы которого находятся в /var/www/html. Хочу создать виртуалхост, допустим alex.org, создал папку /var/www/alex.org/public_html. Привязал его в /etc/hosts на локалхост.

>127.0.0.1 alex.org


Создал конфиг в sites-available (коменты убрал)

><VirtualHost *:80>


> ServerAdmin admin@alex.org


> ServerName alex.org


> ServerAlias www.alex.org


> DocumentRoot /var/www/alex.org/public_html


> ErrorLog ${APACHE_LOG_DIR}/error.log


> CustomLog ${APACHE_LOG_DIR}/access.log combined


></VirtualHost>


Включил сайт a2ensite alex.org.conf, теперь он отображается в sites-enabled
Апач перезапустил.
И тут проблема:
Перехожу на alex.org, меня кидает в дефолтный сайт (/var/www/html/index.html). Я хочу попадать на /var/www/alex.org/public_html/index.html Что я упустил? Пол-дня пытаюсь разобраться.
#598 #514632
>>514622
Нет, платина это "чо у меня денвир выдает кракозябры?"

Попробуй в настройках хоста
<Directory /var/www/alex.org/public_html>
Require all granted
</Directory>
#599 #514633
>>514622
Хз, что за sites-available, ставь через httpd-vhosts.conf в apache/conf/extra как все люди.
#600 #514638
>>514622
NameVirtualHost *:80 включил?
#601 #514657
К символу в константе нельзя обратиться, что ли?
const MY_CONST = 'hello';
echo MY_CONST[1];
Я уже понял, что нельзя, он мне пишет в лог unexpected [ или unexpected {

Но может какой-нибудь оп скажет что-то умное по этому поводу, почему так происходит. Вроде бы в константе тоже строка, с чем это связано?

У меня класс вспомогательный, у него только статичные методы и константы.
Мне эту переменную видимо придется жоско зашить в статичный метод, внутри которого она используется. А если эта строка мне понадобится в других методах?
Хм, я тогда сделаю статичный метод, который тупо возвращает эту строку. Что поделать.
49 Кб, 587x347
#602 #514661
>>514632
>>514633
>>514638
Спасибо конечно, я решил проблему иначе, но это вообще пушка.
http://stackoverflow.com/questions/23713061/virtualhost-always-returns-default-host-with-apache-on-ubuntu-14-04
Первый коммент с 13 плюсами. Меня наебал сам апач. Мне еще предстоят подобные подводные камни? Пол дня въебал впустую изза того что там нет нормального сообщения об ошибке.
#603 #514664
>>514661
Я всегда использую service apache2 restart, а не reload.
restart перезапускает сервер с нуля, то есть stop + start.
reload перезагружает только какие-то там конфиги, не факт что те что надо.
#604 #514693
>>514550

DI это когда мы передаем классу A класс B снаружи и тем самым делаем эти классы менее спутанными. Обязательные зависимости обычно внедряются через конструктор, необязательные через сеттеры.

> Будет ли следующий пример реализацией этого паттерна:


Нет так как File это не сервис от которого зависит FileMapper. Это объект, с которым работает метод save.

А вот объект PDO в FileMapper стоит передавать именно через конструктор. Это позволяет внешнему коду решать какой именно объект какого класса будет использовать FileMapper для выполнения запросов.

>>514561

>Тут речь походу о синглтонах,


Не совсем то. Анон говорит про DI container то есть класс который содержит в себе экземпляры сервисов (должны же они где-то храниться).

>>514568

Registry это не очень хороший паттерн, так как он не обсепечивает DI. Он приведен в пример только чтобы показать что такой паттерн есть и может где-то используется.

Registry это когда в начале программы мы делаем:

Registry::set('serviceA', new ServiceA);

а в классе B делаем

$serviceA = Registry::get('serviceA');

Тут как видишь полноценной DI нет, мы не можем явно классу B передать экземпляр serviceA, он сам его берет из реестра.

Вот описание: http://design-pattern.ru/patterns/registry.html
http://omurashov.ru/pattern-registry/

> чем Service Locator лучше


ServiceLocator это когда у нас есть класс, хранящий или умеющий создавать сервисы. и мы передаем его:

$classB = new ClassB($serviceLocator);

Собственно он плох тем что отравляет код, все объекты теперь должны принимать его в конструкторе. И вместо того чтобы указать явно какие сервисы нужны классу мы передаем ему сразу все. Это ухудшает код.

Но в контроллерах это удобно так как контроллер все равно нельзя повторно использовать, и ему нужно много сервисов, так что передавть их через конструктор неудобно. Для контроллера использовать SL (или передавать в него DI container что по сути то же самое) это вполне нормально. В симфони например так сделано.

Вот статья про него: http://sergeyteplyakov.blogspot.ru/2013/03/di-service-locator.html

Полный контроль дает только DI то есть передача serviceA в класс B через конструктор или сеттер.

>>514591

Да, но он не используется обычно.

>>514597

> Как я понял, единственное отличие, что Registry статический, а SL обычный класс,


Разница в том что SL передается в конструктор чтобы класс мог брать из него что ему надо. А Registry вообще чем-то напоминает глобальные переменные.

Погугли эти паттерны, почитай статьи.
#604 #514693
>>514550

DI это когда мы передаем классу A класс B снаружи и тем самым делаем эти классы менее спутанными. Обязательные зависимости обычно внедряются через конструктор, необязательные через сеттеры.

> Будет ли следующий пример реализацией этого паттерна:


Нет так как File это не сервис от которого зависит FileMapper. Это объект, с которым работает метод save.

А вот объект PDO в FileMapper стоит передавать именно через конструктор. Это позволяет внешнему коду решать какой именно объект какого класса будет использовать FileMapper для выполнения запросов.

>>514561

>Тут речь походу о синглтонах,


Не совсем то. Анон говорит про DI container то есть класс который содержит в себе экземпляры сервисов (должны же они где-то храниться).

>>514568

Registry это не очень хороший паттерн, так как он не обсепечивает DI. Он приведен в пример только чтобы показать что такой паттерн есть и может где-то используется.

Registry это когда в начале программы мы делаем:

Registry::set('serviceA', new ServiceA);

а в классе B делаем

$serviceA = Registry::get('serviceA');

Тут как видишь полноценной DI нет, мы не можем явно классу B передать экземпляр serviceA, он сам его берет из реестра.

Вот описание: http://design-pattern.ru/patterns/registry.html
http://omurashov.ru/pattern-registry/

> чем Service Locator лучше


ServiceLocator это когда у нас есть класс, хранящий или умеющий создавать сервисы. и мы передаем его:

$classB = new ClassB($serviceLocator);

Собственно он плох тем что отравляет код, все объекты теперь должны принимать его в конструкторе. И вместо того чтобы указать явно какие сервисы нужны классу мы передаем ему сразу все. Это ухудшает код.

Но в контроллерах это удобно так как контроллер все равно нельзя повторно использовать, и ему нужно много сервисов, так что передавть их через конструктор неудобно. Для контроллера использовать SL (или передавать в него DI container что по сути то же самое) это вполне нормально. В симфони например так сделано.

Вот статья про него: http://sergeyteplyakov.blogspot.ru/2013/03/di-service-locator.html

Полный контроль дает только DI то есть передача serviceA в класс B через конструктор или сеттер.

>>514591

Да, но он не используется обычно.

>>514597

> Как я понял, единственное отличие, что Registry статический, а SL обычный класс,


Разница в том что SL передается в конструктор чтобы класс мог брать из него что ему надо. А Registry вообще чем-то напоминает глобальные переменные.

Погугли эти паттерны, почитай статьи.
#605 #514697
>>514602

> И расскажите о "миграциях", потому что я слышал что не нужно лезть в базу и править таблицы руками, это нужно делать через эти самые миграции. Что это вообще?


Миграция это файл с кодом (SQL или PHP) который обновляет структуру базы данных. Очевидно он нужен чтобы сохранять изменения структуры в репозиторий (и иметь возможность получить структуру базы для любой ревизии) а также передавать сделанные тобой изменеия другим участникам команды и применять их на серверах.

Ну и это логично, база это часть приложения и информация о ней должна быть в репозитории.

А как иначе?

Обычно в фреймворках (Yii например) есть готовые шаблоны для миграций, тебе надо туда только SQL или команды создания таблиц дописать.

>>514615

Там нельзя ничего фиксить. надо писать свои темы и расширения. Иди читай мануал прежде чем брать задачи по вордпрессу.
#606 #514702
>>514622

Сделай команду apachectl -t -D DUMP_VHOSTS (или apache2ctl?). Она выводит список описанных в конфиге хостов и ты можешь проверить есть там твой хост или нет.

Не забудь перезапустить Апач также.

>>514633

Ты ерунду советуешь. Под линуксом обычно на каждый хост создают отдельный файл и их можно включать/отключать.

>>514657

Нет нельзя. Ты вообще не должен пытаться что-то делать с константой кроме присваивания или сравнения.

Также, ты не должен обращаться по индексу к обычным строкам так как это вернет не N-ю букву а N-й байт.

> Вроде бы в константе тоже строка, с чем это связано?


Ты неправильно пытаешься использовать константу.

> Мне эту переменную видимо придется жоско зашить в статичный метод, внутри которого она используется. А если эта строка мне понадобится в других методах?


Mb_substr используй, но мне кажется ты должен сделать тут не константу а статическое приватное свойство.

> Хм, я тогда сделаю статичный метод, который тупо возвращает эту строку.


Тоже хороший вариант.

>>514661

Странно, у меня на дебиане без судо просто не хватает прав:

$ service apache2 reload
Failed to reload apache2.service: Access denied

Дебиан 8, если что. Видимо убунтоводы где-то накосячили и это временный баг.

>>514664

По идее должен то, что надо перезагрузать. А вот изменения в php.ini он не применит наверно так как это не конфиг Апача и он про него не знает.
#606 #514702
>>514622

Сделай команду apachectl -t -D DUMP_VHOSTS (или apache2ctl?). Она выводит список описанных в конфиге хостов и ты можешь проверить есть там твой хост или нет.

Не забудь перезапустить Апач также.

>>514633

Ты ерунду советуешь. Под линуксом обычно на каждый хост создают отдельный файл и их можно включать/отключать.

>>514657

Нет нельзя. Ты вообще не должен пытаться что-то делать с константой кроме присваивания или сравнения.

Также, ты не должен обращаться по индексу к обычным строкам так как это вернет не N-ю букву а N-й байт.

> Вроде бы в константе тоже строка, с чем это связано?


Ты неправильно пытаешься использовать константу.

> Мне эту переменную видимо придется жоско зашить в статичный метод, внутри которого она используется. А если эта строка мне понадобится в других методах?


Mb_substr используй, но мне кажется ты должен сделать тут не константу а статическое приватное свойство.

> Хм, я тогда сделаю статичный метод, который тупо возвращает эту строку.


Тоже хороший вариант.

>>514661

Странно, у меня на дебиане без судо просто не хватает прав:

$ service apache2 reload
Failed to reload apache2.service: Access denied

Дебиан 8, если что. Видимо убунтоводы где-то накосячили и это временный баг.

>>514664

По идее должен то, что надо перезагрузать. А вот изменения в php.ini он не применит наверно так как это не конфиг Апача и он про него не знает.
#607 #514705
>>514693
Спасибо, про паттерны эти понятно стало.
#608 #514743
Какой фреймворк/cms изучать? На чем сайты проще кодить с нуля?
#609 #514802
Если я кого-то пропустил или не проверил, напомните о себе
#610 #514824
>>514743
На Phalcon
#611 #514851
Внезапно, добрый вечер.

Прошу проверить данный код.
Интересно, как можно его улучшить, имея в запасе только те знания, что могли быть получены при работе с этим замечательный курсом: http://archive-ipq-co.narod.ru/.

http://ideone.com/ywckv8
#612 #514860
>>514851
>>514851
Что значит, улучшить? Этот код бесполезен. Решай практические задачки лучше. Переходи к написанию файлообменников, бложиков и минисайтов. Вперед!
#613 #514862
Блять, ребята, ну что вы тут забыли? Создали же /web для таких как вы. Здесь программирование, реальные пацаны ебашат лисп по сисп. echo $ = "Cъебите" . $ = "нахуй" . $ = "в" . $ = "веб" . $ = "," . $ = " " . $ = "мудаки.\n".
#615 #514872
>>514870
Опять смуту вносишь, ебучий шакал?
#616 #514888
>>514697

>надо писать свои темы и расширения.


Я и писал свои темы и расширения, дебила кусок. Я даже не уверен, что это был ВП - цмска какая-то хитровыебанная, но организована как вп.
#617 #514892
>>514860
Но для этого нужно как минимум познать азы и набить руку, чем я упорно стараюсь заниматься.
#618 #514894
>>514470
https://github.com/V3N0m21/Uppu3
Поправил несколько моментов, чуть не сломал мозг делая custom type в доктрине, но все-равно до конца не уверен что все правильно, как-то слишком мудрено получилось, ну и в моем случае не дает никаких плюсов, разве что в целях обучения и понимания.

>При ресайзе маленькие картинки не увеличиваются? ЧТо-то я не вижу проверки на это.



Там стоит проверка на размер, и если одна из сторон меньше заданного размера, задается размер самой картинки
https://github.com/V3N0m21/Uppu3/blob/master/app/Helper/Resize.php#L55

>Стоит сделать проверку на наличие apc и при отсуствии откатываться на файловый кеш



https://github.com/V3N0m21/Uppu3/blob/master/app/bootstrap.php#L9
Поправил, но не уверен что это правильное решение, я так и не нашел четкого мануала по этому поводу, походу все приходят к пониманию этого методом проб и ошибок.

> {{ app.request.getRootUri() }}../css/bootstrap.min.css


>Что-то это странно. Зачем тут две точки? Мне кажется сразу должен идти путь. Что у тебя выдает getRootUri() ?



Это то о чем я говорил, что $app->getRootUri() возвращает не то что мне нужно, он показывает путь до файла index.php, то есть в моем случае он возвращает "/"

Остальные замечания подправлю и сделаю древовидные комменты, а сейчас интересует вопрос правильно ли я сделал custom type в доктрине
#619 #514920
>>514894

>>Стоит сделать проверку на наличие apc и при отсуствии откатываться на файловый кеш


> https://github.com/V3N0m21/Uppu3/blob/master/app/bootstrap.php#L12


> $config->setQueryCacheImpl(new \Doctrine\Commmon\Cache\MemcacheCache());


По моему это не файловый кеш

> Это то о чем я говорил, что $app->getRootUri() возвращает не то что мне нужно, он показывает путь до файла index.php, то есть в моем случае он возвращает "/"


Ну и отлично, припиши к этому 'css/bootsrap.css' и получишь нужный путь который независим от текущего URL. Разве это то что надо?

> https://github.com/V3N0m21/Uppu3/blob/master/app/Resource/MediaInfo.php#L44


Эту функцию надо сделать либо нестатической либо сделать чтобы она сама создавала и возвращала объект. А то странно смотрится:

> $mediaInfo = $mediaInfo->setMediaInfo($mediaInfo, $info);


Ехал mediaInfo через mediaInfo.

Копипасту из ифов стоит заменить на список полей + цикл по нему.

json_decode лучше использовать с массивом, а не объектом StdClass, так как для работы с массивами есть много функций, а для StdClass нет.

Класс MediaInfoType лучше поместить в другую папку, например, Types.

> public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)


Тут по идее должен возвращаться SQL-код для типа этого поля в MySQL (например если ты хочешь создать таблицу на основе аннотаций, доктрине надо знать какому типу поля соответствует твой тип). Посмоти как реализованы другие типы в доктрине и сделай по аналогии:

https://github.com/doctrine/dbal/tree/master/lib/Doctrine/DBAL/Types

Класс File стоит переименовать в FileUtil или FileUploader и перенести в другую папку.

Почему тип регистрируешь через

> Type::addType('mediainfotype', 'Uppu3\Resource\MediaInfoType');



А не как в мануале советуют,

> $conn->getDatabasePlatform()->registerDoctrineTypeMapping('db_mytype', 'mytype');



?
#619 #514920
>>514894

>>Стоит сделать проверку на наличие apc и при отсуствии откатываться на файловый кеш


> https://github.com/V3N0m21/Uppu3/blob/master/app/bootstrap.php#L12


> $config->setQueryCacheImpl(new \Doctrine\Commmon\Cache\MemcacheCache());


По моему это не файловый кеш

> Это то о чем я говорил, что $app->getRootUri() возвращает не то что мне нужно, он показывает путь до файла index.php, то есть в моем случае он возвращает "/"


Ну и отлично, припиши к этому 'css/bootsrap.css' и получишь нужный путь который независим от текущего URL. Разве это то что надо?

> https://github.com/V3N0m21/Uppu3/blob/master/app/Resource/MediaInfo.php#L44


Эту функцию надо сделать либо нестатической либо сделать чтобы она сама создавала и возвращала объект. А то странно смотрится:

> $mediaInfo = $mediaInfo->setMediaInfo($mediaInfo, $info);


Ехал mediaInfo через mediaInfo.

Копипасту из ифов стоит заменить на список полей + цикл по нему.

json_decode лучше использовать с массивом, а не объектом StdClass, так как для работы с массивами есть много функций, а для StdClass нет.

Класс MediaInfoType лучше поместить в другую папку, например, Types.

> public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)


Тут по идее должен возвращаться SQL-код для типа этого поля в MySQL (например если ты хочешь создать таблицу на основе аннотаций, доктрине надо знать какому типу поля соответствует твой тип). Посмоти как реализованы другие типы в доктрине и сделай по аналогии:

https://github.com/doctrine/dbal/tree/master/lib/Doctrine/DBAL/Types

Класс File стоит переименовать в FileUtil или FileUploader и перенести в другую папку.

Почему тип регистрируешь через

> Type::addType('mediainfotype', 'Uppu3\Resource\MediaInfoType');



А не как в мануале советуют,

> $conn->getDatabasePlatform()->registerDoctrineTypeMapping('db_mytype', 'mytype');



?
#620 #514924
>>514894

> как-то слишком мудрено получилось,


А что мудреного? Всего 15 строчек. Просто мы создали свой тип преобразования (маппинга) между значением в БД и значением поля объекта.

> ну и в моем случае не дает никаких плюсов,


Ты получаешь автоматическое сохранение объекта MediaInfo в базу и восстановлние из нее. Это по моему удобнее чем руками там прикручивать преобразование в json и обратно. То, что у тебя было раньше, не работало вообще так как json_decode не восстанавливает объект класса MediaInfo.
#621 #514928
>>514870

Даже ссылку на тред правильно не поменяли, ну их. И у нас всего 600 постов пока.

>>514851

> for ($i=0; $i<=strlen($lowercasedtext);$i++) {if (mb_substr($lowercasedtext,$i,1) != $empty) {


Чтобы убрать пробелы, используй функцию str_replace или strtr, заменяя пробелы на пустую строку.

>for ($ii=0; $ii <= $half; $ii++){


После $i можно использовать $j, $k, Они лучше читаются.

> strlen($without)-$ii-1


Тут ошибка. strlen возвращает длину в байтах, а не число букв (для русских букв не совпадает). Надо использоват mb_strlen. Почитай урок: https://gist.github.com/codedokode/ff99e357e9860ea169b8

> \tif ($ii == $half){


> echo "this word is a fucking PALINDROME, congrats, m8";


Это неправильно так как ты не можешь по совпадению только первой и последней букв сказать что слово палиндром. Надо проверить все.

И смотри внизу ошибку:

> PHP Notice: Undefined variable: without in /home/hz6bPR/prog.php on line 12


Ты обращаешься к несуществующей на тот момент переменной, надо сначала ей присвоить какое-нибудь значение а потом использовать.

Попробуй сделть чтобы программа работала с руссикми буквами. Если что, задавай вопросы.

>>514860

Тролль, уходи.
#621 #514928
>>514870

Даже ссылку на тред правильно не поменяли, ну их. И у нас всего 600 постов пока.

>>514851

> for ($i=0; $i<=strlen($lowercasedtext);$i++) {if (mb_substr($lowercasedtext,$i,1) != $empty) {


Чтобы убрать пробелы, используй функцию str_replace или strtr, заменяя пробелы на пустую строку.

>for ($ii=0; $ii <= $half; $ii++){


После $i можно использовать $j, $k, Они лучше читаются.

> strlen($without)-$ii-1


Тут ошибка. strlen возвращает длину в байтах, а не число букв (для русских букв не совпадает). Надо использоват mb_strlen. Почитай урок: https://gist.github.com/codedokode/ff99e357e9860ea169b8

> \tif ($ii == $half){


> echo "this word is a fucking PALINDROME, congrats, m8";


Это неправильно так как ты не можешь по совпадению только первой и последней букв сказать что слово палиндром. Надо проверить все.

И смотри внизу ошибку:

> PHP Notice: Undefined variable: without in /home/hz6bPR/prog.php on line 12


Ты обращаешься к несуществующей на тот момент переменной, надо сначала ей присвоить какое-нибудь значение а потом использовать.

Попробуй сделть чтобы программа работала с руссикми буквами. Если что, задавай вопросы.

>>514860

Тролль, уходи.
#622 #514953
>>514920
Блин, мне тоже хочется похвастаться файлообменником, давно не вбрасывал.
Но я там так криво прикрутил регистрацию, что лучше сначала сам поправлю те ошибки что вижу, потом покажу.
#623 #514979
Только что мучился с хешами и солями, думал почему у меня после регистрации юзера не пускает форма логина?
Как всегда оказалась тупая ошибка: перепутал местами, в одном месте написал sha1($salt . $password), а в другом sha1($password . $salt).

Надо учиться быть внимательным и анализировать, не сидеть и смотреть на него "чо ты не работаешь?", а разбивать код на кусочки и отслеживать построчно. Это хоть и рутинно при большом объеме кода, но дает плоды.
#624 #514981
>>514928

> .


> \tif ($ii == $half){


> echo "this word is a fucking PALINDROME, congrats, m8";


>Это неправильно так как ты не можешь по совпадению только первой и последней букв сказать что слово палиндром. Надо проверить все.


Я пытался сделать цикл в цикле, который сравнивает шаг прохождения с половиной длины слова, по достижению значения которого цикл завершался. Проверка велась как первая буква == последняя, вторая == предпоследняя, итд. Проверял выводом результата. (http://ideone.com/DNgLQV)

Вроде исправил.
Вот итог. http://ideone.com/YIgY9M

Спасибо!
#625 #515006
>>514981

>цикл


Но это не цикл.
#626 #515017
Объясните разницу между авторизацией и аутентификацией.
Когда пользователь логинится, это что?
#627 #515023
>>515017
Аутентификация - это проверка соответствия субъекта и того, за кого он пытается себя выдать, с помощью некой уникальной информации (отпечатки пальцев, цвет радужки, голос и тд.), в простейшем случае - с помощью имени входа и пароля.

Авторизация - это проверка и определение полномочий на выполнение некоторых действий (например, чтение файла /var/mail/eltsin) в соответствии с ранее выполненной аутентификацией,
#628 #515024
Нужно написать парсер-постер с кроном и базой данных.
Подскажите фреймворк/cmf. Пока остановился на связке slim+twig+medoo.
#629 #515033
>>515023
Блин, только что закоммитил с комментарием "Добавил авторизацию", подразумевая вход через форму логин/пароль.
Как теперь исправить комментарий к коммиту?
Так, тут вроде либо --ammend -m, либо -c. Блин, такое полотно, хрен что найдешь.

Переведите
--amend
Replace the tip of the current branch by creating a new commit. The recorded tree is prepared
as usual (including the effect of the -i and -o options and explicit pathspec), and the
message from the original commit is used as the starting point, instead of an empty message,
when no other message is specified from the command line via options such as -m, -F, -c, etc.
The new commit has the same parents and author as the current one (the --reset-author option
can countermand this).

-c <commit>, --reedit-message=<commit>
Like -C, but with -c the editor is invoked, so that the user can further edit the commit
message.

Оно мне только исправит комментарий к коммиту, или создаст новый?
#630 #515035
>>515033
Изменение название последнего коммита:
git commit --amend -m "Новое название"
#631 #515039
>>514953
Ты там какую-то йобу строишь с блэкджеком и шлюхами, а у меня простой файлообменник как написано в минимальной инструкции к задаче. А вообще я завидую твоему энтузиазму, мне очень сложно начать делать что-то просто из интереса, нужно какое-то сверхусилие над собой, но после того как начал оно идет само собой. Мне вот например для этого нужны комменты ОПа, сам я почему-то не могу заставить себя прикручивать что-то сверх нормы, внутри включается режим "и так пойдет", и хз как это искоренять
#632 #515049
посоны, хочу использовать https://www.devbridge.com/sourcery/components/jquery-autocomplete/

но там нужно в качестве ответа использовать json, который я не шарю, читал вот здесь https://learn.javascript.ru/json
и вроде понятно как таковой объект создать, но как его вернуть, в php я бы вернул с помощью echo, а как вернуть это?
#633 #515050
>>515049
Куда ты его возвращать собрался? Чем?
#634 #515052
>>515050
Почитай https://www.devbridge.com/sourcery/components/jquery-autocomplete/

хочу вернуть результат выборки.
#635 #515053
>>515050
через аякс
#636 #515054
>>515052
>>515053
Куда вернуть? На сервер или клиенту? Чем разбирать будешь?
#637 #515055
>>515039
Ну не пилить же под каждый виджет типа плеера или древовидных комментариев отдельный проект. Поэтому я все туда сую.
Плюс я собираюсь это дело показывать в качестве примера выполненных работ (в моей мухосрани 50% работодателей просят что-то показать, а что я им покажу? задачку на айфон в кредит?)
Хотя пожалуй задание действительно на это не рассчитано, бедный слим уже раздуло от большого количества кода.

По поводу мотивации не могу ничего советовать. Мною движет желание обеспечить себе комфортную обстановку в плане психологии и финансов. Я знаю что мне нужно, и я иду к этому.
#638 #515056
>>515054
ну на сервер идет запрос, я клиенту возвращаю ответ. всё как обычно.
А эта хуйня Ajax AutoComplete for jQuery требует, чтобы я ей(клиенту) возвращал данные в json объекте.
#639 #515057
>>515056

>Response Format



Response from the server must be JSON formatted following JavaScript object:

{
// Query is not required as of version 1.2.5
"query": "Unit",
"suggestions": [
{ "value": "United Arab Emirates", "data": "AE" },
{ "value": "United Kingdom", "data": "UK" },
{ "value": "United States", "data": "US" }
]
}
Data can be any value or object. Data object is passed to formatResults function and onSelect callback. Alternatively, if there is no data you can supply just a string array for suggestions:

{
"query": "Unit",
"suggestions": ["United Arab Emirates", "United Kingdom", "United States"]
}
#640 #515059
>>515057
>>515056
Так возвращай данные в json, в чем проблема? JSON - это просто форматированная определенным образом строка, ничгео сложного ведь.

http://www.objgen.com/json?demo=true - json генератор
http://jsonlint.com/ - чекер json
http://php.net/manual/ru/function.json-encode.php
http://php.net/manual/ru/function.json-decode.php
#641 #515065
>>515059
допустим в файле, в котором обрабатываю запрос у меня есть
$response = '{

"query": "Unit",
"suggestions": [
{ "value": "United Arab Emirates", "data": "AE" },
{ "value": "United Kingdom", "data": "UK" },
{ "value": "United States", "data": "US" }
]
}';
echo json_encode($response);

но тогда ответ пикрелейтед, что за хуйня? зачем экранирует?!
если это вбить в http://jsonlint.com/
то оно мне пишет:
Parse error on line 1:
"{ \r\n\r\n\"que
^
Expecting '{', '['

что я делаю не так?
75 Кб, 1599x362
#642 #515066
>>515065
отклеилась
#643 #515067
>>515065
может ему обязательно нужен массив?
#644 #515072
>>515024
Laravel, angular
#645 #515076
>>515066
>>515067
>>515065
Так и должно быть. JSON при передаче экранируется.
jsonlint валит ошибки, потому что он чекает сырой JSON, а не экранированный.
#646 #515079
>>515072
Тяжеленькие они. Скриптик должен легким получится.
Может полегче есть что-нибудь?
#647 #515164
Почти готовый список студентов: https://github.com/blackberryJam/abiturients
Учтены все замечания, озвученные здесь: >>511406

Осталось прикрутить пагинацию к html-шаблону. Честно говоря, я пока не особо представляю, как это сделать по-человечески.
#648 #515179
>>515164
Хочу уметь также
#649 #515213
>>515164
Эм, просто вставить в любое место хтмл кода.
#650 #515216
>>515164
>>515164

>html


Для быдла. Элита давно перешла на xml.
#651 #515219
>>515213
Вставить хтмл-пагинатор я могу. А как его оживить -- пока не представляю.
#652 #515222
>>515219
Я имею в виду сделать по-умному. Чтоб номер текущей страницы красился в другой цвет (с этим понятно), чтоб слева и справа от текущей страницы показывалось только заданное число номеров других страниц (а дальше -- многоточие) и тому подобные вещи. Идеально, если эти параметры можно без труда настроить PHP-кодом.
#653 #515224
>>515216

> xml


У тебя ошибка в слове json
#654 #515230
>>515222
Так прикрути парочку ява скриптов и все, зачем там изъебываться?
#655 #515234
>>515230

>ява скриптов


Я не умею пока.
#656 #515240
>>514979

> тупая ошибка: перепутал местами, в одном месте написал sha1($salt . $password), а в другом sha1($password . $salt).



Твоя ошибка в том что ты код который делает одно и то же пишешь 2 раза, а не выносишь в функцию. Дублирования кода быть не должно.
#657 #515242
>>515065

Ты не уделил должного внимания изуению формата JSON и чтению мануалп по JSON_encode. Не разобрал все примеры кода в мануале по этой функции.

> $response = '{


> echo json_encode($response);


Ты посмотри что он тебе выводит. Ты должен видеть

{ ...

а видишь

"{ ...

Тебя это не удивляет? Кавычка это не такая вещь которую можно проигнорировать так как она полностью меняет весь смысл. Начни с чтения википедии:

https://ru.wikipedia.org/wiki/JSON

Ты подаешь на вход json_encode строку и получаешь на выходе закодированную в JSON эту строку. А виджету нужна не строка, а словарь (хеш) описанного формата.

На вход json_encode надо подавать правильно сформированный массив с данными (так как в php нет словарей то и JSON-массив и JSON-словарь на строне PHP обозначается массивом). перечитай мануал PHP и внимательно посмотри примеры кода в нем.

> то оно мне пишет:


> Parse error on line 1:


> "{ \r\n\r\n\"que


> ^


> Expecting '{', '['


Все правильно пишет. JSON объект на самом верхнем уровне по стандарту должен быть словарем либо массивом, а не строкой.

Также, JSON ответ должен иметь заголовок Content-Type: application/json

Не забудь поставить соответствующий header().
#657 #515242
>>515065

Ты не уделил должного внимания изуению формата JSON и чтению мануалп по JSON_encode. Не разобрал все примеры кода в мануале по этой функции.

> $response = '{


> echo json_encode($response);


Ты посмотри что он тебе выводит. Ты должен видеть

{ ...

а видишь

"{ ...

Тебя это не удивляет? Кавычка это не такая вещь которую можно проигнорировать так как она полностью меняет весь смысл. Начни с чтения википедии:

https://ru.wikipedia.org/wiki/JSON

Ты подаешь на вход json_encode строку и получаешь на выходе закодированную в JSON эту строку. А виджету нужна не строка, а словарь (хеш) описанного формата.

На вход json_encode надо подавать правильно сформированный массив с данными (так как в php нет словарей то и JSON-массив и JSON-словарь на строне PHP обозначается массивом). перечитай мануал PHP и внимательно посмотри примеры кода в нем.

> то оно мне пишет:


> Parse error on line 1:


> "{ \r\n\r\n\"que


> ^


> Expecting '{', '['


Все правильно пишет. JSON объект на самом верхнем уровне по стандарту должен быть словарем либо массивом, а не строкой.

Также, JSON ответ должен иметь заголовок Content-Type: application/json

Не забудь поставить соответствующий header().
#658 #515245
>>515076

Ты ошибаешься, смотри мой пост.

>>515216

и когда новую версию XHTML увидим? Учитывая что старую практически никто никогда не использовал за все время ее существования (все использовали HTML 4, а позже HTML 5), то новую вряд ли ждет успех.

>>515222

Сделай объект генерирубющий массив из цифр и ссылок. А шаблон проходит по этому массиву и оформляет его в виде HTML тегов.

Там по моему в комментариях к заадче написано же.

https://github.com/codedokode/pasta/blob/master/student-list.md#Постраничная-навигация

Для вывода двоеточия в объекте можно сделать методы говоряшие надо его выводить или не надо в данном случае.

>>515224

Бразеры пока отображают HTML а не jSOn. Да и в hTML как минимум тегов больше.

>>515230

Если ты не разбираешься в проблеме не давай бессмысленных и запутывающих советов. Какие преимущества тут дает использование JS? С пагинауией после ее вывода ничего не происходит. Никаких очевидно, значит он не нужен.

Ты тролль или просто дебил?
#658 #515245
>>515076

Ты ошибаешься, смотри мой пост.

>>515216

и когда новую версию XHTML увидим? Учитывая что старую практически никто никогда не использовал за все время ее существования (все использовали HTML 4, а позже HTML 5), то новую вряд ли ждет успех.

>>515222

Сделай объект генерирубющий массив из цифр и ссылок. А шаблон проходит по этому массиву и оформляет его в виде HTML тегов.

Там по моему в комментариях к заадче написано же.

https://github.com/codedokode/pasta/blob/master/student-list.md#Постраничная-навигация

Для вывода двоеточия в объекте можно сделать методы говоряшие надо его выводить или не надо в данном случае.

>>515224

Бразеры пока отображают HTML а не jSOn. Да и в hTML как минимум тегов больше.

>>515230

Если ты не разбираешься в проблеме не давай бессмысленных и запутывающих советов. Какие преимущества тут дает использование JS? С пагинауией после ее вывода ничего не происходит. Никаких очевидно, значит он не нужен.

Ты тролль или просто дебил?
#659 #515258
>>515245

>https://github.com/codedokode/pasta/blob/master/student-list.md#Постраничная-навигация


Что-то я упустил это. Попробую завтра разобраться.
#660 #515318
Прошу проверить задачку № 5.2 (депозит в 10000 и счёт до миллиона), вопрос о решении: конечный возраст ставить твердое число? (петушку будет 65), или высчитывать дробное? икак вообще правильне доделать? Спасибо

https://ideone.com/qM0fUW

Накоплено 10000 и петушку уже 16 лет
Накоплено 11000 и петушку уже 17 лет
Накоплено 12100 и петушку уже 18 лет
Накоплено 13310 и петушку уже 19 лет
Накоплено 14641 и петушку уже 20 лет
Накоплено 16105.1 и петушку уже 21 лет
Накоплено 17715.61 и петушку уже 22 лет
Накоплено 19487.171 и петушку уже 23 лет
Накоплено 21435.8881 и петушку уже 24 лет
Накоплено 23579.47691 и петушку уже 25 лет
Накоплено 25937.424601 и петушку уже 26 лет
Накоплено 28531.1670611 и петушку уже 27 лет
Накоплено 31384.28376721 и петушку уже 28 лет
Накоплено 34522.712143931 и петушку уже 29 лет
Накоплено 37974.983358324 и петушку уже 30 лет
Накоплено 41772.481694157 и петушку уже 31 лет
Накоплено 45949.729863572 и петушку уже 32 лет
Накоплено 50544.702849929 и петушку уже 33 лет
Накоплено 55599.173134922 и петушку уже 34 лет
Накоплено 61159.090448415 и петушку уже 35 лет
Накоплено 67274.999493256 и петушку уже 36 лет
Накоплено 74002.499442582 и петушку уже 37 лет
Накоплено 81402.74938684 и петушку уже 38 лет
Накоплено 89543.024325524 и петушку уже 39 лет
Накоплено 98497.326758076 и петушку уже 40 лет
Накоплено 108347.05943388 и петушку уже 41 лет
Накоплено 119181.76537727 и петушку уже 42 лет
Накоплено 131099.941915 и петушку уже 43 лет
Накоплено 144209.9361065 и петушку уже 44 лет
Накоплено 158630.92971715 и петушку уже 45 лет
Накоплено 174494.02268886 и петушку уже 46 лет
Накоплено 191943.42495775 и петушку уже 47 лет
Накоплено 211137.76745353 и петушку уже 48 лет
Накоплено 232251.54419888 и петушку уже 49 лет
Накоплено 255476.69861877 и петушку уже 50 лет
Накоплено 281024.36848064 и петушку уже 51 лет
Накоплено 309126.80532871 и петушку уже 52 лет
Накоплено 340039.48586158 и петушку уже 53 лет
Накоплено 374043.43444774 и петушку уже 54 лет
Накоплено 411447.77789251 и петушку уже 55 лет
Накоплено 452592.55568176 и петушку уже 56 лет
Накоплено 497851.81124994 и петушку уже 57 лет
Накоплено 547636.99237493 и петушку уже 58 лет
Накоплено 602400.69161242 и петушку уже 59 лет
Накоплено 662640.76077367 и петушку уже 60 лет
Накоплено 728904.83685103 и петушку уже 61 лет
Накоплено 801795.32053614 и петушку уже 62 лет
Накоплено 881974.85258975 и петушку уже 63 лет
Накоплено 970172.33784873 и петушку уже 64 лет
#660 #515318
Прошу проверить задачку № 5.2 (депозит в 10000 и счёт до миллиона), вопрос о решении: конечный возраст ставить твердое число? (петушку будет 65), или высчитывать дробное? икак вообще правильне доделать? Спасибо

https://ideone.com/qM0fUW

Накоплено 10000 и петушку уже 16 лет
Накоплено 11000 и петушку уже 17 лет
Накоплено 12100 и петушку уже 18 лет
Накоплено 13310 и петушку уже 19 лет
Накоплено 14641 и петушку уже 20 лет
Накоплено 16105.1 и петушку уже 21 лет
Накоплено 17715.61 и петушку уже 22 лет
Накоплено 19487.171 и петушку уже 23 лет
Накоплено 21435.8881 и петушку уже 24 лет
Накоплено 23579.47691 и петушку уже 25 лет
Накоплено 25937.424601 и петушку уже 26 лет
Накоплено 28531.1670611 и петушку уже 27 лет
Накоплено 31384.28376721 и петушку уже 28 лет
Накоплено 34522.712143931 и петушку уже 29 лет
Накоплено 37974.983358324 и петушку уже 30 лет
Накоплено 41772.481694157 и петушку уже 31 лет
Накоплено 45949.729863572 и петушку уже 32 лет
Накоплено 50544.702849929 и петушку уже 33 лет
Накоплено 55599.173134922 и петушку уже 34 лет
Накоплено 61159.090448415 и петушку уже 35 лет
Накоплено 67274.999493256 и петушку уже 36 лет
Накоплено 74002.499442582 и петушку уже 37 лет
Накоплено 81402.74938684 и петушку уже 38 лет
Накоплено 89543.024325524 и петушку уже 39 лет
Накоплено 98497.326758076 и петушку уже 40 лет
Накоплено 108347.05943388 и петушку уже 41 лет
Накоплено 119181.76537727 и петушку уже 42 лет
Накоплено 131099.941915 и петушку уже 43 лет
Накоплено 144209.9361065 и петушку уже 44 лет
Накоплено 158630.92971715 и петушку уже 45 лет
Накоплено 174494.02268886 и петушку уже 46 лет
Накоплено 191943.42495775 и петушку уже 47 лет
Накоплено 211137.76745353 и петушку уже 48 лет
Накоплено 232251.54419888 и петушку уже 49 лет
Накоплено 255476.69861877 и петушку уже 50 лет
Накоплено 281024.36848064 и петушку уже 51 лет
Накоплено 309126.80532871 и петушку уже 52 лет
Накоплено 340039.48586158 и петушку уже 53 лет
Накоплено 374043.43444774 и петушку уже 54 лет
Накоплено 411447.77789251 и петушку уже 55 лет
Накоплено 452592.55568176 и петушку уже 56 лет
Накоплено 497851.81124994 и петушку уже 57 лет
Накоплено 547636.99237493 и петушку уже 58 лет
Накоплено 602400.69161242 и петушку уже 59 лет
Накоплено 662640.76077367 и петушку уже 60 лет
Накоплено 728904.83685103 и петушку уже 61 лет
Накоплено 801795.32053614 и петушку уже 62 лет
Накоплено 881974.85258975 и петушку уже 63 лет
Накоплено 970172.33784873 и петушку уже 64 лет
#662 #515367
Бамп
#663 #515372
>>515367
Наркоман?
#664 #515376
>>515318

> конечный возраст ставить твердое число? (петушку будет 65), или высчитывать дробное? икак вообще правильне доделать?


Целое, возраст обычно никто не пишет в дробном виде, да и банк начисляет проценты не каждый день, а раз в месяц или год.

> while ($deposit <= 1000000){


> \tfor ($deposit = 10000; $deposit <= 1000000; $deposit = $deposit * $bankRate) {


Тут один из циклов лишний. Используй либо while либо for но не все сразу.
#665 #515430
Ананасы, не понимаю, почему последняя функция не видит
переменную area, я же ее объявил не в функции, а выше.
хелп ми плиз
var area = null;
var areas = [
<?php echo substr("$areas", 0, -1)?>
];

$('#area').autocomplete({
lookup: areas,
onSelect: function (suggestion) {
area = suggestion.data;
alert(area);
}
});
$('#city').autocomplete({
serviceUrl: 'autocomplete.php',
params: {
'area': area

},
onSelect: function (suggestion) {
alert('You selected: ' + suggestion.value + ', ' + suggestion.data);
}
});
#666 #515466
>>514470
ОП, подскажи по поводу древовидных комментов:

С Doctrine Extensions я разобраться не могу вообще. Все стопорится еще на этапе инициализации в bootstrap.php, коротко - я не могу понять как прикрутить AnnotationReader. Пример который у них там предложен мне не помогает, а скорее наоборот еще сильнее запутывает, если можешь направить меня, было бы отлично, потому что я перерыл все что мог перерыть и ничего не нашел, мне бы подошел чей-то рабочий код или еще что-нибудь в этом роде.
Походу мне кажется чтоб разобраться придется перечитывать всю документацию по Доктрине чтоб понять что, куда, откуда вызывает и берется.

Пока решил делать комменты просто средствами доктрины как adjacency list, и появился вопрос, чтоб передать parentId в форму, мне нужно обязательно прикручивать jQuery, или этому есть альтернатива?
#667 #515470
>>515055
>>515055
>>515055
>>515055
>>515055
>>515055
>>515055
Как ты будешь устраиваться погромистом без диплома? Это все равно что хуй какой-то придет устраиваться хирургом, который врачевать научился на своих домашних животных.
#668 #515472
>>515470
а где у нас дают дипломы веб-прогромиста, педик?
76 Кб, 625x626
#669 #515473
#670 #515521
>>515470
В миллионниках без проблем. У хирурга человек сдохнет, а у программера всего лишь сайт заглючит, в крайнем случае другого посадят допиливать, убытков никаких. Поэтому берут всех подряд, даже бомжей.
#671 #515553
>>515470
иди нахуй отсюда, дебил.
#672 #515585
>>515164
Ну теперь, в принципе, всё готово: https://github.com/blackberryJam/abiturients
Кроме 404-й страницы.
С пагинацией разобрался, можно настраивать диапазон отображаемых номеров страниц.
#673 #515625
ОП, вопрос по плееру.
Ему нужно подсовывать в конфигурацию данные, которые я теоретически могу взять прямо из страницы, потому что у меня выше плеера идет таблица с описанием файла. Но меня смущает, что дизайнер/верстальщик в любой момент может изменить страницу, выкинуть из нее некоторые элементы, и у меня сдохнет плеер. Значит все-таки лучше сделать явный xhr-запрос к серверу?
#674 #515639
Аноны, сегодня совершенно случайно решил посмотреть API контакта https://vk.com/dev/methods и надо заметить очень многое там нашёл интересное для себя. В голове сразу возникло несколько идей приложений для контакта, поясните, например если я напишу приложение для контакта в котором можно будет по интересующему запросу найти группы и пользователей, а потом автоматически оставить на стенах (если они открыты) всякие сообщения, то есть сделать это массово сразу для всех, то есть например слать спам так можно, это будет как-то сразу же пресекаться? Или попросту такое приложение не напишешь в силу некоторых ограниений?
#675 #515642
>>515639
Нет, не будет пресекаться. Пиши.
#676 #515646
Посоны, допустим есть сайт знакомств, и нужно сделать там модерацию. Допустим пользователь жалуется на какую-то анкету, и вот как распределить какому мочератору должна прийти эта жалоба: всем? но тогда могут все кинуться решать одну проблему, а если рандомно, то как-то ненадежно. Поясните, где как что устроенно, плз
#677 #515665
Посоны, есть туториал по Zend какой-нибудь, чтобы за полдня врубиться, что там да как? Дали заказ по нему, а я ни бубу. В php шарю более-менее.
#678 #515713
>>515665
А вообще с фреймворками работал?
Вообще вряд ли ты быстро в нем разберешься, но почитай оф. документацию, там примеры есть841
#679 #515785
>>515642
Мне уже напомнили о существовании капчи в этом случае. Кстати какие можно написать полезные скрипты используя АПИ вконтакте, кроме авторизации и комментариев? Вроде бы и функций столько есть, только не понимаю что можно нормальное написать при помощи всего этого.
#680 #515796
>>515713
С wordpress и typo3 работал. Ну попробую, просто оф. документация длинная и запутанная, думал может чего для нубов есть, в стиле w3schools или сайта ОПа.
65 Кб, 1223x373
#681 #515831
>>515625

>В сообщении присутствует слово из спам-листа.


В маме абу присутствует мой половой орган.
#682 #515832
>>515831

Синхронные аякс запросы использовать недопустимо так как они блокируют браузер и интерфейс пользователя. Это фича из прошлого, которая в светлом будущем не нужна.
#683 #515833
>>515832
Ну и? Что предлагаешь?
Ставить какую-нибудь костыльную задержку? Есть в js аналог sleep? setTimeout?
#684 #515846
>>515833
бесконечный цикл, который чекает переменную. Из эвента аякса кладется в переменную.
#685 #515855
>>515625

> Ему нужно подсовывать в конфигурацию данные, которые я теоретически могу взять прямо из страницы,


Это неправильно. А если данные как-то модифицируются для представления пользователю, форматируются и тд, ты будешь делать преобразования в обратном порядке? Это непрваильно.

Если тебе нужно заложить какие-то данные в DOm-элемент, можно использовать data-атрибуты, например:

<img src="small.jpg" data-full-size="big.jpg" alt="">

Но тут все еще проще. Тебе можно передать данные напрямую в JS-скрипт:

<script>
var path = 'audio.mp3';
initPlayer(path);
</script>

Как корректно подставить данные из PHP в JS-строку, соблюдая все правила экранирования спецсимволов? Раньше я писал для этого свою функцию, но потом обнаружил что существует готовая:

var path = <?= json_encode($phpString) ?>;

Так как JSON это подмножество JS то любое JSON-закодированное значение является корректным значением в яваскрипте и мы можем смело присвоить его переменной, и не бояться что полуим ошибку JS. Таким образом можно передавать значения null, false|true, цифры, строки, массивы и словари.

Заметь что кавычки ставить не надо.

Заметь что мы не используем здесь htmlspecialchars. Почему? Потому, что теги script и style имеют особый тип содержимого: в них не интерпретируются html-сущности вроде </ и в них угловые скобки не обозначают теги, а передаются js- или css-движку как есть. Потому при вставке данных внутрь style/script не надо их экранировать. Единственное, в этих данных не должна встречаться последовательность

</

которая браузером может интерпретироватся как конец тега script/style. json_encode заменяет / на \/ потому в ее результате такая последовательность встретиться не может.

Это относится только к тегам script/style. Если ты хочешь вставить js-переменную, например в атрибут тега, ты обязан ее экранировать по всем правилам (json_encode преобразует ее в JS-значение, htmlspecialchars экранирует спецсимволы в значении атрибута):

<div onclick="doSmth(<?= htmlspecialchars(json_encode($value), ENT_QUOTES) ?>)">

Собственно, это был мини-урок на тему «как передать переменную в JS».

Аякс-запросы тут не лучшая идея так как мы без необходимости усложняем код. зачем делать сложно если можно сделать просто?
#685 #515855
>>515625

> Ему нужно подсовывать в конфигурацию данные, которые я теоретически могу взять прямо из страницы,


Это неправильно. А если данные как-то модифицируются для представления пользователю, форматируются и тд, ты будешь делать преобразования в обратном порядке? Это непрваильно.

Если тебе нужно заложить какие-то данные в DOm-элемент, можно использовать data-атрибуты, например:

<img src="small.jpg" data-full-size="big.jpg" alt="">

Но тут все еще проще. Тебе можно передать данные напрямую в JS-скрипт:

<script>
var path = 'audio.mp3';
initPlayer(path);
</script>

Как корректно подставить данные из PHP в JS-строку, соблюдая все правила экранирования спецсимволов? Раньше я писал для этого свою функцию, но потом обнаружил что существует готовая:

var path = <?= json_encode($phpString) ?>;

Так как JSON это подмножество JS то любое JSON-закодированное значение является корректным значением в яваскрипте и мы можем смело присвоить его переменной, и не бояться что полуим ошибку JS. Таким образом можно передавать значения null, false|true, цифры, строки, массивы и словари.

Заметь что кавычки ставить не надо.

Заметь что мы не используем здесь htmlspecialchars. Почему? Потому, что теги script и style имеют особый тип содержимого: в них не интерпретируются html-сущности вроде </ и в них угловые скобки не обозначают теги, а передаются js- или css-движку как есть. Потому при вставке данных внутрь style/script не надо их экранировать. Единственное, в этих данных не должна встречаться последовательность

</

которая браузером может интерпретироватся как конец тега script/style. json_encode заменяет / на \/ потому в ее результате такая последовательность встретиться не может.

Это относится только к тегам script/style. Если ты хочешь вставить js-переменную, например в атрибут тега, ты обязан ее экранировать по всем правилам (json_encode преобразует ее в JS-значение, htmlspecialchars экранирует спецсимволы в значении атрибута):

<div onclick="doSmth(<?= htmlspecialchars(json_encode($value), ENT_QUOTES) ?>)">

Собственно, это был мини-урок на тему «как передать переменную в JS».

Аякс-запросы тут не лучшая идея так как мы без необходимости усложняем код. зачем делать сложно если можно сделать просто?
#686 #515857
>>515833

Вообще в таких случаях надо ипользовать асинхроннуое программирование. Функция должна не возвращать значение, а вызывать колбкек:

function getVariable(onSuccess, onError) {
...
}

// использование:
getVariable(function (result) {
...
}, function (error) {
...
});

Если у тебя будет много асинхронных функций, то код будет напоминать кашу из вложенных друг в друга коллбеков. В таком случае ты можешь избавиться от них, используя Promise (обещания). В новых браузерах они будут встроены, для остальных надо подключить библиотеку.

C promise асинхронный код выглядит так:

var promise = getVariable(); // функция возвращет объект promise

// задаем обработчики для успеха/неудачи выполнения запроса
promise.then(function (result) {
...
}, function (error) {
....
});

Чтобы промиз работал, твоя функция getVariable должна выглядеть примерно так:

function getVariable() {
var promise = new Promise();
....
if (isOk) {
result = JSON.parse(...);
promise.resolve(result); // вызвает обраьотчик успешноо завершения
} else {
promise.reject('error text '); // вызвает обработчик ошибки
}
....
return promise;
}

Этот код выглядит похоже на предыдущий, тут тоже коллбеки, но если бы у нас была не одна асинхронная функция, а много, то с промизами код будет выглядеть чище. Промисы можно возвращать и передавать в функции как обычные переменные, и с ними мы пишем линейный код, а не кучу вложенных друг в друга коллбеков.

Мануал: https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Promise

Вот старая статья про асинхронное программрование: http://javascript.ru/unsorted/async (там вместо промизов используют самописный аналог).

Кстати твой код делающий ajax запрос никак не обрабатывает ошибки. Это плохо, такой код нельзя делать, тем более в учебном задании. Всегда проверяй и обрабатывай возможные ошибки.
#686 #515857
>>515833

Вообще в таких случаях надо ипользовать асинхроннуое программирование. Функция должна не возвращать значение, а вызывать колбкек:

function getVariable(onSuccess, onError) {
...
}

// использование:
getVariable(function (result) {
...
}, function (error) {
...
});

Если у тебя будет много асинхронных функций, то код будет напоминать кашу из вложенных друг в друга коллбеков. В таком случае ты можешь избавиться от них, используя Promise (обещания). В новых браузерах они будут встроены, для остальных надо подключить библиотеку.

C promise асинхронный код выглядит так:

var promise = getVariable(); // функция возвращет объект promise

// задаем обработчики для успеха/неудачи выполнения запроса
promise.then(function (result) {
...
}, function (error) {
....
});

Чтобы промиз работал, твоя функция getVariable должна выглядеть примерно так:

function getVariable() {
var promise = new Promise();
....
if (isOk) {
result = JSON.parse(...);
promise.resolve(result); // вызвает обраьотчик успешноо завершения
} else {
promise.reject('error text '); // вызвает обработчик ошибки
}
....
return promise;
}

Этот код выглядит похоже на предыдущий, тут тоже коллбеки, но если бы у нас была не одна асинхронная функция, а много, то с промизами код будет выглядеть чище. Промисы можно возвращать и передавать в функции как обычные переменные, и с ними мы пишем линейный код, а не кучу вложенных друг в друга коллбеков.

Мануал: https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Promise

Вот старая статья про асинхронное программрование: http://javascript.ru/unsorted/async (там вместо промизов используют самописный аналог).

Кстати твой код делающий ajax запрос никак не обрабатывает ошибки. Это плохо, такой код нельзя делать, тем более в учебном задании. Всегда проверяй и обрабатывай возможные ошибки.
#687 #515860
>>515855
Уже сделал аяксом. Ну ладно, завтра перепишу. Лучше перестараться, чем недостараться.

У меня там используется смарти. Он точно обрабатывает код внутри тега <script>?
Погоди, я тогда не смогу вынести js-код во внешний файл, раз ты мне предлагаешь подставлять что-то из php.
>>515857
Ладно, заврта перечитаю твои кантаты, я замаялся, спать хочу.
#688 #515861
>>515832

Попрактиковаться в асинхронном программировании и промизах ты можешь, реализовав аякс-отправку древовидных комментариев. Не забудь обрабатывать как ошибки связи с сервером так и ошибки валидации комментария.

Также, так как это учебное задание, сделай форму отправки так, чтобы она работала и без яваскрипта или при возникновении ошибки в JS коде (то есть чтобы в этом случае слался обычный POST-запрос с перезагрузкой страницы. Это лучше чем ничего).
#689 #515862
>>515860

> У меня там используется смарти. Он точно обрабатывает код внутри тега <script>?


Думаю, да. Смарти не пытается анализировать HTML код и ему без разницы какой там тег. Также, имей в виду смарти довольно древний и он не очень красивый с токи зрения синтаксиса, архитектуры, и тд. Я бы советовал еще изучить twig, он современный и лучше на мой взгляд. И он используется в симфони.
#690 #515863
>>515860

> Погоди, я тогда не смогу вынести js-код во внешний файл, раз ты мне предлагаешь подставлять что-то из php.


Код функции ты выносишь во внешний файл, а вызов вставляешь в страницу маленьким inline-скриптом.
63 Кб, 761x1011
#691 #515866
Три недели назад я начал учить пхп, чтобы стать пхп-макакой и пить смузи в офисе и обслуживать стартап.
Но потом мне сказали, что если душа не лежит к программированию, я только из-за денег, то я ничего не добьюсь.
Поэтому я принял решение уйти из треда.
#692 #515868
>>515860
>>515855

Ах да, намопню также что если ты используешь шаблонизатор с автоматическим экранированием html-сущностей (например twig), то при выводе JSN-строки в тело тега script надо не забыть отключить автоэкранирование:

<script>
var x = {{ phpString | json_encode | raw }};
#693 #515893
Наткнулся на древнюю технологию от яндекса: https://web.archive.org/web/20100723005345/http://xscript.opensource.yandex.net/

Интересно конечно, XML, XSLT — помню, они считались многообещающими технологиями, а сейчас как-то отошли. Справедливости ради, тот же XSLT очень громоздкий, из него нельзя вызывать php-функции, и в сравнении с twig проигрывает подчистую.
#694 #515928
>>514981

Ок, теперь верно, но читаемость кода плохая.

Во-первых, слова в переменной надо разделять:

> $originaltext


$originalText

Во-вторых, не стоит городить такие длинные выражения и копипастить их по 2 раза:

> echo mb_substr($lowercasedtext, $j, 1) . " and " . mb_substr($lowercasedtext, mb_strlen($lowercasedtext) - $j-1, 1)."\n";


Помести это в переменные, например $letter1 и $letter2

Также, чтобы взять послеюнюю букву не надо считать длину, достаточно передать -1 в качестве номера:

$lastLetter = mb_substr($text, -1, 1);

Ну и часть комментариев по моему лишняя, например комментарий над функцией mb_strtolower не добавляет никакой новой информации.
#695 #515942
>>515430

> не понимаю, почему последняя функция не видит


переменную area,
Открой оладчик в браузере (Ctrl + shift + I), поставь точку остановва внутри функции и разберись что там видно.

Статья http://learn.javascript.ru/debugging-chrome

>>515466

> Все стопорится еще на этапе инициализации в bootstrap.php, коротко - я не могу понять как прикрутить AnnotationReader.


Согласен, в документации все очень запутанно. Давай посмотрим на пример отсюда:

https://github.com/l3pp4rd/DoctrineExtensions/blob/master/doc/annotations.md#em-setup

и код отсюда: https://github.com/Atlantic18/DoctrineExtensions/blob/master/example/em.php

Здесь важно отличать общую инициализацию доктрины от того места, где подключается нужное расширение. Нам нужно только оно.

Во-первых, все проблемы с автозагрузкой должен решать композер. Ты не должен о ней беспокоиться, так что весь код относящийся к ней пропускаем.

Далее, там идет создание AnnotationReader — но это часть доктрины и у тебя он и так уже создается, может быть только неявно, при вызове

> Setup::createAnnotationMetadataConfiguration


(загляни в эту функцию и посмотри что она делает и что вызывает. Ты увидишь что она создает и AnnotationReader, и кеш пытается сама прикрутить)

Далее идет вызов

> Gedmo\DoctrineExtensions::registerAbstractMappingIntoDriverChainORM


Вот это уже инетереснее, так как возможно это нам нужно, чтобы расширения могли читать адресованные им аннотации, они встраивают свой драйвер в цепочку, которая занимается их чтением. Вот исходник этой функции: https://github.com/l3pp4rd/DoctrineExtensions/blob/master/lib/Gedmo/DoctrineExtensions.php#L35

Схема тут довольно сложная, но если разобраться, вот как выглядит построенная иерархия:

Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain
- AnnotationDriver // тот что создается в registerAbstractMappingIntoDriverChainORM
--CachedReader
---AnnotationReader
- AnnotationDriver // работает с папкой с твоими сущностями
-- CachedReader
--- AnnotationReader

Как видишь, тут мы вместо одного AnnotationDriver создаем цепочку из 2, один нацелен на папку DoctrineExtensions/../Entity, другой на твои сущности.

AnnotationDriver это штука которая читает и анализирует аннотации прописанные например в классе FileResource, кеш там стоит чтобы не делать это на каждый запрос, а только первый раз.

Я посмотрел папку DoctrineExtensions/lib/Tree/Entity, там всего один класс AbstractClosure, я думаю, если ты его не используешь (и если тебе нужно только расширение Tree) то эта цепочка тебе не требуется. Но в качестве упражнения, пожалуй, стоит ее реализовать. Можешь вынести это в отдельную функцию в bootstrap.php

Не забудь что там надо везде передать выбранный нами драйвер кеша, а не то что функции подсовывают по умолчанию.

Посмотри исходники упомянутых функций и разберись как создается эта цепочка.

От тебя требуется создать описанную выше иерархию.

Смотрим код примера дальше.

>// general ORM configuration


> $config = new Doctrine\ORM\Configuration;


Это как я уже написал выше, делается при вызове Setup::createAnnotationMetadataConfiguration и потому не нужно. От нас требуется лишь передать в нужное место созданный выше DriverChain с 2 драйверами аннотаций. Так как функция createAnnotationMetadataConfiguration не позволяет задать драйвер (она создает его сама), то мы от нее отказываемся и заменяем на Setup::createConfiguration после чего ставим в качестве драйвера аннотаций нашу DriverChain.

> $sluggableListener = new Gedmo\Sluggable\SluggableListener;


> $loggableListener = new Gedmo\Loggable\LoggableListener;


> $timestampableListener = new Gedmo\Timestampable\TimestampableListener;


Тут расширения добавляют свои обработчики событий (то есть они будут вызываться например после загрузки сущности из БД или перед сохранением). так как мы не используем эти расширения то можно их не добавлять.

> $treeListener = new Gedmo\Tree\TreeListener;


А вот это нужно, так как мы его используем.

Ну вот и все, то есть реально нужно сделать только 2 вещи:

— сделать цепочку из 2 annotation driver (реально не нужно, но в качестве управжнения стоит сделать)
— добавить обработчик событий от расширения Tree в доктрину

Ну а далее изучай как исопльзуется Tree. Во-первых, ты должен разметить свою сущность, пометив используемые для реализации дерева поля с помощью аннотаций:

https://github.com/l3pp4rd/DoctrineExtensions/blob/master/doc/tree.md#tree-entity-example

Во-вторых, расширение добавляет в репозиторий дополнительные методы для работы с деревом:

https://github.com/l3pp4rd/DoctrineExtensions/blob/master/doc/tree.md#using-repository-functions
https://github.com/l3pp4rd/DoctrineExtensions/blob/master/doc/tree.md#repository-methods-all-strategies

Насчет выбора стратегии:

> Пока решил делать комменты просто средствами доктрины как adjacency list,


Не пойдет. Такие комментарии нельзя эффективно выбирать. Почитай май урок, по моему materialized path для комментариев идеален, быстрая вставка и быстрая выборка в уже отсортированном виде.

> чтоб передать parentId в форму, мне нужно обязательно прикручивать jQuery, или этому есть альтернатива?


Есть такие альтернативы:

- чистый JS/DOm без jQuery
- если ты не силен в JS то можно для начала сделать просто радиокнопки перед каждым комментаием, выбирающий parentId. Радиокнопки средствами CSS можно превратить в кнопку «ответить» и заодно сделать подсветку выбранного комментария.

В перспективе надо бы сделать кнопку «ответить» которая через JS вставляет форму, заполняет в ней parentId, а затем аяксом отправляет. На случай пробелм с JS хорошо бы предусмотреть неаяксовую отправку если не сработал JS-код или если он отключен.

Не забудь при отправке аякс-запроса блокировать форму и обрабатывать сетевые ошибки с возможностью повторить попытку. Не забудь валидацию комментария на сервере и вывод списка ошибок. Если грамотно это спроектировать, то для обработки аякс- и не-аякс отправки можно использовать один и тот же код с парой ифов (для аякса например он отдает ответ в JSON, а при неаяксовой отправке делает редирект на страницу с комментариями).

Если какие-то вопросы или уточнения, спрашивай.
#695 #515942
>>515430

> не понимаю, почему последняя функция не видит


переменную area,
Открой оладчик в браузере (Ctrl + shift + I), поставь точку остановва внутри функции и разберись что там видно.

Статья http://learn.javascript.ru/debugging-chrome

>>515466

> Все стопорится еще на этапе инициализации в bootstrap.php, коротко - я не могу понять как прикрутить AnnotationReader.


Согласен, в документации все очень запутанно. Давай посмотрим на пример отсюда:

https://github.com/l3pp4rd/DoctrineExtensions/blob/master/doc/annotations.md#em-setup

и код отсюда: https://github.com/Atlantic18/DoctrineExtensions/blob/master/example/em.php

Здесь важно отличать общую инициализацию доктрины от того места, где подключается нужное расширение. Нам нужно только оно.

Во-первых, все проблемы с автозагрузкой должен решать композер. Ты не должен о ней беспокоиться, так что весь код относящийся к ней пропускаем.

Далее, там идет создание AnnotationReader — но это часть доктрины и у тебя он и так уже создается, может быть только неявно, при вызове

> Setup::createAnnotationMetadataConfiguration


(загляни в эту функцию и посмотри что она делает и что вызывает. Ты увидишь что она создает и AnnotationReader, и кеш пытается сама прикрутить)

Далее идет вызов

> Gedmo\DoctrineExtensions::registerAbstractMappingIntoDriverChainORM


Вот это уже инетереснее, так как возможно это нам нужно, чтобы расширения могли читать адресованные им аннотации, они встраивают свой драйвер в цепочку, которая занимается их чтением. Вот исходник этой функции: https://github.com/l3pp4rd/DoctrineExtensions/blob/master/lib/Gedmo/DoctrineExtensions.php#L35

Схема тут довольно сложная, но если разобраться, вот как выглядит построенная иерархия:

Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain
- AnnotationDriver // тот что создается в registerAbstractMappingIntoDriverChainORM
--CachedReader
---AnnotationReader
- AnnotationDriver // работает с папкой с твоими сущностями
-- CachedReader
--- AnnotationReader

Как видишь, тут мы вместо одного AnnotationDriver создаем цепочку из 2, один нацелен на папку DoctrineExtensions/../Entity, другой на твои сущности.

AnnotationDriver это штука которая читает и анализирует аннотации прописанные например в классе FileResource, кеш там стоит чтобы не делать это на каждый запрос, а только первый раз.

Я посмотрел папку DoctrineExtensions/lib/Tree/Entity, там всего один класс AbstractClosure, я думаю, если ты его не используешь (и если тебе нужно только расширение Tree) то эта цепочка тебе не требуется. Но в качестве упражнения, пожалуй, стоит ее реализовать. Можешь вынести это в отдельную функцию в bootstrap.php

Не забудь что там надо везде передать выбранный нами драйвер кеша, а не то что функции подсовывают по умолчанию.

Посмотри исходники упомянутых функций и разберись как создается эта цепочка.

От тебя требуется создать описанную выше иерархию.

Смотрим код примера дальше.

>// general ORM configuration


> $config = new Doctrine\ORM\Configuration;


Это как я уже написал выше, делается при вызове Setup::createAnnotationMetadataConfiguration и потому не нужно. От нас требуется лишь передать в нужное место созданный выше DriverChain с 2 драйверами аннотаций. Так как функция createAnnotationMetadataConfiguration не позволяет задать драйвер (она создает его сама), то мы от нее отказываемся и заменяем на Setup::createConfiguration после чего ставим в качестве драйвера аннотаций нашу DriverChain.

> $sluggableListener = new Gedmo\Sluggable\SluggableListener;


> $loggableListener = new Gedmo\Loggable\LoggableListener;


> $timestampableListener = new Gedmo\Timestampable\TimestampableListener;


Тут расширения добавляют свои обработчики событий (то есть они будут вызываться например после загрузки сущности из БД или перед сохранением). так как мы не используем эти расширения то можно их не добавлять.

> $treeListener = new Gedmo\Tree\TreeListener;


А вот это нужно, так как мы его используем.

Ну вот и все, то есть реально нужно сделать только 2 вещи:

— сделать цепочку из 2 annotation driver (реально не нужно, но в качестве управжнения стоит сделать)
— добавить обработчик событий от расширения Tree в доктрину

Ну а далее изучай как исопльзуется Tree. Во-первых, ты должен разметить свою сущность, пометив используемые для реализации дерева поля с помощью аннотаций:

https://github.com/l3pp4rd/DoctrineExtensions/blob/master/doc/tree.md#tree-entity-example

Во-вторых, расширение добавляет в репозиторий дополнительные методы для работы с деревом:

https://github.com/l3pp4rd/DoctrineExtensions/blob/master/doc/tree.md#using-repository-functions
https://github.com/l3pp4rd/DoctrineExtensions/blob/master/doc/tree.md#repository-methods-all-strategies

Насчет выбора стратегии:

> Пока решил делать комменты просто средствами доктрины как adjacency list,


Не пойдет. Такие комментарии нельзя эффективно выбирать. Почитай май урок, по моему materialized path для комментариев идеален, быстрая вставка и быстрая выборка в уже отсортированном виде.

> чтоб передать parentId в форму, мне нужно обязательно прикручивать jQuery, или этому есть альтернатива?


Есть такие альтернативы:

- чистый JS/DOm без jQuery
- если ты не силен в JS то можно для начала сделать просто радиокнопки перед каждым комментаием, выбирающий parentId. Радиокнопки средствами CSS можно превратить в кнопку «ответить» и заодно сделать подсветку выбранного комментария.

В перспективе надо бы сделать кнопку «ответить» которая через JS вставляет форму, заполняет в ней parentId, а затем аяксом отправляет. На случай пробелм с JS хорошо бы предусмотреть неаяксовую отправку если не сработал JS-код или если он отключен.

Не забудь при отправке аякс-запроса блокировать форму и обрабатывать сетевые ошибки с возможностью повторить попытку. Не забудь валидацию комментария на сервере и вывод списка ошибок. Если грамотно это спроектировать, то для обработки аякс- и не-аякс отправки можно использовать один и тот же код с парой ифов (для аякса например он отдает ответ в JSON, а при неаяксовой отправке делает редирект на страницу с комментариями).

Если какие-то вопросы или уточнения, спрашивай.
#696 #515945
>>515466

А, если тебя вдруг интересует, почему все так сложно и почему у нас 2 класса, AnnotationDriver + AnnotationReader (да еще и кеш посередине), а не один? Потому что доктрина позволяет описывать маппинг разными способами: в аннотациях, в XML, в YML и потому нам нужны разные Reader для разных форматов.

Ну и я тебе советую почитать код расширения:

https://github.com/l3pp4rd/DoctrineExtensions/blob/master/lib/Gedmo/Tree/TreeListener.php

Как видишь он при разных событиях вызвыает разные методы у выбранной для сущности стратегии. Вот например стратегия для MPath:

https://github.com/l3pp4rd/DoctrineExtensions/blob/master/lib/Gedmo/Tree/Strategy/ORM/MaterializedPath.php
https://github.com/l3pp4rd/DoctrineExtensions/blob/master/lib/Gedmo/Tree/Strategy/AbstractMaterializedPath.php

Вот например довольно сложный код вычисления нового path при вставке и обновлении сущности: https://github.com/l3pp4rd/DoctrineExtensions/blob/master/lib/Gedmo/Tree/Strategy/AbstractMaterializedPath.php#L272

По идее чтобы реализовать MPath расширению tree надо лишь отслеживать изменение сущностей, и вычислять для них правильные path/level перед сохранением (правда ситуация становится сложнее когда у нас большой набор сущностей с изменениями, добавлямых и удаляемых сущностей — возможно в таких случаях расширение может что-то неправильно посчитать). Удаление детей при удалении родителя, как я понимаю, делается за счет Foreign KEy в базе по parentId.
#697 #515952
>>515164

Вообще, я вижу у тебя много классов, пора бы забудываться о том чтобы их по папкам раскладывать, сделать неймспейсы и PSR-4.

Ну и хорошо что ты придумываешь свой фреймворк, у нас это ок, но в реальных задачах не изобретай велосипеды и бери готовое.

> function addGetParameterToQueryString($parameter, $value, $queryString = null)


Что-то какие-то костыли пошли в ход. Почему бы не собирать URL с нуля вместо того чтобы разбирать и добалять параметры?

Лучше либо собирать URL с нуля либо передавать в пагинатор шаблон вида index.php?p={page} и подставлять число в него.

И разумеется функцию надо не в bootstrap.php, а в отдельный файл положить или сделать класс Util со статическими методами.

> $container = new Container(new PDO($dsn, $username, $password, $options));


Я думаю, PDO лучше не передавать, а создавать внутри контейнера, в функции GetPdo, а то все объекты кроме него создаются внутри.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/AbiturientService.php#L11


> public function trySave(Abiturient $abiturient, Validator $validator)


я думаю что валидатор уместнее передавать через конструктор, как и маппер, так как он нужен в одном экземпляре, сколько бы мы студентов не проверяли.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/AbiturientService.php#L25


> // Ограничение потенциально бесконечного цикла.


Что будет если не удалось подобрать уникальный токен с 5 попыток? Твой код почему то замалчивает ощибку как будто бы все в порядке. это непраивльно. Ты должен выбрасыват исключение в таких слуаях иначе никто не узнает о проблеме, пока у тебя половина базы не будет забита неправильными данными. Чем раньше ты обнаружишь проблему тем проще будет ее исправлять.

Не скрывай и не игнорируй ошибки.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/AbiturientService.php#L38


> public function getToken($isNew)


Мне не нравится параметр isNew, Это по сути 2 разных функции (получение или генерация токена) и не надо объединять их в одну. Это только запутывает код.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/AbiturientService.php#L43


> public function fillFieldsWithValues(Abiturient $abiturient, array $values = array())


Это наверно должно быть в классе Abiturient, так как данные в себя он может сам проставить.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/AbiturientsMapper.php#L7


> const SURNAME = "surname";


Я думаю, это лишнее, не надо поля в БД (и поля объекта) объявлять константами. Можно передавать их как просто имена (по крайней мере я не видел чтобы так делали)

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/AbiturientsMapper.php#L71


> foreach ($abiturient as $property => $value) {


Стоит сделать отдельную функцию, которая преобразует массив из БД в объект-студента.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/AbiturientsMapper.php#L110


> = "SELECT COUNT .... LIMIT 1";


LIMIT 1 не имеет смысла так как COUNT это аггрегирующая (объединяющая строки) функция и без GROUP BY она вернет ровно 1 строку.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/AbiturientsMapper.php#L122


> public function getAbiturients($orderBy, $orderTrend)


Ты вставляешь переменные в запрос, надо сделать их проверку по списку разрешенных значений. Иначе это SQL инъекция.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/AbiturientsMapper.php#L139


> public function search($string, $orderBy, $orderTrend)



Алгоритм поиска переусложнен. Я бы предложил сделать так:

- получаем массив со списком id (не с полным набором полей) по каждому слову.
- объединяем массивы id через array_intersect, оставляя только те id которые встречаются везде
- выбираем объекты через функцию вроде getByIds с сортировкой и пагинацией если массив id не пуст

Ну и конечно есть альтернативные варианты. Во-первых, можно попробовать настроить в msyql FULLTEXT поиск:

http://www.mysql.ru/docs/man/Fulltext_Search.html

Раньше он был только в MyISAM, в новой mySQL он есть ии для InnoDB. Он не позволяет искать по середине или правой части слова.

Во-вторых, мжно искать через LIKE по склееным вместе полям, но это не позволяет искать слова в любом порядке, так что лучше оставить твой вариант.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/Container.php


> public function getPaginator($perPage, array $abiturients = array())


Мне кажется пагинатор незачем класть в контейнер. В контейнере мы храним объекты которые должны быть в одном экземпляре, а пагинаторов может быть много (если на странице выводится несколько таблиц например).

Пагинатор потому надо создавать через new. Это не сервис, а лишь модель переключателя страниц.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/FrontController.php#L10


> protected function route($uriPath)


Тут надо выводить страницу 404 если маршрут не найден. Не забудь выдавать правильный статус через header(). Я бы советовал выдачу страницы 404 поместить например в базовый контроллер так как на практике бывает надо ее выдавать из не-фронт контроллера.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/MainPageController.php#L78


> $abiturients = $paginator->getCurrentPageContent();


Не, так не пойдет. Надо из базы брать то, что надо, через LIMIT. Я думаю, это не задача пагинатора, а маппера, задача пагинатора лишь отображать номера страниц.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/MainPageController.php#L79


> if ($paginator->numOfPages > 1) {


> $paginationSet = $paginator->getPaginationSet(3);


Если if не сработает, переменной не будет существовать. Это ведет к ошибкам и такого не должно быть, засунь в нее null хотя бы. А если подумать, эта переменная вообще не нужна так как мы можем перенести этот if прямо в шаблон.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/Paginator.php#L20


> public function getCurrentPage()


> return isset($_GET['page']) ? intval($_GET['page']) : 1;


Работу с GET лучше вынести в контроллер, это его задача, а номер в пагинатор правильнее передавать извне. А то вдруг нам надо не из GET взять номер, а откуда-то еще.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/UserpageController.php#L40


> protected function render(Abiturient $abiturient, $errors)


Это приемлемо, но довольно громоздко, на практике шаблонизаторы обычно получают на вход имя шаблона + массив переменных:

$this->render('teplate.twig', [
'a' => $a,
'b' => $b
]);

Но можно оставить и твой вариант.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/Validator.php#L51


> if ($birthyear > 1999 || $birthyear < 1901) {


Обижаешь 15-летних юных гениев.

Кстати мне кажется лучше вместо проверки года вычислять возраст и отсеивать по нему. А то через 5 лет твой код начнет отсеивать 20-летних. Это недальновидно.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/index.php#L2


> error_reporting(-1);


> mb_internal_encoding('utf-8');


> define("SITE_ROOT", __DIR__);


Это стоит тоже в bootstrap перенести

> .myform


если не знаешь как назвать css-класс, используй назвние приложения: abiturient-form

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/templates/basicTemplate.html.php#L11


> <link href= "../style/style.css" rel="stylesheet">


Эта ссылка хрупкая так как она зависит от текщего URL. Если ты добавишь несколько сегментов например:

/student/list/by-name/page/1

То она будет указывать совсем в другое место (/student/list/by-name/style/stуle.css)

Стоит завести параметр в конфиге rootUri который определяет корень сайта (напрмиер / или /students) и подставлять его в путь к css- файлам.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/templates/basicTemplate.html.php#L28


> <li class="<?=parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) == "/" ? "activ


Шаблон не должен лезть в SERVER, передавай имя текущего пункта из контроллера.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/templates/alert_success.html.php#L3


> <strong>Успешно!</strong><br/> <?=$flashMessage;?>


Неплохо бы CSS/HTML подучить. Это оформляется как h3 + ul/li для каждой ошибки либо h3 + p если сообщение одно.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/templates/form.html.php#L5


> $service = $this->container->getAbiturientService();


Шаблон не должен лезть в DI контейнер.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/templates/form.html.php#L10


> foreach ($errors as $key => $value) {


Я думаю лучше этот foreach перенести в alert_warning.html.php и используовать версию с доветочием:

<?php foreach ... ?>
<p>...</p>
<?php endforeach ?>

Форму бы надо оформить. Ты используешь бутстрап, почему бы не сделать как там принято:

http://getbootstrap.com/css/#forms

Использование <br> так часто как у тебя верный признак что человек не знает HTML/CSS.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/templates/paginator.html.php#L13


> <a href="<?=$paginator->getNextPageLink();?>" aria-label="Next">


Все выводимые данные надо пропускать через htmlspecialchars

например & в ссылках должен выводиться как &amp; по правилам HTML.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/templates/table.html.php


Функции надо вынести из шаблона в отдельный файл. Можно сдеолать класс ViewHelper со статическими методами.

В таблице надо бы показыать текщуее направление сортировки. Например, подсвечивая треугольничек или заголовок.

Так, вообще неплохо, но пока еще есть что дорабатывать.
#697 #515952
>>515164

Вообще, я вижу у тебя много классов, пора бы забудываться о том чтобы их по папкам раскладывать, сделать неймспейсы и PSR-4.

Ну и хорошо что ты придумываешь свой фреймворк, у нас это ок, но в реальных задачах не изобретай велосипеды и бери готовое.

> function addGetParameterToQueryString($parameter, $value, $queryString = null)


Что-то какие-то костыли пошли в ход. Почему бы не собирать URL с нуля вместо того чтобы разбирать и добалять параметры?

Лучше либо собирать URL с нуля либо передавать в пагинатор шаблон вида index.php?p={page} и подставлять число в него.

И разумеется функцию надо не в bootstrap.php, а в отдельный файл положить или сделать класс Util со статическими методами.

> $container = new Container(new PDO($dsn, $username, $password, $options));


Я думаю, PDO лучше не передавать, а создавать внутри контейнера, в функции GetPdo, а то все объекты кроме него создаются внутри.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/AbiturientService.php#L11


> public function trySave(Abiturient $abiturient, Validator $validator)


я думаю что валидатор уместнее передавать через конструктор, как и маппер, так как он нужен в одном экземпляре, сколько бы мы студентов не проверяли.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/AbiturientService.php#L25


> // Ограничение потенциально бесконечного цикла.


Что будет если не удалось подобрать уникальный токен с 5 попыток? Твой код почему то замалчивает ощибку как будто бы все в порядке. это непраивльно. Ты должен выбрасыват исключение в таких слуаях иначе никто не узнает о проблеме, пока у тебя половина базы не будет забита неправильными данными. Чем раньше ты обнаружишь проблему тем проще будет ее исправлять.

Не скрывай и не игнорируй ошибки.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/AbiturientService.php#L38


> public function getToken($isNew)


Мне не нравится параметр isNew, Это по сути 2 разных функции (получение или генерация токена) и не надо объединять их в одну. Это только запутывает код.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/AbiturientService.php#L43


> public function fillFieldsWithValues(Abiturient $abiturient, array $values = array())


Это наверно должно быть в классе Abiturient, так как данные в себя он может сам проставить.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/AbiturientsMapper.php#L7


> const SURNAME = "surname";


Я думаю, это лишнее, не надо поля в БД (и поля объекта) объявлять константами. Можно передавать их как просто имена (по крайней мере я не видел чтобы так делали)

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/AbiturientsMapper.php#L71


> foreach ($abiturient as $property => $value) {


Стоит сделать отдельную функцию, которая преобразует массив из БД в объект-студента.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/AbiturientsMapper.php#L110


> = "SELECT COUNT .... LIMIT 1";


LIMIT 1 не имеет смысла так как COUNT это аггрегирующая (объединяющая строки) функция и без GROUP BY она вернет ровно 1 строку.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/AbiturientsMapper.php#L122


> public function getAbiturients($orderBy, $orderTrend)


Ты вставляешь переменные в запрос, надо сделать их проверку по списку разрешенных значений. Иначе это SQL инъекция.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/AbiturientsMapper.php#L139


> public function search($string, $orderBy, $orderTrend)



Алгоритм поиска переусложнен. Я бы предложил сделать так:

- получаем массив со списком id (не с полным набором полей) по каждому слову.
- объединяем массивы id через array_intersect, оставляя только те id которые встречаются везде
- выбираем объекты через функцию вроде getByIds с сортировкой и пагинацией если массив id не пуст

Ну и конечно есть альтернативные варианты. Во-первых, можно попробовать настроить в msyql FULLTEXT поиск:

http://www.mysql.ru/docs/man/Fulltext_Search.html

Раньше он был только в MyISAM, в новой mySQL он есть ии для InnoDB. Он не позволяет искать по середине или правой части слова.

Во-вторых, мжно искать через LIKE по склееным вместе полям, но это не позволяет искать слова в любом порядке, так что лучше оставить твой вариант.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/Container.php


> public function getPaginator($perPage, array $abiturients = array())


Мне кажется пагинатор незачем класть в контейнер. В контейнере мы храним объекты которые должны быть в одном экземпляре, а пагинаторов может быть много (если на странице выводится несколько таблиц например).

Пагинатор потому надо создавать через new. Это не сервис, а лишь модель переключателя страниц.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/FrontController.php#L10


> protected function route($uriPath)


Тут надо выводить страницу 404 если маршрут не найден. Не забудь выдавать правильный статус через header(). Я бы советовал выдачу страницы 404 поместить например в базовый контроллер так как на практике бывает надо ее выдавать из не-фронт контроллера.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/MainPageController.php#L78


> $abiturients = $paginator->getCurrentPageContent();


Не, так не пойдет. Надо из базы брать то, что надо, через LIMIT. Я думаю, это не задача пагинатора, а маппера, задача пагинатора лишь отображать номера страниц.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/MainPageController.php#L79


> if ($paginator->numOfPages > 1) {


> $paginationSet = $paginator->getPaginationSet(3);


Если if не сработает, переменной не будет существовать. Это ведет к ошибкам и такого не должно быть, засунь в нее null хотя бы. А если подумать, эта переменная вообще не нужна так как мы можем перенести этот if прямо в шаблон.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/Paginator.php#L20


> public function getCurrentPage()


> return isset($_GET['page']) ? intval($_GET['page']) : 1;


Работу с GET лучше вынести в контроллер, это его задача, а номер в пагинатор правильнее передавать извне. А то вдруг нам надо не из GET взять номер, а откуда-то еще.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/UserpageController.php#L40


> protected function render(Abiturient $abiturient, $errors)


Это приемлемо, но довольно громоздко, на практике шаблонизаторы обычно получают на вход имя шаблона + массив переменных:

$this->render('teplate.twig', [
'a' => $a,
'b' => $b
]);

Но можно оставить и твой вариант.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/Validator.php#L51


> if ($birthyear > 1999 || $birthyear < 1901) {


Обижаешь 15-летних юных гениев.

Кстати мне кажется лучше вместо проверки года вычислять возраст и отсеивать по нему. А то через 5 лет твой код начнет отсеивать 20-летних. Это недальновидно.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/index.php#L2


> error_reporting(-1);


> mb_internal_encoding('utf-8');


> define("SITE_ROOT", __DIR__);


Это стоит тоже в bootstrap перенести

> .myform


если не знаешь как назвать css-класс, используй назвние приложения: abiturient-form

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/templates/basicTemplate.html.php#L11


> <link href= "../style/style.css" rel="stylesheet">


Эта ссылка хрупкая так как она зависит от текщего URL. Если ты добавишь несколько сегментов например:

/student/list/by-name/page/1

То она будет указывать совсем в другое место (/student/list/by-name/style/stуle.css)

Стоит завести параметр в конфиге rootUri который определяет корень сайта (напрмиер / или /students) и подставлять его в путь к css- файлам.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/templates/basicTemplate.html.php#L28


> <li class="<?=parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) == "/" ? "activ


Шаблон не должен лезть в SERVER, передавай имя текущего пункта из контроллера.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/templates/alert_success.html.php#L3


> <strong>Успешно!</strong><br/> <?=$flashMessage;?>


Неплохо бы CSS/HTML подучить. Это оформляется как h3 + ul/li для каждой ошибки либо h3 + p если сообщение одно.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/templates/form.html.php#L5


> $service = $this->container->getAbiturientService();


Шаблон не должен лезть в DI контейнер.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/templates/form.html.php#L10


> foreach ($errors as $key => $value) {


Я думаю лучше этот foreach перенести в alert_warning.html.php и используовать версию с доветочием:

<?php foreach ... ?>
<p>...</p>
<?php endforeach ?>

Форму бы надо оформить. Ты используешь бутстрап, почему бы не сделать как там принято:

http://getbootstrap.com/css/#forms

Использование <br> так часто как у тебя верный признак что человек не знает HTML/CSS.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/templates/paginator.html.php#L13


> <a href="<?=$paginator->getNextPageLink();?>" aria-label="Next">


Все выводимые данные надо пропускать через htmlspecialchars

например & в ссылках должен выводиться как &amp; по правилам HTML.

> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/templates/table.html.php


Функции надо вынести из шаблона в отдельный файл. Можно сдеолать класс ViewHelper со статическими методами.

В таблице надо бы показыать текщуее направление сортировки. Например, подсвечивая треугольничек или заголовок.

Так, вообще неплохо, но пока еще есть что дорабатывать.
#698 #515954
>>515179

Ну так бери и делай задание, там подробные комментарии есть. Это если ты знаешь ООП и прошел нащ учебник, если нет то начинай с ООП и можешь еще другие задачки из учебника порешать.

>>515646

Можно показывать всем, но как только кто-то за нее берется, блокировать ее на N минут так что второму открыть отчет не получится.

>>515665

Это маловероятно, Zend большой фреймворк. На оф сайте есть доки на русском в том числе.

>>515785

мы не одобряем и не обсуждаем создание спамботов тут. Хорошему товару и услугам не нужна спам-реклама, она нужна только лузерам которые купили какую-нибудь никому не нужную фигню и не могут продать ее даже по себестоимости.

К счатстью, госорганы не дремлют и периодически наказывают любителей тратить чужое время.

А на западе за спам вообще сажают. Так-то.
#699 #515956
Аноны, скоро будет перекат, но пока посидим тут.

>>515846

Троллишь? еды не будет тут, это не /b тут 2 с половиной анона всего сидят.
#700 #516020
>>515952
Спасибо за очередную простыню.

>> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/AbiturientsMapper.php#L7


>> const SURNAME = "surname";


>Я думаю, это лишнее, не надо поля в БД (и поля объекта) объявлять константами. Можно передавать их как просто имена (по крайней мере я не видел чтобы так делали)


>


Ну я исходил из того, что в таблице могут появиться новые поля, что названия этих полей нам могут потребоваться где-то в другом месте, и не факт, что объект абитуриента будет иметь соответствующее свойство. А ещё названия полей таблицы могут поменяться. И придётся по всему коду их заменять.
В моём приложении это действительно, наверное, лишняя заморочка, но как решаются такие проблемы в реальных задачах? И возникают ли?

> <link href= "../style/style.css" rel="stylesheet">


>Эта ссылка хрупкая так как она зависит от текщего URL. Если ты добавишь несколько сегментов например:



>/student/list/by-name/page/1



>То она будет указывать совсем в другое место (/student/list/by-name/style/stуle.css)



>Стоит завести параметр в конфиге rootUri который определяет корень сайта (напрмиер / или /students) и подставлять его в путь к css- файлам.


>параметр в конфиге rootUri


Ты про что-то вроде этого: define("SITE_ROOT", __DIR__) ?
Оно у меня есть в index (ты сказал в bootstrap перенести. Кстати, а почему бы не оставить его в индексе? __DIR__ там тот, который нам нужен, т. к. индекс в корне сайта лежит, а в bootstrap придётся прописывать вручную).

С остальными замечаниями всё понятно, исправлю.
#701 #516044
>>516020

>Ты про что-то вроде этого: define("SITE_ROOT", __DIR__) ?


Туплю, это же путь в файловой системе.
Для rootUri подобную константу объявить в bootstrap?
#702 #516053
>>516020

> В моём приложении это действительно, наверное, лишняя заморочка, но как решаются такие проблемы в реальных задачах? И возникают ли?


Лучше сразу назвать поля правильно. Потому что единственный способ потом их поменять это поиск и замена по всему коду. Константы вряд ли решение так как очень неудобно в каждый запрос их вставлять.

>>516044

Почему константу? переменную наверно лучше.
#703 #516059
>>516053

>Почему константу?


Ну в процессе выполнения скрипта этот самый rootURI не меняется же.
В константу собираюсь записать вытащенную из глобального массива нужную нам часть адреса.
#704 #516069
Кто-нибудь, объясните, как работает этот код: http://php.net/manual/ru/function.spl-autoload-register.php#102180
Почему в spl_autoload_register() передаётся массив, хотя в документации такого нет?
Почему в аутпуте есть эти строки:

>Class1::__construct()


>Class2::__construct()


?
26 Кб, 720x400
#705 #516095
>>515866
А как понять, что душа лежит к кодингу, а не к заманчивым перспективам стать финансово успешным? Я вот начал учить из-за того, что меня интересует зп в 1+ к вечнозеленых и не нужно мне лечить про то, что это враки, я лично знаю 3-х, которые получают от 1к до 1.5к на пыхе, не будучи сеньорами. Но в процессе понял, что меня прет писать проекты, особенно, когда не начинаешь писать, а заканчиваешь и окидываешь взглядом строки кода, кликаешь по интерфесу и все работает, все клево, но вот сидя дома я не могу себя заставить что-то писать, играю в игори, читаю книжки, а писать влом. Получается работаю только под прессом - НАДА, то есть пришел дядя тимлид сказал пиши сука и я пишу, и мне нравится, но как только заданий нет, мне фиолетово становится. Лежит ли у меня душа к кодингу или нет и мне стоит покинуть всю эту херню?
Я этим вопросом уже год мучаюсь. Пздц.
#706 #516125
>>516069

Массив это способ сделать ссылку на метод объекта. В PHP есть несколько способов передать ссылку на функцию, массив один из них:

http://php.net/manual/ru/language.types.callable.php
http://habrahabr.ru/post/259991/
http://habrahabr.ru/post/147620/

> Почему в аутпуте есть эти строки:


В конструкторе класса стоит echo, может в коде его забыли добавить.
#707 #516148
>>515866
Ну они правы. Если все через силу учишь и из под палки делаешь, то не пойдет. А если определенное удовольствие получаешь во время процесса изучения очередной технической поебени, то нормально, можно работать.
#708 #516149
>>516095

Если у тебя душа не лежит то работа надоест тебе через несколько месяцев/лет (мотивация от получения денег проходит через месяц-два) и ты сам с нее уйдешь. Ну или будешь мучаться.
#709 #516153
>>515942
https://github.com/V3N0m21/Uppu3/blob/master/app/bootstrap.php

Я не понимаю, вроде же все правильно настроено, почему я получаю ошибку "The class 'Uppu3\Resource\FileResource' was not found in the chain configured namespaces Gedmo, Entity"

ОП, посмотри пожалуйста, я уже с этим бутстрапом с ума схожу, я попроходил по всем функциям, почитал весь затрагиваемый код, но все-равно не понимаю какого хрена оно не работает. Я наверно еще ни с одной проблемой так долго безвыходно не бился.
#710 #516155
>>515954

>Zend большой фреймворк. На оф сайте есть доки на русском в том числе.


На рутрекере книгу от индуса нашел:
http://rutracker.org/forum/viewtopic.php?t=4663386
Сейчас по ней пробую, вроде проще оф. документации.
#711 #516166
>>516153

> https://github.com/V3N0m21/Uppu3/blob/master/app/bootstrap.php#L30


Что тут значит Entity? Если посомтреть на прототип функции то это

public function addDriver(MappingDriver $nestedDriver, $namespace)

(кстати если тебе интересно как я нашел функцию: я в пустой папке создал composer.json, и прописал в него доктрину, после чего сделал composer install, послу чего перетащил папку vendor в sublime, после этого по Ctrl + Shift + R можно перейти к любой функции и классу из доктрины).

Вместо Entity надо указать твой неймспейс для сущностей. Тебе даже в сообщении об ошибки об этом пишется.
#712 #516168
>>516153

Ну и не бойся лезть в код той же доктрины и смотреть что не так. Ты можешь даже var_dump туда напихать (только не забудь удалить потом).
#713 #516170
>>516166
Мдя, я думал Entity это имя аннотации, поставил свой неймспейс, вернулся к старым баранам
"[Semantical Error] The annotation "@Entity" in class Uppu3\Resource\FileResource was never imported. Did you maybe forget to add a "use" statement for this annotation?"
#714 #516172
>>516170

Аннотации это не просто абстрактные имена. Аннотации это имена классов. Например аннотация @Entity соответствует классу

http://www.doctrine-project.org/api/orm/2.2/source-class-Doctrine.ORM.Mapping.Entity.html#26

Как ты видишь, свойства этого класса соответсвутют опциям, которые можно указывать в скобочках после Entity.

Посмотри файл по ссылке.

А раз это классы то для них действуют те же правила и надо указыват use c именем неймспейса.

Обычно пишут

use Doctrine\ORM\Mapping;
#715 #516182
>>516172

>Аннотации это не просто абстрактные имена. Аннотации это имена классов. Например аннотация @Entity соответствует классу



Ну это я понял, но это все-равно мне не объясняет что не так в моем бутстрапе. Извини, может я уже очень сильно торможу, но сейчас я не могу понять что не правильно в моем бутстрапе, и почему доктрина не может прочитать @Entity в FileResource.
#716 #516191
>>516182

Потому что надо написать либо use либо полное имя класса вместо Entity. Потому что его полное имя это \Doctrine\ORM\Mapping\Entity
#717 #516199
>>516191
Все-равно, я не понимаю, почему здесь
http://doctrine-orm.readthedocs.org/en/latest/reference/basic-mapping.html
в примерах нету ничего о том что нужно использовать use Doctrine\ORM\Mapping?
Ну и опять же, сделав так как ты говоришь, получил новую ошибку "Class "Uppu3\Resource\FileResource" is not a valid entity or mapped super class."

Ладно, буду биться головой об стенку и гуглить дальше, может таки на меня снизойдет озарение, а то у меня уже начинает закрадываться подозрение что я тупой
#718 #516214
>>516199

Действительно, в примерах нет use. Может там какая-то опция есть которая позволяет без него обходиться?

Но тут например оно есть: http://doctrine-common.readthedocs.org/en/latest/reference/annotations.html

Если посмотреть, там есть опция http://doctrine-common.readthedocs.org/en/latest/reference/annotations.html#default-namespace которая задает неймспецс по умолчнаию — видимо ты ее откючил когда переделывал конфигурацию доктрины.

Вот еще ответ вроде бы по теме: http://stackoverflow.com/a/15108579 — там дело в том что есть 2 разных reader.

> Ну и опять же, сделав так как ты говоришь, получил новую ошибку "Class "Uppu3\Resource\FileResource" is not a valid entity or mapped super class."


Стоит посмотреть где эта ошибка выдается и что именно проверяется, в исходниках доктрины.

http://stackoverflow.com/questions/7820597/class-xxx-is-not-a-valid-entity-or-mapped-super-class-after-moving-the-class-i

Судя по этому посту причина может быть в том что у тебя нет корректной аннотации @Entity
#719 #516221
>>516214
Я уже в принципе понял, если использовать $annotationReader = new Doctrine\Common\Annotations\AnnotationReader;
то use нужен, а если
$annotationReader = new Doctrine\Common\Annotations\SimpleAnnotationReader;
то нет.
Ну и весь стэковерфлоу я уже пересмотрел, все эти решения видел и сверял со своим классом, вроде ошибок у себя я не вижу, entity проставлен. Надо бы порыть в сторону доктрины, посмотреть на чем у меня ошибка вылетает.
А не может быть такой что этот экстеншонс нормально работает с доктриной версии 2.1, а с 2.5 такие проблемы?
Потому что я
#720 #516222
>>516221

Вряд ли дело в версии.

Насчет "Class "Uppu3\Resource\FileResource" is not a valid entity or mapped super class." можешь попробовать очистить (или временно отключить, заменив на ArrayCache) кеш, может там что осталось. Иногда очистка кеша делает чудеса.
#721 #516239
>>516222
Насчет кэша ты прав, поменял, помогло - теперь у меня другая ошибка "[Semantical Error] The annotation "@Doctrine\ORM\Mapping\Entity" in class Uppu3\Resource\FileResource does not exist, or could not be auto-loaded."

Вернусь к этому вопросу со свежей головой. Блин, за целый день так и не сделал ничего полезного, и походу не продвинулся вообще в понимании этого вопроса, пичалька
#722 #516308
Если я сделаю все, что сказал мне ОП в своем посте, который он дублирует уже 54 раз, я стану пхп-программистом и смогу во фриланс?
#723 #516349
Заслал резюме на фирму, пособеседовали сначала по скайпу, а во вторник техническое собеседование в реале предложили. Какие бывают вопросы и как быстрее подготовиться? Ни разу на пхп программера еще не собеседовался.
#724 #516416
>>516349
Алсо хотят memcached/nginx и оптимизацию для высокопроизводительных вебсайтов, где про это читнуть вообще?
#725 #516430
>>514622
столько пердолинга и ради чего? Я только из-за этого и не ставлю себе linux и им не обмазываюсь, ибо пока не будешь знать как все работает и чувствовать себя как бог - всякая работа будет адом. Пердолинг - вообще какая то ихняя философия. Хочешь поставь на свою убунту очередную ебу - будь добр прочитай талмуд по йобе, 2-3 дня попердолся и в конце узнай, что кретины написавшие йобу криворукие пидарасы.
#726 #516432
>>513854
Компьютерные сети как в целом написаны? Я танненбаума "архитектура ПК" читаю, мне кажется простым и логичным все. Если так, то норм будет.
#727 #516444
>>516430
От программистов для программистов же. При разработке постоянно с какими-нибудь кривыми либами и такими же кривыми доками к ним ебешься. После тяжелого рабочего дня приходишь домой, включаешь пеку, а там все то же самое, только уже в операционке.
#728 #516493
Что-то я уже походу совсем поехал.
Начал я делать одно задание из сайта в ОП-посте. Вроде все норм и особых проблем изначально не наблюдалось.
Но потом появилась одна функция. В эту функцию я передаю одно значение. И данное значение в функции мне нужно использовать как индекс массива.
Так вот, конструкция вида

> $bill = 100;\t\t\t\t\t\t\t\t\t
> echo $bills[$bill] . "\n";

вне функции работает нормально. Но как только я пытаюсь запилить вот это:

> function checkBills ($bill) {\t\t\t\t\t\t


> echo $bills[$bill] . "__";


> и так далее...



происходит некоторое дерьмо. В частности echo благополучно выводит "__" и все. А при умножении данного значения в функции на любое число получается нуль.
Есть у меня подозрение, что я что-то пропустил в теории, только вот что я так и не нашел. В общем хз, помогите что ль.
Вот сам ...кхм код http://ideone.com/Dfx6JB.
Так же буду рад любым замечаниям по поводу кода.
#729 #516495
#730 #516549
>>516493

Смотри что написано внизу страницы http://ideone.com/Dfx6JB

> PHP Notice: Undefined variable: bills in /home/unuKY0/prog.php on line 21


> PHP Notice: Undefined variable: amout in /home/unuKY0/prog.php on line 22


> PHP Notice: Undefined variable: bills in /home/unuKY0/prog.php on line 22


> PHP Notice: Undefined variable: amout in /home/unuKY0/prog.php on line 28


> PHP Notice: Undefined variable: amout in /home/unuKY0/prog.php on line 29


> PHP Notice: Undefined variable: amout in /home/unuKY0/prog.php on line 29



Видишь сколько ошибок? Неудивительно что не работает.

Внутри функции не видны переменные которые созданы снаружи (глобальные). Ты должен явно их передавать как аргументы.
#731 #516591
>>516432
Глянул содержание, ощущение что книга написана скорее для чистых сетевиков или сисадминов, хуй знает читать или нет. Разве что просто чтобы лишний раз повыебываться.
#732 #516658
Оп, я раньше тут учился у тебя, год назад примерно. Я работу нашел и все такое, спасибо. Но я пришел, чтобы научиться еще одной вещи. Общение между айфреймами. Манипуляция айфреймом с другого домена. Я почитал, что можно с помощью проксирования, postMessage и т.д. Ну дак вот, дай мне задание какое-нибудь. Ну и поясни немного теорией, у тебя это хорошо получается.
#733 #516731
>>516239

Если не получится, выгрузи на гитхаб, у меня может быть вечером будет время глянуть.
#734 #516796
Добрался до регэкспов в туториале ОПа, там все бэкслеши по два раза повторяются, вроде \\s или \\d. Нужно ли так делать? В кодах часто без второго слеша встречаю, в доке по php строкам стоит, что в строках слеш нужно экранировать только если он перед кавычкой или в конце строки.
#735 #516799
>>516796
Попробовал, работают оба варианта
preg_match('/\d+\w+/',$searchstring,$matches);

preg_match('/\\d+\\w+/',$searchstring,$matches);

var_dump($matches); выдает для обоих идентичный результат.
#736 #516824
>>516799
Вариант с двумя слешами универсален. Не нужно задумываться над тем, какой и когда ставить.
#737 #516862
Как часто в ПХП используется класс DOMDocument, он чаще используется для чтения? Или для создания тоже часто используется? Я сейчас начал его учить и в качестве обучения решил создать таблицу, довольно много времени заняло, кстати как добавить атрибуты таблицы border = 1 там например через класс DOMDocument
#738 #516880
>>516862
Сайт пилишь? Почему через обычный хтмл попробовать не хочешь?
#739 #516894
>>515952

>> https://github.com/blackberryJam/abiturients/blob/5fd7991775c9328775fac4dd2ca25822938af5e2/app/classes/AbiturientsMapper.php#L122


>> public function getAbiturients($orderBy, $orderTrend)


>Ты вставляешь переменные в запрос, надо сделать их проверку по списку разрешенных значений. Иначе это SQL инъекция.


Но ведь эти переменные могут содержать только константы, перечисленные в маппере: https://github.com/blackberryJam/abiturients/blob/master/app/classes/MainPageController.php#L11
Кстати, что скажешь насчёт такого способа защиты от инъекций?
#740 #516939
>>516894

Проверка переменной должна стоять там, где она втавляется в запрос то есть в функции getAbiturients

Там ее нет, значит человек должен искать все места где вызывается эта функция по всему коду и анализировать как обраьатываются параметры. Так не пойдет. Ни я, ни кто-то еще не захочет это делать. Я хочу чтобы сразу было видно безопасна функция или нет.

Ну и даже если у тебя параметр где-то в другом месте проверяется нет никаких гарантий что завтра ты не вызовешь функцию из другого места. где эти параметры не проверяются.

Потому должна быть проверка в функции getAbiturients.

> Кстати, что скажешь насчёт такого способа защиты от инъекций?


Это не защита. Функция вставляет данные прямо в запрос и нет гарантий что завтра кт-ото не впишет вызов который не проверяет их.
#741 #516942
>>516862

Чаще для разбора HTML/XML, иногда и для создания.

>>516799

Разница есть когда надо найти бекслеш регуляркой. Тогда ты должен писать его 4 раза:

\\\\

По правилам регулярок для поиска бекслеша надо написать его ровно 2 раза: \\ . Но PHP интерпретирует \\ в строке как один бекслеш, и движок регулярок получит только один бекслеш. Потому их надо написать 4 штуки.

Вот это тут описано: http://php.net/manual/ru/language.types.string.php#language.types.string.syntax.double

Также когда ты хочешь найти знак доллара, придется наставить бекслешей. По правилам регулярок ты должен вписать \$ но с учетом обработки строк PHP придется написать "\\\$" для строки в двойных кавычках и '\\$' для строки в одинарных.

Это все из-за того что PHP обрабатывает escape-последовательности при чтении программы и движок регулярок получает уже обработанную стрку.

Ты можешь увидеть это поведение с помощью echo:

echo "\\\\ \\\$"; выведет \\ \$
#742 #516944
>>516658

1. Сделай iframe-виджет который умеет подстраивать свои размеры под содержимое. Ну например на сайте a.example.com мы подключам JS код с b.example.com который создает ифрейм и загружает в него например список новостей. Как ты знаешь, размер ифрейма задается снаружи, а нам надо чтобы после загрузки списка новостей ифрейм подстроил свой размер (высоту), чтобы они отображались без прокрутки. Он должен это делать за счет обмена сообщениями с яваскриптом на странице, передавая ему команды изменить размер ифрейма.

Не забудь проверять источник сообщений.

2. Сделай iframe-widget-плеер (плеер разумеется можно взять готовый например любой jquery player плагин, лучше с поддержкой HTML 5 audio). Ты подключаешь один и тот же iframe на одной или нескольких страницах в разных вкладках браузера, эти iframe находят друг друга. После этого в любом из них при нажатии воспроизведения все остальные ставятся на паузу. Также изменения громкости в одном плеере действует на все остальные.

Такой механизм полезен не только для плеера. Преставь что пользователь открыл несколько страниц соцсети. По умолчанию каждая из них устанавливает отдельное соединение с сервером чтобы узнавать о новых сообщениях, лайках и тд и отображать уведомления. Но если эти вкладки могут находить друг друга то они могут поручить получение уведомлений только одной из них. Это снижает нагрузку на сервер. разумеется, надо понимать что пользователь может в любой момент закрыть вкладку-мастер, в этом случае оставшиеся страницы должны выбрать нового мастера.
#743 #516947
Я тупой дебил, но у меня вопрос.
В первой задачке на функции (про айпад) из учебника http://archive-ipq-co.narod.ru/l1/functions.html
Так как кредит без первого взноса, надо как-то хитро учесть проценты и комиссию за первый взнос, верно? Я просто ничего не смыслю в этих кредитах, экономику в универе прогуливал.
http://pastebin.com/kyR66dcT-Djn Вот это сырой вариант, объясните мне кто-нить, почему у меня PHPStorm ругается на пробел после круглых скобок после for??
#744 #516953
>>516947

Твоя ссылка на pastebin не открывается (пишут что код удален).

Там первый взнос просто длается добавлением его в самом начале к сумме долга. То есть ты берешь кредит на 39999 и должен уже 39999 + 7777. И с этой суммы начинается отсчет.

Каждый месяц на долг добавляется процент (от текущей суммы долга) и фиксированная комиссия. После этого анон платит, проходит месяц и все повторяется.
#745 #517116
Скачал много всяких баз каталогов для регистрации сайтов (СЕО), собрал в один файл получилось примерно 35 000 уникализировал при помощи пхп скрипта, получилось 24 000, теперь хочу проверить сколько из них реально рабочих (те которые хотя бы загружаются) и хочу для каждого послать запрос, то есть 24 000 запросов при помощи file_get_content, но что то я боюсь это делать, как на это отреагирует провайдер?

И ещё один вопрос, есть несколько прог которые автоматически регистрируют в каталогах, собственно интересно как это у них получается? Каталогов сайтов очень большое количество и все они по разному сделаны, не писать же парсер для каждого? Или все они по одинаковому сделаны и есть какие-то общие АПИ в которые можно закинуть адрес сайта, выбрать категорию, ключевые слова и всё остальное в автоматическом режиме?

Если у них есть АПИ, то есть смысл попробовать написать скрипт который будет проверять насколько живой тот или иной каталог сайтов. То есть загружаешь файл со списком (урлами) каталогов, проверяешь каждый и возвращаешь уже файл только с теми которые реально работают.
#746 #517117
>>516880
Нет, решил именно подтянуть знание DOM.
#747 #517278
>>517116
Провайдер тебя забанит. Юзай бесплатного или прокси.

>Каталогов сайтов очень большое количество и все они по разному сделаны, не писать же парсер для каждого?


Как раз и пишут для каждого. Там писать не особо много, всего-то форма добавления url и пара возможных ответов сервака. Но когда их много ,то дохуя выходит, да, поэтому эти проги за бабло обычно и продают. API общего нет.
#748 #517318
Как Factory паттерн работает? Не очень понятно.
#749 #517320
>>513365
А куда тогда идти? На Java и C# работы нет, на Python и Ruby тоже мало... 1C что ли учить?
#750 #517326
>>513365

> и без того короткой профессиональной жизни программиста


Проиграл что-то. Ну прямо спортсмен или фотомодель ваш программист, такая карьера короткая, да.
#751 #517331
>>517320
В миллионниках полно работы на жабах и .net, на рыбе тоже есть. Еще можно в низкоуровневое уйти на C или C++, или программирование игр на Unity и UE. Если работа есть только на пыхе, лучше съехать с этого мухосранска.
#752 #517332
>>517326

Ну как же. Сейчас в 20 уже тимлид, а в 25 тебя выкидывают и берут нового школьника.
105 Кб, 604x453
#753 #517350
>>513365
Мне бы хоть на пхп научиться кодить, остальные языки слишком сложные, я довольно глупый.
#754 #517374
>>515952

>> function addGetParameterToQueryString($parameter, $value, $queryString = null)


>Что-то какие-то костыли пошли в ход. Почему бы не собирать URL с нуля вместо того чтобы разбирать и добалять параметры?


Мне надо добавлять параметры, если их значение не установлено. А если установлено -- менять на новые. Чтобы собрать URL с нуля, пагинатору придётся узнавать о том, для какой страницы (просто выдачи или же поиска) он формирует ссылки. Не выходит ли это за пределы его задач?
Эта же функция у меня используется и в шаблоне, при формировании сортировочных кнопок-ссылок.

>передавать в пагинатор шаблон вида index.php?p={page} и подставлять число в него.


Значение подставлять просто конкатенацией?
Если у нас там уже есть какие-то get-переменные, как их сохранить, не разбирая запрос на части и не собирая потом вновь?

Функция была изначально создана мной для того, чтобы реализовать переход между страницами без потери настроек сортировки.
#755 #517379
>>517374
Чтоб не искать, сама функция вот: https://github.com/blackberryJam/abiturients/blob/master/app/bootstrap.php#L23
#756 #517403
Подкиньте статью какую, как mysql запросы на скорость оптимизировать. Чего избегать, что использовать.
#757 #517585
>>517318

Factory (фабрика) это класс, который создает другие объекты. Идея примерно такая, что при исплоьзовании new мы не можем повлиять на то, объекты какого класса и как создаются:

public function doSmth()
{
return new SomeClass;
}

Если эту функцию написали не мы, то повлиять на нее мы не можем.

В случае создания объектов через фабрику, мы можем передать другую фабрику и повлиять на то как создаются объекты:

public function _ _ construct(Factory $factory)
{
$this->factory = $factory;
}

public function doSmth()
{
return $this->factory->createSomeObject();
}

Вот в википедии схема есть: https://ru.wikipedia.org/wiki/%D0%90%D0%B1%D1%81%D1%82%D1%80%D0%B0%D0%BA%D1%82%D0%BD%D0%B0%D1%8F_%D1%84%D0%B0%D0%B1%D1%80%D0%B8%D0%BA%D0%B0_(%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD_%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F)

На практике это редко когда нужно так как сильно усложняет код.

И еще, если ты пытаешься заучить паттерны (например к собеседованию), то ты занимаешься глупостью. Чтобы понимать эти паттерны, надо чтобы ты сталкивался с кодом который их использует (либо может использовать). Если у тебя нет особого опыта работы с ООП-кодом, ты паттерны просто не поймешь.

Так что если хочешь изучать паттерны, для начала посиди поковыряйся в коде Симфони например.
#757 #517585
>>517318

Factory (фабрика) это класс, который создает другие объекты. Идея примерно такая, что при исплоьзовании new мы не можем повлиять на то, объекты какого класса и как создаются:

public function doSmth()
{
return new SomeClass;
}

Если эту функцию написали не мы, то повлиять на нее мы не можем.

В случае создания объектов через фабрику, мы можем передать другую фабрику и повлиять на то как создаются объекты:

public function _ _ construct(Factory $factory)
{
$this->factory = $factory;
}

public function doSmth()
{
return $this->factory->createSomeObject();
}

Вот в википедии схема есть: https://ru.wikipedia.org/wiki/%D0%90%D0%B1%D1%81%D1%82%D1%80%D0%B0%D0%BA%D1%82%D0%BD%D0%B0%D1%8F_%D1%84%D0%B0%D0%B1%D1%80%D0%B8%D0%BA%D0%B0_(%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD_%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F)

На практике это редко когда нужно так как сильно усложняет код.

И еще, если ты пытаешься заучить паттерны (например к собеседованию), то ты занимаешься глупостью. Чтобы понимать эти паттерны, надо чтобы ты сталкивался с кодом который их использует (либо может использовать). Если у тебя нет особого опыта работы с ООП-кодом, ты паттерны просто не поймешь.

Так что если хочешь изучать паттерны, для начала посиди поковыряйся в коде Симфони например.
#758 #517589
>>517331

Тролль незаметен.

>>517116

сео лучше обсуждать в /web, мы тут программированием занимаемся.

>>517374

> Чтобы собрать URL с нуля, пагинатору придётся узнавать о том, для какой страницы (просто выдачи или же поиска) он формирует ссылки. Не выходит ли это за пределы его задач?


Ну так сейчас ты передаешь querytring, а будешь передавать массив параметров, не много и поменяется. Или передавай шаблон ссылки.

> Значение подставлять просто конкатенацией?


заменой {page} на число.

> Если у нас там уже есть какие-то get-переменные, как их сохранить, не разбирая запрос на части и не собирая потом вновь?


При замене ничего не теряется. Ну или ты можешь передавать массив параметров.

>>517403

Это в 2 словах не объяснишь. Надо правильно распределить память для mysql, натсроить индексы, переписать неудачные запросы.

Кое-что есть тут:

http://ruhighload.com/post/%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0+%D1%81+%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D0%B0%D0%BC%D0%B8+%D0%B2+MySQL
http://www.mysql.ru/docs/man/MySQL_indexes.html
http://habrahabr.ru/post/211022/
#758 #517589
>>517331

Тролль незаметен.

>>517116

сео лучше обсуждать в /web, мы тут программированием занимаемся.

>>517374

> Чтобы собрать URL с нуля, пагинатору придётся узнавать о том, для какой страницы (просто выдачи или же поиска) он формирует ссылки. Не выходит ли это за пределы его задач?


Ну так сейчас ты передаешь querytring, а будешь передавать массив параметров, не много и поменяется. Или передавай шаблон ссылки.

> Значение подставлять просто конкатенацией?


заменой {page} на число.

> Если у нас там уже есть какие-то get-переменные, как их сохранить, не разбирая запрос на части и не собирая потом вновь?


При замене ничего не теряется. Ну или ты можешь передавать массив параметров.

>>517403

Это в 2 словах не объяснишь. Надо правильно распределить память для mysql, натсроить индексы, переписать неудачные запросы.

Кое-что есть тут:

http://ruhighload.com/post/%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0+%D1%81+%D0%B8%D0%BD%D0%B4%D0%B5%D0%BA%D1%81%D0%B0%D0%BC%D0%B8+%D0%B2+MySQL
http://www.mysql.ru/docs/man/MySQL_indexes.html
http://habrahabr.ru/post/211022/
#759 #517590
Аноны, скоро перекатимся, погодите я дораму досмотрю.
#760 #517650
Аноны, новый тред начинается тут: >>517643\t
#761 #517791
На чем сайты лучше писать, на фрейморке или цмсе?
#762 #518186
помогите советом
у меня есть несколько блоков, в которых есть изображения, эти блоки формируются на основе данных из бд.
Так вот, мне хотелось бы иметь возможность посчитать количество изображений в каждом из блоков и в зависимости от этого менять их размер.
$('.изображение').length показывает количество всех изображений, но как найти конкретно в каждом из блоков?
#763 #519013
С недельку не заходил, у меня появились вопросы но не по самому php, а о том как происходит процесс добавления сайта на хостинг, вот у меня есть статический сайт на компе с чего начать и что нужно сделать чтобы залить его?
#764 #519114
Юзаю вот этот мануал => http://phpclub.ru/mysql/doc/tutorial.html
Но он по ходу устарел.
Вот тут проблема: http://phpclub.ru/mysql/doc/loading-tables.html
Создаю файлик со значения полей, чтобы не вбивать ручками(у меня в качестве разделителя ";"). Чтобы подставить NULL в поле death, пишу \n в нужных местах. Получается такой файл.
Fluffy;Harold;cat;f;1993-02-04;\N
Claws;Gwen;cat;m;1994-03-17;\N
Buffy;Harold;dog;f;1989-05-13;N
Fang;Benny;dog;m;1990-08-27;\N
Bowser;Diane;dog;m;1998-08-31;1995-07-29
Chirpy;Gwen;bird;f;1998-09-11;\N
Whistler;Gwen;bird;\N;1997-12-09;\N
Slim;Benny;snake;m;1996-04-29;\N
У автора все получилось, и заместо \N вставилось NULL, у меня и других парней с форума, на котором я искал решение другой проблемы с этим примером тоже самое(последний пост, там в конце почемуто NULL присутствует): http://sqlinfo.ru/forum/viewtopic.php?id=4087
То есть вместо NULL значение становится 0000-00-00, через select NULL вставляется. Я хз, что тут делать. Нет я могу забить все руками и пойти по мануалу дальше(так и сделаю пока), но хочу разобраться.
24 Кб, 278x200
#765 #519121
Вброшу заодно задачки, только я особо в них не вникал, писал лишь бы работало и старался сильно не говнокодить, я еще с php720 задачи решаю, вброшу их позже.
http://ideone.com/Chstwl
http://ideone.com/yddJ6y
http://ideone.com/xgdIm2
http://ideone.com/gmkUEV
изучающий-SQL-анон
#766 #519139
Котаны вот здесь http://archive-ipq-co.narod.ru/l1/conditions.html задание W4.2 я должен гсч задать число от 100000 до 999999 а затем делить его на 10 и в итоге получиться последняя цифра поста, то есть нужно задать что выводить при получении чисел от 0 до 9 так? Подскажите пожалуйста ибо я не понял задания. А для задания с кубиками код так должен выглядеть конечный в итоге или можно лучше было?
#767 #519143
>>519139
*получится самофикс
#768 #519153
>>519139
По идее так
<?php

echo "Добро пожаловать в рулетку\n";

$random = mt_rand(100000,999999);
echo "Номер поста $random\n";
$lastDigit=$random %10;

if ($lastDigit==6){
\techo "Поздравляю ты шестерка\n";
}elseif ($lastDigit==7){
\techo "Блатной да?\n";
}else {
\techo "Ты мужик";
}
#769 #519181
>>519153
>>519143
>>519121
>>519139
>>519114
>>519013
>>518186
>>517791

Мы уже в новом треде сидим >>517643

Перепостите вопросы или ссылку на них там.
#770 #519558
Новый тред тут >>517643
#771 #519562
>>519013

Тебе ответил в новом треде >>519553

>>517791

Шаблонный сайт на CMS, нестандартный на фреймворке.

>>519121

Ответил в новом >>519553

>>519139
>>519153

Ответил в новом треде >>519555
#772 #523328
Хлопцы, в чем отличие php_self от script_name?
6 Кб, 160x184
#773 #523837
Привет, котаны, два вопроса:
1. Это легитимный тред? Если нет, то киньте линк.
2. В общес, освоил основы пыхи, джс, джиквери, мускуль, теперь пора учить, то, что принесет мне трудоустройство и соответственно профит. План такой - делаю как говорят, в прочессе учусь\разбираюсь и следующим делаю уже свой проект. Вот решил по этому гайду заниматься https://github.com/githubjeka/yii2-tutorial
Кто что думает, особенно ОП, что можешь сказать после беглого взгляда.
#774 #525356
>>510035 (OP)
http://ideone.com/xoYyhz
Может кто - нибудь подсказать что я сделал не так? Только начал учить, и застрял.
Обновить тред
Двач.hk не отвечает.
Вы видите копию треда, сохраненную 13 августа 2015 года.

Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее

Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
« /pr/В начало тредаВеб-версияНастройки
/a//b//mu//s//vg/Все доски